);
65 if((m_Flags & fHandle) == 0) {
67 "CExec:: CResult contains process exit code, not handle");
69 returnm_Result.handle;
72CExec::CResult::operator
intptr_t(
void)
const 76 return(
intptr_t)m_Result.exitcode;
81 "CExec:: CResult undefined conversion");
88 #if defined(NCBI_OS_MSWIN) 93 static const ints_Mode[] = {
94P_OVERLAY, P_WAIT, P_NOWAIT, P_DETACH
98 _ASSERT(0 <= x_mode && x_mode <
sizeof(s_Mode) /
sizeof(s_Mode[0]));
99 returns_Mode[x_mode];
104 #if defined(NCBI_OS_UNIX) 111 const char* cmdname,
const char*
const* argv,
112 const char*
const* envp = (
const char*
const*)0)
115 const char* empty_env[] = { 0 };
130 returnexecv(cmdname,
const_cast<char**
>(argv));
132 returnexecvp(cmdname,
const_cast<char**
>(argv));
135 returnexecve(cmdname,
const_cast<char**
>(argv),
const_cast<char**
>(envp));
143 if(pipe(status_pipe) < 0) {
145 "CExec:: Failed to create status pipe");
147fcntl(status_pipe[0], F_SETFL,
148fcntl(status_pipe[0], F_GETFL, 0) & ~O_NONBLOCK);
149fcntl(status_pipe[1], F_SETFD,
150fcntl(status_pipe[1], F_GETFD, 0) | FD_CLOEXEC);
154 switch(pid = fork()) {
162 close(status_pipe[0]);
165 if(freopen(
"/dev/null",
"r", stdin)) {
};
166 if(freopen(
"/dev/null",
"w", stdout)) {
};
167 if(freopen(
"/dev/null",
"a", stderr)) {
};
177status = execv(cmdname,
const_cast<char**
>(argv));
180status = execvp(cmdname,
const_cast<char**
>(argv));
184status = execve(cmdname,
const_cast<char**
>(argv),
const_cast<char**
>(envp));
189 if(write(status_pipe[1], &errcode,
sizeof(errcode))) {
};
190 close(status_pipe[1]);
199 close(status_pipe[1]);
204 while((
n= read(status_pipe[0], &errcode,
sizeof(errcode))) < 0) {
208 close(status_pipe[0]);
212errno = (size_t)
n>=
sizeof(errcode) ? errcode : 0;
231(arg.find(
' ') !=
NPOS&& arg.find(
'"') ==
NPOS)) {
232 return '"'+ arg +
'"';
246 #if defined(NCBI_OS_MSWIN) 248 if(!arg.empty() && arg.find_first_of(
" \t\n\v\"") ==
NPOS) {
255 unsigned intn_backslashes = 0;
257 while(it != arg.end() && *it ==
'\\') {
261 if(it == arg.end()) {
266s.append(n_backslashes * 2,
'\\');
270 else if(*it ==
'"') {
274s.append(n_backslashes * 2 + 1,
'\\');
280s.append(n_backslashes,
'\\');
297 #if defined(_DEBUG) && SIZEOF_VOIDP > SIZEOF_INT 300 # if defined(WORDS_BIGENDIAN) 301 intlo =
int(((
Uint8)arg >> 32) & 0xffffffffU);
302 inthi =
int((
Uint8)arg & 0xffffffffU);
304 inthi =
int(((
Uint8)arg >> 32) & 0xffffffffU);
305 intlo =
int((
Uint8)arg & 0xffffffffU);
307 if(lo == 0 && hi != 0) {
309 "It is possible that you used 0 instead of NULL " 310 "to terminate the argument list of a CExec::Spawn*() call.");
314 # define s_CheckExecArg(x) 322 #if defined(NCBI_OS_MSWIN) 326va_list& begin,
const char* cmdname,
const char* argv)
329va_list v_args = begin;
330 size_txcnt = argv ? 2 : 1;
332 while(va_arg(v_args,
const char*)) {
348 for(
size_t i= 2;
i< xcnt; ++
i) {
353 for(
size_t i= 0;
i< xargs.size(); ++
i) {
354args[
i] = xargs[
i].c_str();
358va_arg(v_args,
const char**);
364vector<TXString>& xargs,
TXArgsOrEnv& t_args,
const char* cmdname,
const char** argv)
367 const char* argv_empty[] = {
NULL,
NULL};
370 const char** p = argv ? argv : argv_empty;
384 for(
size_t i= 1;
i< xcnt; ++
i) {
388 for(
size_t i= 0;
i< xargs.size(); ++
i) {
389args[
i] = xargs[
i].c_str();
395vector<TXString>& xargs,
TXArgsOrEnv& t_args,
const char** begin)
397 const char** envp = begin;
410 while(i_arg < xcnt) {
411 # if defined(_UNICODE) 414args[i_arg] = *(envp++);
418 # if defined(_UNICODE) 419 for(
size_t i= 0;
i< xargs.size(); ++
i) {
420args[
i] = xargs[
i].c_str();
423args[i_arg++] =
NULL;
428 #if defined(NCBI_OS_MSWIN) 429 #define XGET_EXEC_ARGS(name, ptr) \ 430 const TXChar* const *a_##name; \ 431 vector<TXString> x_##name; \ 432 TXArgsOrEnv t_##name; \ 434 va_start(vargs, ptr); \ 435 s_Create_Args_L(x_##name, t_##name, vargs, cmdname, ptr); \ 436 a_##name = t_##name.get(); 438 #define XGET_EXEC_ARGS(name, ptr) \ 439 int xcnt = ptr ? 2 : 1; \ 441 va_start(vargs, ptr); \ 442 while ( va_arg(vargs, const char*) ) xcnt++; \ 444 const char ** a_##name = new const char*[xcnt+1]; \ 446 NCBI_THROW(CCoreException, eNullPtr, kEmptyStr); \ 447 TXArgsOrEnv t_##name(a_##name); \ 448 a_##name[0] = cmdname; \ 450 va_start(vargs, ptr); \ 452 while ( xi < xcnt ) { \ 454 a_##name[xi] = va_arg(vargs, const char*); \ 455 s_CheckExecArg(a_##name[xi]); \ 457 a_##name[xi] = (const char*)0 460 #if defined(NCBI_OS_MSWIN) 461 # define XGET_PTR_ARGS(name, ptr) \ 462 const TXChar* const *a_##name; \ 463 vector<TXString> x_##name; \ 464 TXArgsOrEnv t_##name; \ 465 s_Create_Args_V(x_##name, t_##name, cmdname, (const char**)ptr); \ 466 a_##name = t_##name.get(); 467 # define XGET_PTR_ENVP(name, ptr) \ 468 const TXChar* const *a_##name; \ 469 vector<TXString> x_##name; \ 470 TXArgsOrEnv t_##name; \ 471 s_Create_Env(x_##name, t_##name, (const char**)ptr); \ 472 a_##name = t_##name.get(); 474 # define XGET_PTR_ARGS(name, ptr) \ 475 const char* ptr_empty[] = { NULL, NULL }; \ 476 const char* const *a_##name = ptr ? ptr : ptr_empty; \ 477 char** xptr = const_cast<char**>(ptr ? ptr : ptr_empty); \ 478 xptr[0] = const_cast<char*>(cmdname); 479 # define XGET_PTR_ENVP(name, ptr) \ 480 const char* const *a_##name = ptr; 483 #if defined(NCBI_OS_MSWIN) && defined(_UNICODE) 484 # define XGET_EXEC_ENVP(name) \ 485 const TXChar* const *a_##name; \ 486 vector<TXString> x_##name; \ 487 TXArgsOrEnv t_##name; \ 488 s_Create_Env(x_##name, t_##name, va_arg(vargs, const char**)); \ 489 a_##name = t_##name.get(); 491 # define XGET_EXEC_ENVP(name) \ 492 const char * const * a_##name = va_arg(vargs, const char**); 497 #define RETURN_RESULT(func) \ 498 if (status == -1) { \ 499 NCBI_THROW(CExecException, eSpawn, "CExec::"#func "() failed"); \
502if ((mode & static_cast<EMode>(fModeMask)) == eWait) { \
503result.m_Flags = CResult::fExitCode; \
504result.m_Result.exitcode = (TExitCode)status; \
506result.m_Flags = CResult::fHandle; \
507result.m_Result.handle = (TProcessHandle)status; \
515 #if defined(NCBI_OS_MSWIN) 518 #elif defined(NCBI_OS_UNIX) 519status = system(cmdline);
523 "CExec::System: call to system failed");
525 #if defined(NCBI_OS_UNIX) 527 returnWIFSIGNALED(status) ? WTERMSIG(status) + 0x80 : WEXITSTATUS(status);
546 const TXChar*
const* a_args;
547 const TXChar*
const* a_envs;
549 #if defined(NCBI_OS_MSWIN) 550 # define DO_PROCESS_ARGS 1 552 #if defined(NCBI_OS_MSWIN) && defined(_UNICODE) 553 # define DO_PROCESS_ENVS 1 556 #if defined(DO_PROCESS_ARGS) 557vector<TXString> v_args;
559 #if defined(DO_PROCESS_ENVS) 560vector<TXString> v_envs;
563 size_t n= args.size();
572 #if defined(DO_PROCESS_ARGS) 574v_args.reserve(
n+ 1);
576 for(
const string& e : args) {
579 for(
size_t i= 0;
i<
n; ++
i) {
580ptr[
i] = v_args[
i].c_str();
583ptr[0] = cmdname.c_str();
584 for(
size_t i= 1;
i<
n; ++
i) {
585ptr[
i] = args[
i- 1].c_str();
591 #if defined(DO_PROCESS_ARGS) 593args_empty[0] =
const_cast<TXChar*
>(v_args.front().c_str());
595args_empty[0] =
const_cast<char*
>(cmdname.c_str());
608 #if defined(DO_PROCESS_ENVS) 610v_envs.reserve(
n+ 1);
611 for(
const string& e :
env) {
614 for(
size_t i= 0;
i<
n; ++
i) {
615ptr[
i] = v_envs[
i].c_str();
618 for(
size_t i= 0;
i<
n; ++
i) {
619ptr[
i] =
env[
i].c_str();
631 #if defined(NCBI_OS_MSWIN) 634 if(realmode == P_OVERLAY) {
651 #elif defined(NCBI_OS_UNIX) 670 #if defined(NCBI_OS_MSWIN) 673 if(realmode == P_OVERLAY) {
681 #elif defined(NCBI_OS_UNIX) 696 #if defined(NCBI_OS_MSWIN) 699 if(realmode == P_OVERLAY) {
707 #elif defined(NCBI_OS_UNIX) 720 #if defined(NCBI_OS_MSWIN) 723 if(realmode == P_OVERLAY) {
727 #elif defined(NCBI_OS_UNIX) 741 #if defined(NCBI_OS_MSWIN) 744 if(realmode == P_OVERLAY) {
748 #elif defined(NCBI_OS_UNIX) 762 #if defined(NCBI_OS_MSWIN) 765 if(realmode == P_OVERLAY) {
773 #elif defined(NCBI_OS_UNIX) 782 const char*
const* argv,
const char*
const* envp)
789 #if defined(NCBI_OS_MSWIN) 792 if(realmode == P_OVERLAY) {
800 #elif defined(NCBI_OS_UNIX) 813 #if defined(NCBI_OS_MSWIN) 816 if(realmode == P_OVERLAY) {
820 #elif defined(NCBI_OS_UNIX) 829 const char*
const* argv,
const char*
const* envp)
835 #if defined(NCBI_OS_MSWIN) 838 if(realmode == P_OVERLAY) {
842 #elif defined(NCBI_OS_UNIX) 861 unsigned longtimeout)
863 typedeflist<TProcessHandle>::iterator THandleIt;
868 for(THandleIt it = handles.begin(); it != handles.end(); ) {
871 if(exitcode != -1) {
891 if(x_sleep > timeout) {
902 return(
int)
result.size();
907 const char* argv, ...
)
911 #if defined(NCBI_OS_MSWIN) 913 # if defined(NCBI_COMPILER_MSVC) 917STARTUPINFO StartupInfo;
918PROCESS_INFORMATION ProcessInfo;
919 const intkMaxCmdLength = 4096;
923memset(&StartupInfo, 0,
sizeof(StartupInfo));
924StartupInfo.cb =
sizeof(STARTUPINFOA);
925StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
926StartupInfo.wShowWindow = SW_HIDE;
927 DWORDdwCreateFlags = (
mode==
eDetach) ? DETACHED_PROCESS : CREATE_NEW_CONSOLE;
928 # if defined(_UNICODE) 929dwCreateFlags |= CREATE_UNICODE_ENVIRONMENT;
933cmdline.reserve(kMaxCmdLength);
937cmdline +=
_TX(
" ");
940va_start(vargs, argv);
941 const char* p =
NULL;
942 while((p = va_arg(vargs,
const char*))) {
943cmdline +=
_TX(
" ");
957dwCreateFlags,
NULL,
NULL, &StartupInfo, &ProcessInfo))
965WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
967GetExitCodeProcess(ProcessInfo.hProcess, &exitcode);
969CloseHandle(ProcessInfo.hProcess);
974CloseHandle(ProcessInfo.hProcess);
979status = (
intptr_t)ProcessInfo.hProcess;
981CloseHandle(ProcessInfo.hThread);
984 #elif defined(NCBI_OS_UNIX) 1018 string tmp= filename;
1019 # ifdef NCBI_OS_MSWIN 1022 stringdir, title, ext;
1030 size_tsep =
tmp.find_first_of(
"/\\");
1036 # ifdef NCBI_OS_MSWIN 1050list<string> split_path;
1051 # ifdef NCBI_OS_MSWIN 1058 ITERATE(list<string>, it, split_path) {
1069 if(path.empty() &&
CFile(
tmp).Exists()) {
1079 if(!path.empty()) {
1088 switch(GetErrCode()) {
1089 caseeSystem:
return "eSystem";
1090 caseeSpawn:
return "eSpawn";
1091 caseeResult:
return "eResult";
The result type for Spawn methods.
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
CDiagContext & GetDiagContext(void)
Get diag context instance.
#define ERR_POST_X(err_subcode, message)
Error posting with default error code and given error subcode.
void PrintStop(void)
Print exit message.
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
void Warning(CExceptionArgs_Base &args)
virtual const char * GetErrCodeString(void) const
Get error code interpreted as text.
static TExitCode System(const char *cmdline)
Execute the specified command.
static CResult RunSilent(EMode mode, const char *cmdname, const char *argv,...)
Run console application in invisible mode.
static bool IsExecutable(const string &path)
Check executable permissions for specified file.
static CResult SpawnLPE(EMode mode, const char *cmdname, const char *argv,...)
Spawn a new process with specified command-line arguments, environment settings and find file to exec...
static CResult Spawn(const string &cmdname, const vector< string > &args, const vector< string > &env, EMode mode, TModeFlags flags=0)
Spawn a new process.
int TExitCode
Exit code type.
static CResult SpawnVP(EMode mode, const char *cmdname, const char *const *argv=NULL)
Spawn a new process with variable number of command-line arguments and find file to execute from the ...
struct CExec::CResult::@98 m_Result
Result of Spawn*() methods.
TExitCode GetExitCode(void)
Get exit code.
virtual const char * GetErrCodeString(void) const override
Translate from the error code value to its string representation.
unsigned int TModeFlags
bitwise OR of "EModeFlag"
EMode
Which exec mode the spawned process is called with.
static string ResolvePath(const string &filename)
Find executable file.
static CResult SpawnL(EMode mode, const char *cmdname, const char *argv,...)
Spawn a new process with specified command-line arguments.
static string QuoteArg(const string &arg)
Quote argument.
TProcessHandle GetProcessHandle(void)
Get process handle/pid.
static CResult SpawnLP(EMode mode, const char *cmdname, const char *argv,...)
Spawn a new process with variable number of command-line arguments and find file to execute from the ...
static CResult SpawnV(EMode mode, const char *cmdname, const char *const *argv=NULL)
Spawn a new process with variable number of command-line arguments.
static TExitCode Wait(TProcessHandle handle, unsigned long timeout=kInfiniteTimeoutMs)
Wait until specified process terminates.
static CResult SpawnVPE(EMode mode, const char *cmdname, const char *const *argv, const char *const *envp)
Spawn a new process with variable number of command-line arguments and specified environment settings...
static CResult SpawnLE(EMode mode, const char *cmdname, const char *argv,...)
Spawn a new process with specified command-line arguments and environment settings.
EWaitMode
Mode used to wait processes termination.
static CResult SpawnVE(EMode mode, const char *cmdname, const char *const *argv, const char *const *envp)
Spawn a new process with variable number of command-line arguments and specified environment settings...
TFlags m_Flags
What m_Result stores.
@ fModeMask
Mask for all master modes, all EModeFlags must be declared above it.
@ fPath
Find command file to execute using PATH environment variable.
@ fNewGroup
UNIX only: Move newly created process to a new group after fork() (assign new PGID).
@ eWait
Suspends calling thread until execution of new process is complete (synchronous operation).
@ eDetach
Like eNoWait, continues to execute calling process; new process is run in background with no access t...
@ eOverlay
Overlays calling process with new process, destroying calling process.
@ eNoWait
Continues to execute calling process concurrently with new process (asynchronous spawn).
@ eWaitAny
Wait any process to terminate.
@ eWaitAll
Wait all processes to terminate.
static string NormalizePath(const string &path, EFollowLinks follow_links=eIgnoreLinks)
Normalize a path.
static bool IsAbsolutePath(const string &path)
Check if a "path" is absolute for the current OS.
static string MakePath(const string &dir=kEmptyStr, const string &base=kEmptyStr, const string &ext=kEmptyStr)
Assemble a path from basic components.
static char GetPathSeparator(void)
Get path separator symbol specific for the current platform.
static string GetCwd(void)
Get the current working directory.
static void SplitPath(const string &path, string *dir=0, string *base=0, string *ext=0)
Split a path string into its basic components.
@ fExecute
Execute / List(directory) permission.
uint64_t Uint8
8-byte (64-bit) unsigned integer
const unsigned long kInfiniteTimeoutMs
Infinite timeout in milliseconds.
int Wait(unsigned long timeout=kInfiniteTimeoutMs, CExitInfo *info=0) const
Wait until process terminates.
@ eHandle
A process handle (MS Windows).
#define END_NCBI_SCOPE
End previously defined NCBI scope.
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
static list< string > & Split(const CTempString str, const CTempString delim, list< string > &arr, TSplitFlags flags=0, vector< SIZE_TYPE > *token_pos=NULL)
Split a string using specified delimiters.
@ fSplit_MergeDelimiters
Merge adjacent delimiters.
unsigned int
A callback function used to compare two keys in a database.
Definition of all error codes used in corelib (xncbi.lib).
#define FALSE
bool replacment for C indicating false.
void SleepMilliSec(unsigned long ml_sec, EInterruptOnSignal onsignal=eRestartOnSignal)
void s_Create_Args_L(vector< TXString > &xargs, TXArgsOrEnv &t_args, va_list &begin, const char *cmdname, const char *argv)
void s_Create_Env(vector< TXString > &xargs, TXArgsOrEnv &t_args, const char **begin)
string s_QuoteSpawnArg(const string &arg)
static int s_SpawnUnix(ESpawnFunc func, CExec::EMode full_mode, const char *cmdname, const char *const *argv, const char *const *envp=(const char *const *) 0)
#define XGET_EXEC_ARGS(name, ptr)
static int s_GetRealMode(CExec::EMode mode)
void s_Create_Args_V(vector< TXString > &xargs, TXArgsOrEnv &t_args, const char *cmdname, const char **argv)
#define XGET_PTR_ENVP(name, ptr)
AutoPtr< const TXChar *, TXArgsDeleter > TXArgsOrEnv
#define RETURN_RESULT(func)
#define XGET_PTR_ARGS(name, ptr)
#define s_CheckExecArg(x)
const unsigned long kWaitPrecision
#define XGET_EXEC_ENVP(name)
ArrayDeleter< const TXChar * > TXArgsDeleter
Defines a portable execute class.
Defines classes: CDirEntry, CFile, CDir, CSymLink, CMemoryFile, CFileUtil, CFileLock,...
Functor template for deleting array of objects.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4