dynamicCode.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2026 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "dynamicCode.H"
27 #include "OSHA1stream.H"
28 #include "dlLibraryTable.H"
29 #include "regIOobject.H"
30 #include "Pstream.H"
31 #include "stringOps.H"
32 #include "IFstream.H"
33 #include "OFstream.H"
34 #include "OSspecific.H"
35 
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 
38 namespace Foam
39 {
41 }
42 
44 (
45  Foam::debug::infoSwitch("allowSystemOperations", 0)
46 );
47 
48 const Foam::fileName Foam::dynamicCode::codeTemplateDirName
49 (
50  "codeTemplates/dynamicCode"
51 );
52 
53 const Foam::word Foam::dynamicCode::topDirName
54 (
55  "dynamicCode"
56 );
57 
58 const char* const Foam::dynamicCode::libTargetRoot
59 (
60  "LIB = $(PWD)/../platforms/$(WM_OPTIONS)/lib/lib"
61 );
62 
63 
64 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
65 
66 void Foam::dynamicCode::addLineDirective
67 (
68  string& code,
69  const label lineNum,
70  const fileName& name
71 )
72 {
73  code = "#line " + Foam::name(lineNum) + " \"" + name + "\"\n" + code;
74 }
75 
76 
77 void Foam::dynamicCode::copyAndFilter
78 (
79  ISstream& is,
80  OSstream& os,
81  const HashTable<string>& mapping
82 )
83 {
84  if (!is.good())
85  {
87  << "Failed opening for reading " << is.name()
88  << exit(FatalError);
89  }
90 
91  if (!os.good())
92  {
94  << "Failed writing " << os.name()
95  << exit(FatalError);
96  }
97 
98  // Copy file while rewriting $VARS and ${VARS}
99  string line;
100  do
101  {
102  // Read the next line without continuation
103  is.getLine(line, false);
104 
105  // Expand according to mapping.
106  // Expanding according to env variables might cause too many
107  // surprises
109  os.writeQuoted(line, false) << nl;
110  }
111  while (is.good());
112 }
113 
114 
115 bool Foam::dynamicCode::resolveTemplates
116 (
117  const wordList& templateNames,
118  DynamicList<fileName>& resolvedFiles,
119  DynamicList<fileName>& badFiles
120 )
121 {
122  bool allOkay = true;
123  forAll(templateNames, fileI)
124  {
125  const fileName& templateName = templateNames[fileI];
126 
127  const fileName file
128  (
130  (
131  templateName,
132  dynamicCode::codeTemplateDirName,
133  "system"
134  )
135  );
136 
137  if (file.empty())
138  {
139  badFiles.append(templateName);
140  allOkay = false;
141  }
142  else
143  {
144  resolvedFiles.append(file);
145  }
146  }
147 
148  return allOkay;
149 }
150 
151 
152 bool Foam::dynamicCode::createMakeFiles() const
153 {
154  // Create Make/files
155  if (compileFiles_.empty())
156  {
157  return false;
158  }
159 
160  const fileName dstFile(codePath()/"Make/files");
161 
162  // Create dir
163  mkDir(dstFile.path());
164 
165  OFstream os(dstFile);
166 
167  if (!os.good())
168  {
170  << "Failed writing " << dstFile
171  << exit(FatalError);
172  }
173 
174  // Write compile files
175  forAll(compileFiles_, fileI)
176  {
177  os.writeQuoted(compileFiles_[fileI], false) << nl;
178  }
179 
180  os << nl << dynamicCode::libTargetRoot << codeSha1Name_ << nl;
181 
182  return true;
183 }
184 
185 
186 bool Foam::dynamicCode::createMakeOptions() const
187 {
188  if (compileFiles_.empty())
189  {
190  return false;
191  }
192 
193  // Read the options template file
194  const fileName optionsFile
195  (
196  dynamicCode::resolveTemplate(optionsFileName_)
197  );
198 
199  verbatimString options;
200  verbatimString libs;
201 
202  if (!optionsFileName_.empty())
203  {
204  const fileName optionsFile
205  (
206  dynamicCode::resolveTemplate(optionsFileName_)
207  );
208 
209  if (!optionsFile.empty())
210  {
211  IFstream is(optionsFile);
212  if (!is.good())
213  {
215  << "Failed opening " << optionsFile
216  << exit(FatalError);
217  }
218 
219  dictionary optionsDict(is);
220 
221  options = optionsDict.lookupOrDefault<verbatimString>
222  (
223  "codeOptions",
225  );
226 
227  libs = optionsDict.lookupOrDefault<verbatimString>
228  (
229  "codeLibs",
231  );
232  }
233  else
234  {
236  << "Cannot find options file " << optionsFileName_
237  << exit(FatalError);
238  }
239  }
240 
241  // Add the code specific options and libs
242  options += options_;
243  libs += libs_;
244 
245  if (options.empty() && libs.empty())
246  {
247  return false;
248  }
249 
250  const fileName dstFile(codePath()/"Make/options");
251  mkDir(dstFile.path());
252 
253  OFstream os(dstFile);
254 
255  if (!os.good())
256  {
258  << "Failed writing " << dstFile
259  << exit(FatalError);
260  }
261 
262  os.writeQuoted(options + "\n\n" + libs, false) << nl;
263 
264  return true;
265 }
266 
267 
268 bool Foam::dynamicCode::writeDigest() const
269 {
270  const fileName file(digestFile());
271  mkDir(file.path());
272 
273  OFstream os(file);
274  os << '_';
275  os.writeQuoted(sha1_.str(), false) << nl;
276 
277  return os.good();
278 }
279 
280 
281 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
282 
284 (
285  const dictionary& contextDict,
286  const dictionary& codeDict,
287  const word& codeName,
288  const word& codeDirName,
289  const wordList& codeKeys,
290  const wordList& codeDictVars,
291  const word& optionsFileName,
292  const wordList& compileFiles,
293  const wordList& copyFiles
294 )
295 :
296  codeRoot_
297  (
298  stringOps::expandEnvVar("$FOAM_CASE")/topDirName
299  ),
300  libSubDir_(stringOps::expandEnvVar("platforms/$WM_OPTIONS/lib")),
301  codeName_(codeName),
302  codeKeys_(codeKeys),
303  codeDictVars_(codeDictVars),
304  optionsFileName_(optionsFileName),
305  compileFiles_(compileFiles),
306  copyFiles_(copyFiles),
307  codeStrings_(codeKeys.size())
308 {
309  if (isAdministrator())
310  {
311  FatalIOErrorInFunction(contextDict)
312  << "This code should not be executed by someone with administrator"
313  << " rights due to security reasons." << nl
314  << "(it writes a shared library which then gets loaded "
315  << "using dlopen)"
316  << exit(FatalIOError);
317  }
318 
320  {
321  FatalIOErrorInFunction(contextDict)
322  << "Loading a shared library using case-supplied code is not"
323  << " enabled by default" << nl
324  << "because of security issues. If you trust the code you can"
325  << " enable this" << nl
326  << "facility be adding to the InfoSwitches setting in the system"
327  << " controlDict:" << nl << nl
328  << " allowSystemOperations 1" << nl << nl
329  << "The system controlDict is either" << nl << nl
330  << " ~/.OpenFOAM/$WM_PROJECT_VERSION/controlDict" << nl << nl
331  << "or" << nl << nl
332  << " $WM_PROJECT_DIR/etc/controlDict" << nl
333  << endl
334  << exit(FatalIOError);
335  }
336 
337  read(contextDict, codeDict);
338 
339  const word sha1Str(sha1_.str());
340 
341  codeSha1Name_ = codeName_ + '_' + sha1Str;
342 
343  codeDirName_ =
344  (
345  codeDirName.empty()
346  ? word('_' + sha1Str)
347  : codeDirName
348  );
349 
350  varSubstitutions_.set("typeName", codeName_);
351  varSubstitutions_.set("uniqueFunctionName", codeSha1Name_);
352  varSubstitutions_.set("SHA1sum", sha1Str);
353 }
354 
355 
357 (
358  const dictionary& contextDict,
359  const word& codeName,
360  const word& codeDirName,
361  const wordList& codeKeys,
362  const wordList& codeDictVars,
363  const word& codeOptionsFileName,
364  const wordList& compileFiles,
365  const wordList& copyFiles
366 )
367 :
369  (
370  contextDict,
371  contextDict,
372  codeName,
373  codeDirName,
374  codeKeys,
375  codeDictVars,
376  codeOptionsFileName,
377  compileFiles,
378  copyFiles
379  )
380 {}
381 
382 
383 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
384 
386 (
387  const dictionary& contextDict,
388  const dictionary& codeDict
389 )
390 {
391  // Expand all dictionary entries. Note that this removes any leading or
392  // trailing whitespace, which is necessary for compilation options, and
393  // doesn't hurt for everything else
394  List<const entry*> codePtrs(codeKeys_.size(), nullptr);
395  codeKeySubstitutions_.clear();
396  forAll(codeKeys_, i)
397  {
398  const word& key = codeKeys_[i];
399  codePtrs[i] = codeDict.lookupEntryPtr(key, false, false);
400  if (codePtrs[i])
401  {
402  codeStrings_[i] = verbatimString(codePtrs[i]->stream());
404  (
405  codeStrings_[i],
406  contextDict, // Lookup variables from the context dictionary
407  codeDictVars_[i]
408  );
409  codeKeySubstitutions_.insert(key, codeStrings_[i]);
410  }
411  else
412  {
413  codeKeySubstitutions_.insert(key, "");
414  }
415  }
416 
417  // Code options
418  const entry* optionsPtr =
419  codeDict.lookupEntryPtr("codeOptions", false, false);
420  if (optionsPtr)
421  {
422  optionsString_ = verbatimString(optionsPtr->stream());
424  (
425  optionsString_,
426  contextDict,
427  word::null
428  );
429  options_ = stringOps::trim(optionsString_);
430  }
431 
432  // Code libs
433  const entry* libsPtr = codeDict.lookupEntryPtr("codeLibs", false, false);
434  if (libsPtr)
435  {
436  libsString_ = verbatimString(libsPtr->stream());
438  (
439  libsString_,
440  contextDict,
441  word::null
442  );
443  libs_ = stringOps::trim(libsString_);
444  }
445 
446  // Calculate SHA1 digest from all entries
447  OSHA1stream os;
448  forAllConstIter(HashTable<string>, codeKeySubstitutions_, iter)
449  {
450  os << iter();
451  }
452  os << options_ << libs_;
453  sha1_ = os.digest();
454 
455  // Add line directives after calculating SHA1
456  forAll(codeKeys_, i)
457  {
458  if (codePtrs[i])
459  {
460  const word& key = codeKeys_[i];
461  addLineDirective
462  (
463  codeKeySubstitutions_[key],
464  codePtrs[i]->startLineNumber(),
465  codeDict.name()
466  );
467  }
468  }
469 }
470 
471 
473 {
474  word libName(libPath.name(true));
475  libName.erase(0, 3); // Remove leading 'lib' from name
476  return libName;
477 }
478 
479 
481 (
482  const fileName& templateName
483 )
484 {
485  return findConfigFile
486  (
487  templateName,
488  codeTemplateDirName,
489  "system"
490  );
491 }
492 
493 
494 bool Foam::dynamicCode::copyOrCreateFiles(const bool verbose) const
495 {
496  if (verbose)
497  {
498  Info<< "Creating new library in " << libRelPath() << endl;
499  }
500 
501  HashTable<string> filterVars(varSubstitutions_);
502 
503  // Collect all the filter variables
504  forAllConstIter(HashTable<string>, codeKeySubstitutions_, iter)
505  {
506  filterVars.set(iter.key(), iter());
507  }
508 
509  const label nFiles =
510  compileFiles_.size() + copyFiles_.size();
511 
512  DynamicList<fileName> resolvedFiles(nFiles);
513  DynamicList<fileName> badFiles(nFiles);
514 
515  // Resolve template, or add to bad-files
516  dynamicCode::resolveTemplates
517  (
518  compileFiles_,
519  resolvedFiles,
520  badFiles
521  );
522  dynamicCode::resolveTemplates
523  (
524  copyFiles_,
525  resolvedFiles,
526  badFiles
527  );
528 
529  if (!badFiles.empty())
530  {
532  << "Could not find the code template(s): "
533  << badFiles << nl
534  << exit(FatalError);
535  }
536 
537  // Create dir
538  const fileName outputDir(codePath());
539 
540  // Create dir
541  mkDir(outputDir);
542 
543  // Copy/filter files
544  forAll(resolvedFiles, fileI)
545  {
546  const fileName& srcFile = resolvedFiles[fileI];
547  const fileName dstFile(outputDir/srcFile.name());
548 
549  if (verbose)
550  {
551  Info << " Copying " << srcFile << " to " << dstFile << endl;
552  }
553 
554  IFstream is(srcFile);
555  if (!is.good())
556  {
558  << "Failed opening " << srcFile
559  << exit(FatalError);
560  }
561 
562  OFstream os(dstFile);
563  if (!os.good())
564  {
566  << "Failed writing " << dstFile
567  << exit(FatalError);
568  }
569 
570  // Copy lines while expanding variables
571  dynamicCode::copyAndFilter(is, os, filterVars);
572  }
573 
574 
575  // Create Make/files + Make/options
576  createMakeFiles();
577  createMakeOptions();
578 
579  writeDigest();
580 
581  return true;
582 }
583 
584 
586 {
587  const string wmakeCmd("wmake -s libso " + codePath());
588 
589  if (system(wmakeCmd))
590  {
591  return false;
592  }
593  else
594  {
595  return true;
596  }
597 }
598 
599 
601 {
602  const fileName file(digestFile());
603 
604  if (!exists(file, false, true) || SHA1Digest(IFstream(file)()) != sha1_)
605  {
606  return false;
607  }
608 
609  return true;
610 }
611 
612 
613 void* Foam::dynamicCode::loadLibrary(const fileName& libPath) const
614 {
615  // Cached access to dl libs.
616  // Guarantees clean up upon destruction of Time.
617  if (libs.open(libPath, false))
618  {
619  return libs.findLibrary(libPath);
620  }
621  else
622  {
623  // Uncached opening of libPath. Do not complain if cannot be loaded
624  return dlOpen(libPath, false);
625  }
626 }
627 
628 
630 (
631  const dictionary& dict,
632  const bool masterOnlyRead
633 ) const
634 {
635  const bool create =
637  || (regIOobject::fileModificationSkew <= 0); // Not NFS
638 
639  if (create)
640  {
641  // Write files for new library
642  if (!upToDate())
643  {
644  if (!copyOrCreateFiles(true))
645  {
647  (
648  dict
649  ) << "Failed writing files for" << nl
650  << libRelPath() << nl
651  << exit(FatalIOError);
652  }
653  }
654 
655  if (!wmakeLibso())
656  {
658  (
659  dict
660  ) << "Failed wmake " << libRelPath() << nl
661  << exit(FatalIOError);
662  }
663  }
664 
665  // All processes must wait for compile to finish
666  // Only block if not master only reading of a global dictionary
667  if
668  (
669  !masterOnlyRead
671  )
672  {
673  const fileName libPath = this->libPath();
674 
675  // Determine and communicate the master file size. Scattering
676  // blocks the other processes until the master has finished
677  // compiling.
678  off_t masterSize = Pstream::master() ? fileSize(libPath) : -1;
679  Pstream::scatter(masterSize);
680 
681  // Determine the local file size. This may be incorrect if NFS is
682  // taking its time, in which case we wait and try again.
683  off_t mySize = Pstream::master() ? masterSize : fileSize(libPath);
684 
685  if (debug)
686  {
687  Pout<< endl<< "on processor " << Pstream::myProcNo()
688  << " have masterSize:" << masterSize
689  << " and localSize:" << mySize
690  << endl;
691  }
692 
693  if (mySize < masterSize)
694  {
695  if (debug)
696  {
697  Pout<< "Local file " << libPath
698  << " not of same size (" << mySize
699  << ") as master ("
700  << masterSize << "). Waiting for "
702  << " seconds." << endl;
703  }
705 
706  // Recheck local size
707  mySize = Foam::fileSize(libPath);
708 
709  if (mySize < masterSize)
710  {
712  (
713  dict
714  ) << "Cannot read (NFS mounted) library " << nl
715  << libPath << nl
716  << "on processor " << Pstream::myProcNo()
717  << " detected size " << mySize
718  << " whereas master size is " << masterSize
719  << " bytes." << nl
720  << "If your case is not NFS mounted"
721  << " (so distributed) set fileModificationSkew"
722  << " to 0"
723  << exit(FatalIOError);
724  }
725  }
726 
727  if (debug)
728  {
729  Pout<< endl<< "on processor " << Pstream::myProcNo()
730  << " after waiting: have masterSize:" << masterSize
731  << " and localSize:" << mySize
732  << endl;
733  }
734  }
735 }
736 
737 
738 void Foam::dynamicCode::read(const dictionary& contextDict)
739 {
740  read(contextDict, contextDict);
741 }
742 
743 
745 {
746  writeEntry(os, "name", codeName_);
747 
748  forAll(codeStrings_, i)
749  {
750  if (codeStrings_[i] != verbatimString::null)
751  {
752  writeEntry(os, codeKeys_[i], codeStrings_[i]);
753  }
754  }
755 
756  if (optionsString_ != verbatimString::null)
757  {
758  writeEntry(os, "codeOptions", optionsString_);
759  }
760 
761  if (libsString_ != verbatimString::null)
762  {
763  writeEntry(os, "codeLibs", libsString_);
764  }
765 }
766 
767 
768 // ************************************************************************* //
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:492
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:78
An STL-conforming hash table.
Definition: HashTable.H:127
Input from file stream.
Definition: IFstream.H:85
bool good() const
Return true if next operation might succeed.
Definition: IOstream.H:333
bool good() const
Return true if next operation might succeed.
Definition: Istream.H:101
Output to file stream.
Definition: OFstream.H:87
A Foam::OSstream for calculating SHA-1 digests.
Definition: OSHA1stream.H:152
SHA1Digest digest()
Return the SHA-1 digest for the data processed until now.
Definition: OSHA1stream.H:194
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:57
static void scatter(const List< commsStruct > &comms, T &Value, const int tag, const label comm)
Scatter data. Distribute without modification. Reverse of gather.
The SHA1 message digest.
Definition: SHA1Digest.H:63
std::string str(const bool prefixed=false) const
Return (40-byte) text representation, optionally with '_' prefix.
Definition: SHA1Digest.C:112
bool empty() const
Return true if the UList is empty (ie, size() is zero)
Definition: UListI.H:325
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:423
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:429
const fileName & name() const
Return the dictionary name.
Definition: dictionary.H:111
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
const entry * lookupEntryPtr(const word &, bool recursive, bool patternMatch) const
Find and return an entry data stream pointer if present.
Definition: dictionary.C:507
void * findLibrary(const fileName &libName)
Find the handle of the named library.
bool open(const fileName &libName, const bool verbose=true)
Open the named library, optionally with warnings if problems occur.
Encapsulation of dynamic code dictionaries and functionality.
Definition: dynamicCode.H:51
dynamicCode(const dictionary &contextDict, const dictionary &codeDict, const word &codeName, const word &codeDirName, const wordList &codeKeys, const wordList &codeDictVars, const word &optionsFileName, const wordList &compileFiles, const wordList &copyFiles)
Construct from the context and code dictionaries.
Definition: dynamicCode.C:284
static int allowSystemOperations
Flag if system operations are allowed.
Definition: dynamicCode.H:188
bool upToDate() const
Verify if the copied code is up-to-date, based on Make/SHA1Digest.
Definition: dynamicCode.C:600
bool copyOrCreateFiles(const bool verbose=false) const
Copy/create files prior to compilation.
Definition: dynamicCode.C:494
void write(Ostream &os) const
Write the code for restart.
Definition: dynamicCode.C:744
void * loadLibrary(const fileName &libPath) const
Definition: dynamicCode.C:613
static word libraryBaseName(const fileName &libPath)
Return the library basename without leading 'lib' or trailing '.so'.
Definition: dynamicCode.C:472
static fileName resolveTemplate(const fileName &templateName)
Resolve code-template via Foam::findConfigFile.
Definition: dynamicCode.C:481
bool wmakeLibso() const
Compile a libso.
Definition: dynamicCode.C:585
void createLibrary(const dictionary &dict, const bool masterOnlyRead=false) const
Definition: dynamicCode.C:630
void read(const dictionary &contextDict, const dictionary &codeDict)
Definition: dynamicCode.C:386
A keyword and a list of tokens is an 'entry'.
Definition: entry.H:68
virtual ITstream & stream() const =0
Return token stream if this entry is a primitive entry.
A class for handling file names.
Definition: fileName.H:82
word name() const
Return file name (part beyond last /)
Definition: fileName.C:195
static float fileModificationSkew
Definition: regIOobject.H:100
A class for handling verbatimStrings, derived from string.
static const verbatimString null
An empty verbatimString.
A class for handling words, derived from string.
Definition: word.H:63
static const word null
An empty word.
Definition: word.H:78
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:346
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
int infoSwitch(const char *name, const int defaultValue=0)
Lookup info switch or add default value.
Definition: debug.C:262
string & inplaceExpandCodeString(string &, const dictionary &dict, const word &dictVar="dict", const char sigil='$')
Inplace expand occurrences of variables according to the dictionary.
Definition: stringOps.C:410
string trim(const string &)
Return string trimmed of leading and trailing whitespace.
Definition: stringOps.C:947
string & inplaceExpandCodeTemplate(string &, const HashTable< string, word, string::hash > &mapping, const char sigil='$')
Inplace expand occurrences of variables according to the mapping.
Definition: stringOps.C:654
string expandEnvVar(const string &, const bool allowEmpty=false)
Expand all occurrences of environment variables and paths.
Definition: stringOps.C:241
Namespace for OpenFOAM.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
dlLibraryTable libs
Table of loaded dynamic libraries.
int system(const std::string &command)
Execute the specified command.
Definition: POSIX.C:1230
off_t fileSize(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return size of file.
Definition: POSIX.C:576
List< word > wordList
A List of words.
Definition: fileName.H:54
fileName findConfigFile(const word &configName, const fileName &configFilesPath, const word &configFilesDir, const word &region=word::null)
Search for configuration file for given region.
Definition: dictionaryIO.C:361
bool read(const char *, int32_t &)
Definition: int32IO.C:85
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
bool mkDir(const fileName &, mode_t=0777)
Make a directory and return an error if it could not be created.
Definition: POSIX.C:290
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
bool isAdministrator()
Is user administrator.
Definition: POSIX.C:180
void * dlOpen(const fileName &lib, const bool check=true)
Open a shared library. Return handle to library. Print error message.
Definition: POSIX.C:1236
bool exists(const fileName &, const bool checkVariants=true, const bool followLink=true)
Does the name exist (as directory or file) in the file system?
Definition: POSIX.C:520
messageStream Info
IOerror FatalIOError
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
error FatalError
defineTypeNameAndDebug(atmosphericBoundaryLayer, 0)
unsigned int sleep(const unsigned int)
Sleep for the specified number of seconds.
Definition: POSIX.C:1130
void writeEntry(Ostream &os, const word &key, const DimensionedFieldFunction< DimensionedFieldType > &f)
static const char nl
Definition: Ostream.H:297
dictionary dict