BUG: Foam::system command swallows first argument (fixes #901)
This commit is contained in:
parent
6390c18381
commit
c8fd217e95
@ -193,7 +193,7 @@ void writeRays
|
||||
|
||||
Pout<< "cmd: objToVTK " << fName.c_str() << endl;
|
||||
|
||||
stringList cmd{"objToVTK", fName, fName.lessExt().ext("vtk")};
|
||||
stringList cmd({"objToVTK", fName, fName.lessExt().ext("vtk")});
|
||||
Foam::system(cmd);
|
||||
}
|
||||
|
||||
|
@ -1408,7 +1408,7 @@ int Foam::system(const std::string& command, const bool bg)
|
||||
reinterpret_cast<char*>(0)
|
||||
);
|
||||
|
||||
// obviously failed, since exec should not return at all
|
||||
// Obviously failed, since exec should not return
|
||||
FatalErrorInFunction
|
||||
<< "exec failed: " << command
|
||||
<< exit(FatalError);
|
||||
@ -1426,9 +1426,7 @@ int Foam::system(const std::string& command, const bool bg)
|
||||
|
||||
int Foam::system(const CStringList& command, const bool bg)
|
||||
{
|
||||
const int argc = command.size();
|
||||
|
||||
if (!argc)
|
||||
if (command.empty())
|
||||
{
|
||||
// Treat an empty command as a successful no-op.
|
||||
// For consistency with POSIX (man sh) behaviour for (sh -c command),
|
||||
@ -1459,14 +1457,10 @@ int Foam::system(const CStringList& command, const bool bg)
|
||||
// Close or redirect file descriptors
|
||||
redirects();
|
||||
|
||||
// execvp searches the path, uses the current environ
|
||||
(void) ::execvp(command[0], command.strings());
|
||||
|
||||
// Need command and arguments separately.
|
||||
// args is a nullptr-terminated list of c-strings
|
||||
|
||||
// execvp uses the current environ
|
||||
(void) ::execvp(command[0], command.strings(1));
|
||||
|
||||
// obviously failed, since exec should not return at all
|
||||
// Obviously failed, since exec should not return
|
||||
FatalErrorInFunction
|
||||
<< "exec(" << command[0] << ", ...) failed"
|
||||
<< exit(FatalError);
|
||||
@ -1484,70 +1478,15 @@ int Foam::system(const CStringList& command, const bool bg)
|
||||
|
||||
int Foam::system(const Foam::UList<Foam::string>& command, const bool bg)
|
||||
{
|
||||
// In the future simply call the CStringList version:
|
||||
//
|
||||
// const CStringList cmd(command);
|
||||
// return Foam::system(cmd, bg);
|
||||
|
||||
const int argc = command.size();
|
||||
|
||||
if (!argc)
|
||||
if (command.empty())
|
||||
{
|
||||
// Treat an empty command as a successful no-op.
|
||||
// For consistency with POSIX (man sh) behaviour for (sh -c command),
|
||||
// which is what is mostly being replicated here.
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NB: use vfork, not fork!
|
||||
// vfork behaves more like a thread and avoids copy-on-write problems
|
||||
// triggered by fork.
|
||||
// The normal system() command has a fork buried in it that causes
|
||||
// issues with infiniband and openmpi etc.
|
||||
|
||||
const pid_t child_pid = ::vfork();
|
||||
|
||||
if (child_pid == -1)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "vfork() failed for system command " << command[0]
|
||||
<< exit(FatalError);
|
||||
|
||||
return -1; // fallback error value
|
||||
}
|
||||
else if (child_pid == 0)
|
||||
{
|
||||
// In child
|
||||
|
||||
// Close or redirect file descriptors
|
||||
redirects();
|
||||
|
||||
|
||||
// Need command and arguments separately.
|
||||
// args is a nullptr-terminated list of c-strings
|
||||
|
||||
CStringList args(SubList<string>(command, 0));
|
||||
if (argc > 1)
|
||||
{
|
||||
args.reset(SubList<string>(command, argc-1, 1));
|
||||
}
|
||||
|
||||
// execvp uses the current environ
|
||||
(void) ::execvp(command[0].c_str(), args.strings());
|
||||
|
||||
// obviously failed, since exec should not return at all
|
||||
FatalErrorInFunction
|
||||
<< "exec(" << command[0] << ", ...) failed"
|
||||
<< exit(FatalError);
|
||||
|
||||
return -1; // fallback error value
|
||||
}
|
||||
|
||||
|
||||
// In parent
|
||||
// - started as background process, or blocking wait for the child
|
||||
|
||||
return (bg ? 0 : waitpid(child_pid));
|
||||
// Make a deep copy as C-strings
|
||||
const CStringList cmd(command);
|
||||
return Foam::system(cmd, bg);
|
||||
}
|
||||
|
||||
|
||||
|
@ -498,7 +498,7 @@ bool Foam::dynamicCode::copyOrCreateFiles(const bool verbose) const
|
||||
|
||||
bool Foam::dynamicCode::wmakeLibso() const
|
||||
{
|
||||
stringList cmd{"wmake", "-s", "libso", this->codePath()};
|
||||
stringList cmd({"wmake", "-s", "libso", this->codePath()});
|
||||
|
||||
// NOTE: could also resolve wmake command explicitly
|
||||
// cmd[0] = stringOps::expand("$WM_PROJECT_DIR/wmake/wmake");
|
||||
|
@ -140,6 +140,9 @@ public:
|
||||
|
||||
// Access
|
||||
|
||||
//- True if the size is zero.
|
||||
inline bool empty() const;
|
||||
|
||||
//- Return the number of C-strings (ie, argc)
|
||||
inline int size() const;
|
||||
|
||||
@ -159,6 +162,7 @@ public:
|
||||
//- The flattened character content, with interspersed nul-chars
|
||||
inline const char* data() const;
|
||||
|
||||
|
||||
// Edit
|
||||
|
||||
//- Clear contents and free memory
|
||||
|
@ -111,6 +111,12 @@ inline void Foam::CStringList::clear()
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::CStringList::empty() const
|
||||
{
|
||||
return !argc_;
|
||||
}
|
||||
|
||||
|
||||
inline int Foam::CStringList::size() const
|
||||
{
|
||||
return argc_;
|
||||
|
@ -66,7 +66,7 @@ void Foam::faceShading::writeRays
|
||||
|
||||
Pout<< "cmd: objToVTK " << fName.c_str() << endl;
|
||||
|
||||
stringList cmd{"objToVTK", fName, fName.lessExt().ext("vtk")};
|
||||
stringList cmd({"objToVTK", fName, fName.lessExt().ext("vtk")});
|
||||
Foam::system(cmd);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user