ProcessWin32.c 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773
  1. /*=========================================================================
  2. Program: KWSys - Kitware System Library
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
  8. See http://www.cmake.org/HTML/Copyright.html for details.
  9. This software is distributed WITHOUT ANY WARRANTY; without even
  10. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  11. PURPOSE. See the above copyright notices for more information.
  12. =========================================================================*/
  13. #define KWSYS_IN_PROCESS_C
  14. #include "kwsysPrivate.h"
  15. #include KWSYS_HEADER(Process.h)
  16. /*
  17. Implementation for Windows
  18. On windows, a thread is created to wait for data on each pipe. The
  19. threads are synchronized with the main thread to simulate the use of
  20. a UNIX-style select system call.
  21. On Windows9x platforms, a small WIN32 console application is spawned
  22. in-between the calling process and the actual child to be executed.
  23. This is to work-around a problem with connecting pipes from WIN16
  24. console applications to WIN32 applications.
  25. For more information, please check Microsoft Knowledge Base Articles
  26. Q190351 and Q150956.
  27. */
  28. #ifdef _MSC_VER
  29. #pragma warning (push, 1)
  30. #endif
  31. #include <windows.h> /* Windows API */
  32. #include <string.h> /* strlen, strdup */
  33. #include <stdio.h> /* sprintf */
  34. #include <io.h> /* _unlink */
  35. #ifdef _MSC_VER
  36. #pragma warning (pop)
  37. #pragma warning (disable: 4514)
  38. #pragma warning (disable: 4706)
  39. #endif
  40. /* There are pipes for the process pipeline's stdout and stderr. */
  41. #define KWSYSPE_PIPE_COUNT 2
  42. #define KWSYSPE_PIPE_STDOUT 0
  43. #define KWSYSPE_PIPE_STDERR 1
  44. /* The maximum amount to read from a pipe at a time. */
  45. #define KWSYSPE_PIPE_BUFFER_SIZE 1024
  46. #define kwsysEncodedWriteArrayProcessFwd9x kwsys(EncodedWriteArrayProcessFwd9x)
  47. typedef LARGE_INTEGER kwsysProcessTime;
  48. typedef struct kwsysProcessCreateInformation_s
  49. {
  50. /* Windows child startup control data. */
  51. STARTUPINFO StartupInfo;
  52. /* Special error reporting pipe for Win9x forwarding executable. */
  53. HANDLE ErrorPipeRead;
  54. HANDLE ErrorPipeWrite;
  55. } kwsysProcessCreateInformation;
  56. /*--------------------------------------------------------------------------*/
  57. typedef struct kwsysProcessPipeData_s kwsysProcessPipeData;
  58. static DWORD WINAPI kwsysProcessPipeThread(LPVOID ptd);
  59. static void kwsysProcessPipeThreadReadPipe(kwsysProcess* cp, kwsysProcessPipeData* td);
  60. static int kwsysProcessInitialize(kwsysProcess* cp);
  61. static int kwsysProcessCreate(kwsysProcess* cp, int index,
  62. kwsysProcessCreateInformation* si,
  63. PHANDLE readEnd);
  64. static void kwsysProcessDestroy(kwsysProcess* cp, int event);
  65. static void kwsysProcessCleanupHandle(PHANDLE h);
  66. static void kwsysProcessCleanup(kwsysProcess* cp, int error);
  67. static void kwsysProcessCleanErrorMessage(kwsysProcess* cp);
  68. static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
  69. kwsysProcessTime* timeoutTime);
  70. static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime,
  71. kwsysProcessTime* timeoutLength);
  72. static kwsysProcessTime kwsysProcessTimeGetCurrent();
  73. static DWORD kwsysProcessTimeToDWORD(kwsysProcessTime t);
  74. static double kwsysProcessTimeToDouble(kwsysProcessTime t);
  75. static kwsysProcessTime kwsysProcessTimeFromDouble(double d);
  76. static int kwsysProcessTimeLess(kwsysProcessTime in1, kwsysProcessTime in2);
  77. static kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, kwsysProcessTime in2);
  78. static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProcessTime in2);
  79. extern kwsysEXPORT int kwsysEncodedWriteArrayProcessFwd9x(const char* fname);
  80. /*--------------------------------------------------------------------------*/
  81. /* A structure containing data for each pipe's thread. */
  82. struct kwsysProcessPipeData_s
  83. {
  84. /* ------------- Data managed per instance of kwsysProcess ------------- */
  85. /* Handle for the thread for this pipe. */
  86. HANDLE Thread;
  87. /* Semaphore indicating a process and pipe are available. */
  88. HANDLE Ready;
  89. /* Semaphore indicating when this thread's buffer is empty. */
  90. HANDLE Empty;
  91. /* Semaphore indicating a pipe thread has reset for another process. */
  92. HANDLE Reset;
  93. /* Index of this pipe. */
  94. int Index;
  95. /* The kwsysProcess instance owning this pipe. */
  96. kwsysProcess* Process;
  97. /* ------------- Data managed per call to Execute ------------- */
  98. /* Buffer for data read in this pipe's thread. */
  99. char DataBuffer[KWSYSPE_PIPE_BUFFER_SIZE];
  100. /* The length of the data stored in the buffer. */
  101. DWORD DataLength;
  102. /* Whether the pipe has been closed. */
  103. int Closed;
  104. /* Handle for the read end of this pipe. */
  105. HANDLE Read;
  106. /* Handle for the write end of this pipe. */
  107. HANDLE Write;
  108. };
  109. /*--------------------------------------------------------------------------*/
  110. /* Structure containing data used to implement the child's execution. */
  111. struct kwsysProcess_s
  112. {
  113. /* ------------- Data managed per instance of kwsysProcess ------------- */
  114. /* The status of the process structure. */
  115. int State;
  116. /* The command lines to execute. */
  117. char** Commands;
  118. int NumberOfCommands;
  119. /* The exit code of each command. */
  120. DWORD* CommandExitCodes;
  121. /* The working directory for the child process. */
  122. char* WorkingDirectory;
  123. /* Whether to hide the child process's window. */
  124. int HideWindow;
  125. /* On Win9x platforms, the path to the forwarding executable. */
  126. char* Win9x;
  127. /* On Win9x platforms, the resume event for the forwarding executable. */
  128. HANDLE Win9xResumeEvent;
  129. /* On Win9x platforms, the kill event for the forwarding executable. */
  130. HANDLE Win9xKillEvent;
  131. /* Mutex to protect the shared index used by threads to report data. */
  132. HANDLE SharedIndexMutex;
  133. /* Semaphore used by threads to signal data ready. */
  134. HANDLE Full;
  135. /* Whether we are currently deleting this kwsysProcess instance. */
  136. int Deleting;
  137. /* Data specific to each pipe and its thread. */
  138. kwsysProcessPipeData Pipe[KWSYSPE_PIPE_COUNT];
  139. /* ------------- Data managed per call to Execute ------------- */
  140. /* The exceptional behavior that terminated the process, if any. */
  141. int ExitException;
  142. /* The process exit code. */
  143. DWORD ExitCode;
  144. /* The process return code, if any. */
  145. int ExitValue;
  146. /* Index of last pipe to report data, if any. */
  147. int CurrentIndex;
  148. /* Index shared by threads to report data. */
  149. int SharedIndex;
  150. /* The timeout length. */
  151. double Timeout;
  152. /* Time at which the child started. */
  153. kwsysProcessTime StartTime;
  154. /* Time at which the child will timeout. Negative for no timeout. */
  155. kwsysProcessTime TimeoutTime;
  156. /* Flag for whether the process was killed. */
  157. int Killed;
  158. /* Flag for whether the timeout expired. */
  159. int TimeoutExpired;
  160. /* Flag for whether the process has terminated. */
  161. int Terminated;
  162. /* The number of pipes still open during execution and while waiting
  163. for pipes to close after process termination. */
  164. int PipesLeft;
  165. /* Buffer for error messages (possibly from Win9x child). */
  166. char ErrorMessage[KWSYSPE_PIPE_BUFFER_SIZE+1];
  167. /* Windows process information data. */
  168. PROCESS_INFORMATION* ProcessInformation;
  169. /* Data and process termination events for which to wait. */
  170. PHANDLE ProcessEvents;
  171. int ProcessEventsLength;
  172. };
  173. /*--------------------------------------------------------------------------*/
  174. kwsysProcess* kwsysProcess_New()
  175. {
  176. int i;
  177. /* Process control structure. */
  178. kwsysProcess* cp;
  179. /* Path to Win9x forwarding executable. */
  180. char* win9x = 0;
  181. /* Windows version number data. */
  182. OSVERSIONINFO osv;
  183. /* Allocate a process control structure. */
  184. cp = (kwsysProcess*)malloc(sizeof(kwsysProcess));
  185. if(!cp)
  186. {
  187. /* Could not allocate memory for the control structure. */
  188. return 0;
  189. }
  190. ZeroMemory(cp, sizeof(*cp));
  191. /* Set initial status. */
  192. cp->State = kwsysProcess_State_Starting;
  193. /* Choose a method of running the child based on version of
  194. windows. */
  195. ZeroMemory(&osv, sizeof(osv));
  196. osv.dwOSVersionInfoSize = sizeof(osv);
  197. GetVersionEx(&osv);
  198. if(osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
  199. {
  200. /* This is Win9x. We need the console forwarding executable to
  201. work-around a Windows 9x bug. */
  202. char fwdName[_MAX_FNAME+1] = "";
  203. char tempDir[_MAX_PATH+1] = "";
  204. /* We will try putting the executable in the system temp
  205. directory. Note that the returned path already has a trailing
  206. slash. */
  207. DWORD length = GetTempPath(_MAX_PATH+1, tempDir);
  208. /* Construct the executable name from the process id and kwsysProcess
  209. instance. This should be unique. */
  210. sprintf(fwdName, "cmw9xfwd_%u_%p.exe", GetCurrentProcessId(), cp);
  211. /* If we have a temp directory, use it. */
  212. if(length > 0 && length <= _MAX_PATH)
  213. {
  214. /* Allocate a buffer to hold the forwarding executable path. */
  215. size_t tdlen = strlen(tempDir);
  216. win9x = (char*)malloc(tdlen + strlen(fwdName) + 2);
  217. if(!win9x)
  218. {
  219. kwsysProcess_Delete(cp);
  220. return 0;
  221. }
  222. /* Construct the full path to the forwarding executable. */
  223. sprintf(win9x, "%s%s", tempDir, fwdName);
  224. }
  225. /* If we found a place to put the forwarding executable, try to
  226. write it. */
  227. if(win9x)
  228. {
  229. if(!kwsysEncodedWriteArrayProcessFwd9x(win9x))
  230. {
  231. /* Failed to create forwarding executable. Give up. */
  232. free(win9x);
  233. kwsysProcess_Delete(cp);
  234. return 0;
  235. }
  236. }
  237. else
  238. {
  239. /* Failed to find a place to put forwarding executable. */
  240. kwsysProcess_Delete(cp);
  241. return 0;
  242. }
  243. }
  244. /* Save the path to the forwarding executable. */
  245. cp->Win9x = win9x;
  246. /* Initially no thread owns the mutex. Initialize semaphore to 1. */
  247. if(!(cp->SharedIndexMutex = CreateSemaphore(0, 1, 1, 0)))
  248. {
  249. kwsysProcess_Delete(cp);
  250. return 0;
  251. }
  252. /* Initially no data are available. Initialize semaphore to 0. */
  253. if(!(cp->Full = CreateSemaphore(0, 0, 1, 0)))
  254. {
  255. kwsysProcess_Delete(cp);
  256. return 0;
  257. }
  258. if(cp->Win9x)
  259. {
  260. SECURITY_ATTRIBUTES sa;
  261. ZeroMemory(&sa, sizeof(sa));
  262. sa.nLength = sizeof(sa);
  263. sa.bInheritHandle = TRUE;
  264. /* Create an event to tell the forwarding executable to resume the
  265. child. */
  266. if(!(cp->Win9xResumeEvent = CreateEvent(&sa, TRUE, 0, 0)))
  267. {
  268. kwsysProcess_Delete(cp);
  269. return 0;
  270. }
  271. /* Create an event to tell the forwarding executable to kill the
  272. child. */
  273. if(!(cp->Win9xKillEvent = CreateEvent(&sa, TRUE, 0, 0)))
  274. {
  275. kwsysProcess_Delete(cp);
  276. return 0;
  277. }
  278. }
  279. /* Create the thread to read each pipe. */
  280. for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
  281. {
  282. DWORD dummy=0;
  283. /* Assign the thread its index. */
  284. cp->Pipe[i].Index = i;
  285. /* Give the thread a pointer back to the kwsysProcess instance. */
  286. cp->Pipe[i].Process = cp;
  287. /* The pipe is not yet ready to read. Initialize semaphore to 0. */
  288. if(!(cp->Pipe[i].Ready = CreateSemaphore(0, 0, 1, 0)))
  289. {
  290. kwsysProcess_Delete(cp);
  291. return 0;
  292. }
  293. /* The pipe is not yet reset. Initialize semaphore to 0. */
  294. if(!(cp->Pipe[i].Reset = CreateSemaphore(0, 0, 1, 0)))
  295. {
  296. kwsysProcess_Delete(cp);
  297. return 0;
  298. }
  299. /* The thread's buffer is initially empty. Initialize semaphore to 1. */
  300. if(!(cp->Pipe[i].Empty = CreateSemaphore(0, 1, 1, 0)))
  301. {
  302. kwsysProcess_Delete(cp);
  303. return 0;
  304. }
  305. /* Create the thread. It will block immediately. The thread will
  306. not make deeply nested calls, so we need only a small
  307. stack. */
  308. if(!(cp->Pipe[i].Thread = CreateThread(0, 1024, kwsysProcessPipeThread,
  309. &cp->Pipe[i], 0, &dummy)))
  310. {
  311. kwsysProcess_Delete(cp);
  312. return 0;
  313. }
  314. }
  315. return cp;
  316. }
  317. /*--------------------------------------------------------------------------*/
  318. void kwsysProcess_Delete(kwsysProcess* cp)
  319. {
  320. int i;
  321. /* If the process is executing, wait for it to finish. */
  322. if(cp->State == kwsysProcess_State_Executing)
  323. {
  324. kwsysProcess_WaitForExit(cp, 0);
  325. }
  326. /* We are deleting the kwsysProcess instance. */
  327. cp->Deleting = 1;
  328. /* Terminate each of the threads. */
  329. for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
  330. {
  331. if(cp->Pipe[i].Thread)
  332. {
  333. /* Signal the thread we are ready for it. It will terminate
  334. immediately since Deleting is set. */
  335. ReleaseSemaphore(cp->Pipe[i].Ready, 1, 0);
  336. /* Wait for the thread to exit. */
  337. WaitForSingleObject(cp->Pipe[i].Thread, INFINITE);
  338. /* Close the handle to the thread. */
  339. kwsysProcessCleanupHandle(&cp->Pipe[i].Thread);
  340. }
  341. /* Cleanup the pipe's semaphores. */
  342. kwsysProcessCleanupHandle(&cp->Pipe[i].Ready);
  343. kwsysProcessCleanupHandle(&cp->Pipe[i].Empty);
  344. }
  345. /* Close the shared semaphores. */
  346. kwsysProcessCleanupHandle(&cp->SharedIndexMutex);
  347. kwsysProcessCleanupHandle(&cp->Full);
  348. /* Close the Win9x resume and kill event handles. */
  349. if(cp->Win9x)
  350. {
  351. kwsysProcessCleanupHandle(&cp->Win9xResumeEvent);
  352. kwsysProcessCleanupHandle(&cp->Win9xKillEvent);
  353. }
  354. /* Free memory. */
  355. kwsysProcess_SetCommand(cp, 0);
  356. kwsysProcess_SetWorkingDirectory(cp, 0);
  357. if(cp->CommandExitCodes)
  358. {
  359. free(cp->CommandExitCodes);
  360. }
  361. if(cp->Win9x)
  362. {
  363. _unlink(cp->Win9x);
  364. free(cp->Win9x);
  365. }
  366. free(cp);
  367. }
  368. /*--------------------------------------------------------------------------*/
  369. int kwsysProcess_SetCommand(kwsysProcess* cp, char const* const* command)
  370. {
  371. int i;
  372. for(i=0; i < cp->NumberOfCommands; ++i)
  373. {
  374. free(cp->Commands[i]);
  375. }
  376. cp->NumberOfCommands = 0;
  377. if(cp->Commands)
  378. {
  379. free(cp->Commands);
  380. cp->Commands = 0;
  381. }
  382. if(command)
  383. {
  384. return kwsysProcess_AddCommand(cp, command);
  385. }
  386. return 1;
  387. }
  388. /*--------------------------------------------------------------------------*/
  389. int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
  390. {
  391. int newNumberOfCommands;
  392. char** newCommands;
  393. /* Make sure we have a command to add. */
  394. if(!command)
  395. {
  396. return 0;
  397. }
  398. /* Allocate a new array for command pointers. */
  399. newNumberOfCommands = cp->NumberOfCommands + 1;
  400. if(!(newCommands = (char**)malloc(sizeof(char*) * newNumberOfCommands)))
  401. {
  402. /* Out of memory. */
  403. return 0;
  404. }
  405. /* Copy any existing commands into the new array. */
  406. {
  407. int i;
  408. for(i=0; i < cp->NumberOfCommands; ++i)
  409. {
  410. newCommands[i] = cp->Commands[i];
  411. }
  412. }
  413. /* We need to construct a single string representing the command
  414. and its arguments. We will surround each argument containing
  415. spaces with double-quotes. Inside a double-quoted argument, we
  416. need to escape double-quotes and all backslashes before them.
  417. We also need to escape backslashes at the end of an argument
  418. because they come before the closing double-quote for the
  419. argument. */
  420. {
  421. char* cmd;
  422. char const* const* arg;
  423. int length = 0;
  424. /* First determine the length of the final string. */
  425. for(arg = command; *arg; ++arg)
  426. {
  427. /* Keep track of how many backslashes have been encountered in a
  428. row in this argument. */
  429. int backslashes = 0;
  430. int spaces = 0;
  431. const char* c;
  432. /* Scan the string for spaces. If there are no spaces, we can
  433. pass the argument verbatim. */
  434. for(c=*arg; *c; ++c)
  435. {
  436. if(*c == ' ' || *c == '\t')
  437. {
  438. spaces = 1;
  439. break;
  440. }
  441. }
  442. /* Add the length of the argument, plus 1 for the space
  443. separating the arguments. */
  444. length += (int)strlen(*arg) + 1;
  445. if(spaces)
  446. {
  447. /* Add 2 for double quotes since spaces are present. */
  448. length += 2;
  449. /* Scan the string to find characters that need escaping. */
  450. for(c=*arg; *c; ++c)
  451. {
  452. if(*c == '\\')
  453. {
  454. /* Found a backslash. It may need to be escaped later. */
  455. ++backslashes;
  456. }
  457. else if(*c == '"')
  458. {
  459. /* Found a double-quote. We need to escape it and all
  460. immediately preceding backslashes. */
  461. length += backslashes + 1;
  462. backslashes = 0;
  463. }
  464. else
  465. {
  466. /* Found another character. This eliminates the possibility
  467. that any immediately preceding backslashes will be
  468. escaped. */
  469. backslashes = 0;
  470. }
  471. }
  472. /* We need to escape all ending backslashes. */
  473. length += backslashes;
  474. }
  475. }
  476. /* Allocate enough space for the command. We do not need an extra
  477. byte for the terminating null because we allocated a space for
  478. the first argument that we will not use. */
  479. newCommands[cp->NumberOfCommands] = (char*)malloc(length);
  480. if(!newCommands[cp->NumberOfCommands])
  481. {
  482. /* Out of memory. */
  483. free(newCommands);
  484. return 0;
  485. }
  486. /* Construct the command line in the allocated buffer. */
  487. cmd = newCommands[cp->NumberOfCommands];
  488. for(arg = command; *arg; ++arg)
  489. {
  490. /* Keep track of how many backslashes have been encountered in a
  491. row in an argument. */
  492. int backslashes = 0;
  493. int spaces = 0;
  494. const char* c;
  495. /* Scan the string for spaces. If there are no spaces, we can
  496. pass the argument verbatim. */
  497. for(c=*arg; *c; ++c)
  498. {
  499. if(*c == ' ' || *c == '\t')
  500. {
  501. spaces = 1;
  502. break;
  503. }
  504. }
  505. /* Add the separating space if this is not the first argument. */
  506. if(arg != command)
  507. {
  508. *cmd++ = ' ';
  509. }
  510. if(spaces)
  511. {
  512. /* Add the opening double-quote for this argument. */
  513. *cmd++ = '"';
  514. /* Add the characters of the argument, possibly escaping them. */
  515. for(c=*arg; *c; ++c)
  516. {
  517. if(*c == '\\')
  518. {
  519. /* Found a backslash. It may need to be escaped later. */
  520. ++backslashes;
  521. *cmd++ = '\\';
  522. }
  523. else if(*c == '"')
  524. {
  525. /* Add enough backslashes to escape any that preceded the
  526. double-quote. */
  527. while(backslashes > 0)
  528. {
  529. --backslashes;
  530. *cmd++ = '\\';
  531. }
  532. /* Add the backslash to escape the double-quote. */
  533. *cmd++ = '\\';
  534. /* Add the double-quote itself. */
  535. *cmd++ = '"';
  536. }
  537. else
  538. {
  539. /* We encountered a normal character. This eliminates any
  540. escaping needed for preceding backslashes. Add the
  541. character. */
  542. backslashes = 0;
  543. *cmd++ = *c;
  544. }
  545. }
  546. /* Add enough backslashes to escape any trailing ones. */
  547. while(backslashes > 0)
  548. {
  549. --backslashes;
  550. *cmd++ = '\\';
  551. }
  552. /* Add the closing double-quote for this argument. */
  553. *cmd++ = '"';
  554. }
  555. else
  556. {
  557. /* No spaces. Add the argument verbatim. */
  558. for(c=*arg; *c; ++c)
  559. {
  560. *cmd++ = *c;
  561. }
  562. }
  563. }
  564. /* Add the terminating null character to the command line. */
  565. *cmd = 0;
  566. }
  567. /* Save the new array of commands. */
  568. free(cp->Commands);
  569. cp->Commands = newCommands;
  570. cp->NumberOfCommands = newNumberOfCommands;
  571. return 1;
  572. }
  573. /*--------------------------------------------------------------------------*/
  574. void kwsysProcess_SetTimeout(kwsysProcess* cp, double timeout)
  575. {
  576. cp->Timeout = timeout;
  577. }
  578. /*--------------------------------------------------------------------------*/
  579. void kwsysProcess_SetWorkingDirectory(kwsysProcess* cp, const char* dir)
  580. {
  581. if(cp->WorkingDirectory)
  582. {
  583. free(cp->WorkingDirectory);
  584. cp->WorkingDirectory = 0;
  585. }
  586. if(dir && dir[0])
  587. {
  588. /* We must convert the working directory to a full path. */
  589. DWORD length = GetFullPathName(dir, 0, 0, 0);
  590. if(length > 0)
  591. {
  592. cp->WorkingDirectory = (char*)malloc(length);
  593. if(!GetFullPathName(dir, length, cp->WorkingDirectory, 0))
  594. {
  595. free(cp->WorkingDirectory);
  596. cp->WorkingDirectory = 0;
  597. }
  598. }
  599. }
  600. }
  601. /*--------------------------------------------------------------------------*/
  602. int kwsysProcess_GetOption(kwsysProcess* cp, int optionId)
  603. {
  604. switch(optionId)
  605. {
  606. case kwsysProcess_Option_HideWindow: return cp->HideWindow;
  607. default: return 0;
  608. }
  609. }
  610. /*--------------------------------------------------------------------------*/
  611. void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, int value)
  612. {
  613. switch(optionId)
  614. {
  615. case kwsysProcess_Option_HideWindow: cp->HideWindow = value; break;
  616. default: break;
  617. }
  618. }
  619. /*--------------------------------------------------------------------------*/
  620. int kwsysProcess_GetState(kwsysProcess* cp)
  621. {
  622. return cp->State;
  623. }
  624. /*--------------------------------------------------------------------------*/
  625. int kwsysProcess_GetExitException(kwsysProcess* cp)
  626. {
  627. return cp->ExitException;
  628. }
  629. /*--------------------------------------------------------------------------*/
  630. int kwsysProcess_GetExitValue(kwsysProcess* cp)
  631. {
  632. return cp->ExitValue;
  633. }
  634. /*--------------------------------------------------------------------------*/
  635. int kwsysProcess_GetExitCode(kwsysProcess* cp)
  636. {
  637. return cp->ExitCode;
  638. }
  639. /*--------------------------------------------------------------------------*/
  640. const char* kwsysProcess_GetErrorString(kwsysProcess* cp)
  641. {
  642. if(cp->State == kwsysProcess_State_Error)
  643. {
  644. return cp->ErrorMessage;
  645. }
  646. return 0;
  647. }
  648. /*--------------------------------------------------------------------------*/
  649. void kwsysProcess_Execute(kwsysProcess* cp)
  650. {
  651. int i;
  652. /* Child startup control data. */
  653. kwsysProcessCreateInformation si;
  654. /* Do not execute a second time. */
  655. if(cp->State == kwsysProcess_State_Executing)
  656. {
  657. return;
  658. }
  659. /* Initialize the control structure for a new process. */
  660. if(!kwsysProcessInitialize(cp))
  661. {
  662. strcpy(cp->ErrorMessage, "Out of memory");
  663. cp->State = kwsysProcess_State_Error;
  664. return;
  665. }
  666. /* Reset the Win9x resume and kill events. */
  667. if(cp->Win9x)
  668. {
  669. if(!ResetEvent(cp->Win9xResumeEvent))
  670. {
  671. kwsysProcessCleanup(cp, 1);
  672. return;
  673. }
  674. if(!ResetEvent(cp->Win9xKillEvent))
  675. {
  676. kwsysProcessCleanup(cp, 1);
  677. return;
  678. }
  679. }
  680. /* Initialize startup info data. */
  681. ZeroMemory(&si, sizeof(si));
  682. si.StartupInfo.cb = sizeof(si.StartupInfo);
  683. /* Decide whether a child window should be shown. */
  684. si.StartupInfo.dwFlags |= STARTF_USESHOWWINDOW;
  685. si.StartupInfo.wShowWindow =
  686. (unsigned short)(cp->HideWindow?SW_HIDE:SW_SHOWDEFAULT);
  687. /* Connect the child's output pipes to the threads. */
  688. si.StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
  689. /* Create stderr pipe to be shared by all processes in the pipeline.
  690. Neither end is directly inherited. */
  691. if(!CreatePipe(&cp->Pipe[KWSYSPE_PIPE_STDERR].Read,
  692. &cp->Pipe[KWSYSPE_PIPE_STDERR].Write, 0, 0))
  693. {
  694. kwsysProcessCleanup(cp, 1);
  695. return;
  696. }
  697. /* Create an inherited duplicate of the write end, but do not
  698. close the non-inherited version. We need to keep it open
  699. to use in waking up the pipe threads. */
  700. if(!DuplicateHandle(GetCurrentProcess(), cp->Pipe[KWSYSPE_PIPE_STDERR].Write,
  701. GetCurrentProcess(), &si.StartupInfo.hStdError,
  702. 0, TRUE, DUPLICATE_SAME_ACCESS))
  703. {
  704. kwsysProcessCleanup(cp, 1);
  705. kwsysProcessCleanupHandle(&si.StartupInfo.hStdError);
  706. return;
  707. }
  708. /* Create the pipeline of processes. */
  709. {
  710. HANDLE readEnd = 0;
  711. for(i=0; i < cp->NumberOfCommands; ++i)
  712. {
  713. if(kwsysProcessCreate(cp, i, &si, &readEnd))
  714. {
  715. cp->ProcessEvents[i+1] = cp->ProcessInformation[i].hProcess;
  716. }
  717. else
  718. {
  719. kwsysProcessCleanup(cp, 1);
  720. /* Release resources that may have been allocated for this
  721. process before an error occurred. */
  722. kwsysProcessCleanupHandle(&readEnd);
  723. if(i > 0)
  724. {
  725. kwsysProcessCleanupHandle(&si.StartupInfo.hStdInput);
  726. }
  727. kwsysProcessCleanupHandle(&si.StartupInfo.hStdOutput);
  728. kwsysProcessCleanupHandle(&si.StartupInfo.hStdError);
  729. kwsysProcessCleanupHandle(&si.ErrorPipeRead);
  730. kwsysProcessCleanupHandle(&si.ErrorPipeWrite);
  731. return;
  732. }
  733. }
  734. /* Save a handle to the output pipe for the last process. */
  735. cp->Pipe[KWSYSPE_PIPE_STDOUT].Read = readEnd;
  736. }
  737. /* Close the inherited handles to the stderr pipe shared by all
  738. processes in the pipeline. */
  739. kwsysProcessCleanupHandle(&si.StartupInfo.hStdError);
  740. /* The timeout period starts now. */
  741. cp->StartTime = kwsysProcessTimeGetCurrent();
  742. cp->TimeoutTime = kwsysProcessTimeFromDouble(-1);
  743. /* All processes in the pipeline have been started in suspended
  744. mode. Resume them all now. */
  745. if(cp->Win9x)
  746. {
  747. SetEvent(cp->Win9xResumeEvent);
  748. }
  749. else
  750. {
  751. for(i=0; i < cp->NumberOfCommands; ++i)
  752. {
  753. ResumeThread(cp->ProcessInformation[i].hThread);
  754. }
  755. }
  756. /* ---- It is no longer safe to call kwsysProcessCleanup. ----- */
  757. /* Tell the pipe threads that a process has started. */
  758. for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
  759. {
  760. ReleaseSemaphore(cp->Pipe[i].Ready, 1, 0);
  761. }
  762. /* We don't care about the children's main threads. */
  763. for(i=0; i < cp->NumberOfCommands; ++i)
  764. {
  765. kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread);
  766. }
  767. /* No pipe has reported data. */
  768. cp->CurrentIndex = KWSYSPE_PIPE_COUNT;
  769. cp->PipesLeft = KWSYSPE_PIPE_COUNT;
  770. /* The process has now started. */
  771. cp->State = kwsysProcess_State_Executing;
  772. }
  773. /*--------------------------------------------------------------------------*/
  774. int kwsysProcess_WaitForData(kwsysProcess* cp, int pipes, char** data, int* length,
  775. double* userTimeout)
  776. {
  777. kwsysProcessTime userStartTime;
  778. kwsysProcessTime timeoutLength;
  779. kwsysProcessTime timeoutTime;
  780. DWORD timeout;
  781. int user;
  782. int done = 0;
  783. int expired = 0;
  784. int pipeId = 0;
  785. DWORD w;
  786. /* Make sure we are executing a process. */
  787. if(cp->State != kwsysProcess_State_Executing || cp->Killed ||
  788. cp->TimeoutExpired)
  789. {
  790. return 0;
  791. }
  792. /* Record the time at which user timeout period starts. */
  793. userStartTime = kwsysProcessTimeGetCurrent();
  794. /* Calculate the time at which a timeout will expire, and whether it
  795. is the user or process timeout. */
  796. user = kwsysProcessGetTimeoutTime(cp, userTimeout, &timeoutTime);
  797. /* Loop until we have a reason to return. */
  798. while(!done && cp->PipesLeft > 0)
  799. {
  800. /* If we previously got data from a thread, let it know we are
  801. done with the data. */
  802. if(cp->CurrentIndex < KWSYSPE_PIPE_COUNT)
  803. {
  804. ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Empty, 1, 0);
  805. cp->CurrentIndex = KWSYSPE_PIPE_COUNT;
  806. }
  807. /* Setup a timeout if required. */
  808. if(kwsysProcessGetTimeoutLeft(&timeoutTime, &timeoutLength))
  809. {
  810. /* Timeout has already expired. */
  811. expired = 1;
  812. break;
  813. }
  814. if(timeoutTime.QuadPart < 0)
  815. {
  816. timeout = INFINITE;
  817. }
  818. else
  819. {
  820. timeout = kwsysProcessTimeToDWORD(timeoutLength);
  821. }
  822. /* Wait for a pipe's thread to signal or a process to terminate. */
  823. w = WaitForMultipleObjects(cp->ProcessEventsLength, cp->ProcessEvents,
  824. 0, timeout);
  825. if(w == WAIT_TIMEOUT)
  826. {
  827. /* Timeout has expired. */
  828. expired = 1;
  829. done = 1;
  830. }
  831. else if(w == WAIT_OBJECT_0)
  832. {
  833. /* Save the index of the reporting thread and release the mutex.
  834. The thread will block until we signal its Empty mutex. */
  835. cp->CurrentIndex = cp->SharedIndex;
  836. ReleaseSemaphore(cp->SharedIndexMutex, 1, 0);
  837. /* Data are available or a pipe closed. */
  838. if(cp->Pipe[cp->CurrentIndex].Closed)
  839. {
  840. /* The pipe closed. */
  841. --cp->PipesLeft;
  842. }
  843. else if(pipes & (1 << cp->CurrentIndex))
  844. {
  845. /* Caller wants this data. Report it. */
  846. *data = cp->Pipe[cp->CurrentIndex].DataBuffer;
  847. *length = cp->Pipe[cp->CurrentIndex].DataLength;
  848. pipeId = (1 << cp->CurrentIndex);
  849. done = 1;
  850. }
  851. else
  852. {
  853. /* Caller does not care about this pipe. Ignore the data. */
  854. }
  855. }
  856. else
  857. {
  858. /* A process has terminated. */
  859. kwsysProcessDestroy(cp, w-WAIT_OBJECT_0);
  860. }
  861. }
  862. /* Update the user timeout. */
  863. if(userTimeout)
  864. {
  865. kwsysProcessTime userEndTime = kwsysProcessTimeGetCurrent();
  866. kwsysProcessTime difference = kwsysProcessTimeSubtract(userEndTime,
  867. userStartTime);
  868. double d = kwsysProcessTimeToDouble(difference);
  869. *userTimeout -= d;
  870. if(*userTimeout < 0)
  871. {
  872. *userTimeout = 0;
  873. }
  874. }
  875. /* Check what happened. */
  876. if(pipeId)
  877. {
  878. /* Data are ready on a pipe. */
  879. return pipeId;
  880. }
  881. else if(expired)
  882. {
  883. /* A timeout has expired. */
  884. if(user)
  885. {
  886. /* The user timeout has expired. It has no time left. */
  887. return kwsysProcess_Pipe_Timeout;
  888. }
  889. else
  890. {
  891. /* The process timeout has expired. Kill the child now. */
  892. kwsysProcess_Kill(cp);
  893. cp->TimeoutExpired = 1;
  894. cp->Killed = 0;
  895. return 0;
  896. }
  897. }
  898. else
  899. {
  900. /* The children have terminated and no more data are available. */
  901. return 0;
  902. }
  903. }
  904. /*--------------------------------------------------------------------------*/
  905. int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
  906. {
  907. int i;
  908. int pipe;
  909. /* Make sure we are executing a process. */
  910. if(cp->State != kwsysProcess_State_Executing)
  911. {
  912. return 1;
  913. }
  914. /* Wait for the process to terminate. Ignore all data. */
  915. while((pipe = kwsysProcess_WaitForData(cp, 0, 0, 0, userTimeout)) > 0)
  916. {
  917. if(pipe == kwsysProcess_Pipe_Timeout)
  918. {
  919. /* The user timeout has expired. */
  920. return 0;
  921. }
  922. }
  923. /* When the last pipe closes in WaitForData, the loop terminates
  924. without releaseing the pipe's thread. Release it now. */
  925. if(cp->CurrentIndex < KWSYSPE_PIPE_COUNT)
  926. {
  927. ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Empty, 1, 0);
  928. cp->CurrentIndex = KWSYSPE_PIPE_COUNT;
  929. }
  930. /* Wait for all pipe threads to reset. */
  931. for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
  932. {
  933. WaitForSingleObject(cp->Pipe[i].Reset, INFINITE);
  934. }
  935. /* ---- It is now safe again to call kwsysProcessCleanup. ----- */
  936. /* Close all the pipes. */
  937. kwsysProcessCleanup(cp, 0);
  938. /* Determine the outcome. */
  939. if(cp->Killed)
  940. {
  941. /* We killed the child. */
  942. cp->State = kwsysProcess_State_Killed;
  943. }
  944. else if(cp->TimeoutExpired)
  945. {
  946. /* The timeout expired. */
  947. cp->State = kwsysProcess_State_Expired;
  948. }
  949. else
  950. {
  951. /* The children exited. Report the outcome of the last process. */
  952. cp->ExitCode = cp->CommandExitCodes[cp->NumberOfCommands-1];
  953. if(cp->ExitCode & 0xC0000000)
  954. {
  955. /* Child terminated due to exceptional behavior. */
  956. cp->State = kwsysProcess_State_Exception;
  957. switch (cp->ExitCode)
  958. {
  959. case CONTROL_C_EXIT:
  960. cp->ExitException = kwsysProcess_Exception_Interrupt; break;
  961. case EXCEPTION_FLT_DENORMAL_OPERAND:
  962. case EXCEPTION_FLT_DIVIDE_BY_ZERO:
  963. case EXCEPTION_FLT_INEXACT_RESULT:
  964. case EXCEPTION_FLT_INVALID_OPERATION:
  965. case EXCEPTION_FLT_OVERFLOW:
  966. case EXCEPTION_FLT_STACK_CHECK:
  967. case EXCEPTION_FLT_UNDERFLOW:
  968. case EXCEPTION_INT_DIVIDE_BY_ZERO:
  969. case EXCEPTION_INT_OVERFLOW:
  970. cp->ExitException = kwsysProcess_Exception_Numerical; break;
  971. case EXCEPTION_ACCESS_VIOLATION:
  972. case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
  973. case EXCEPTION_DATATYPE_MISALIGNMENT:
  974. case EXCEPTION_INVALID_DISPOSITION:
  975. case EXCEPTION_IN_PAGE_ERROR:
  976. case EXCEPTION_NONCONTINUABLE_EXCEPTION:
  977. case EXCEPTION_STACK_OVERFLOW:
  978. cp->ExitException = kwsysProcess_Exception_Fault; break;
  979. case EXCEPTION_ILLEGAL_INSTRUCTION:
  980. case EXCEPTION_PRIV_INSTRUCTION:
  981. cp->ExitException = kwsysProcess_Exception_Illegal; break;
  982. default:
  983. cp->ExitException = kwsysProcess_Exception_Other; break;
  984. }
  985. cp->ExitValue = 1;
  986. }
  987. else
  988. {
  989. /* Child exited normally. */
  990. cp->State = kwsysProcess_State_Exited;
  991. cp->ExitException = kwsysProcess_Exception_None;
  992. cp->ExitValue = cp->ExitCode & 0x000000FF;
  993. }
  994. }
  995. return 1;
  996. }
  997. /*--------------------------------------------------------------------------*/
  998. void kwsysProcess_Kill(kwsysProcess* cp)
  999. {
  1000. int i;
  1001. /* Make sure we are executing a process. */
  1002. if(cp->State != kwsysProcess_State_Executing || cp->TimeoutExpired ||
  1003. cp->Killed || cp->Terminated)
  1004. {
  1005. return;
  1006. }
  1007. /* If we are killing a process that just reported data, release
  1008. the pipe's thread. */
  1009. if(cp->CurrentIndex < KWSYSPE_PIPE_COUNT)
  1010. {
  1011. ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Empty, 1, 0);
  1012. cp->CurrentIndex = KWSYSPE_PIPE_COUNT;
  1013. }
  1014. /* Wake up all the pipe threads with dummy data. */
  1015. for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
  1016. {
  1017. DWORD dummy;
  1018. WriteFile(cp->Pipe[i].Write, "", 1, &dummy, 0);
  1019. }
  1020. /* Tell pipe threads to reset until we run another process. */
  1021. while(cp->PipesLeft > 0)
  1022. {
  1023. WaitForSingleObject(cp->Full, INFINITE);
  1024. cp->CurrentIndex = cp->SharedIndex;
  1025. ReleaseSemaphore(cp->SharedIndexMutex, 1, 0);
  1026. cp->Pipe[cp->CurrentIndex].Closed = 1;
  1027. ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Empty, 1, 0);
  1028. --cp->PipesLeft;
  1029. }
  1030. /* Kill the children. */
  1031. cp->Killed = 1;
  1032. if(cp->Win9x)
  1033. {
  1034. /* Windows 9x. Tell the forwarding executable to kill the child. */
  1035. SetEvent(cp->Win9xKillEvent);
  1036. }
  1037. else
  1038. {
  1039. /* Not Windows 9x. Just terminate the children. */
  1040. for(i=0; i < cp->NumberOfCommands; ++i)
  1041. {
  1042. TerminateProcess(cp->ProcessInformation[i].hProcess, 255);
  1043. }
  1044. }
  1045. /* Wait for windows to finish cleaning up the children. */
  1046. for(i=0; i < cp->NumberOfCommands; ++i)
  1047. {
  1048. WaitForSingleObject(cp->ProcessInformation[i].hProcess, INFINITE);
  1049. }
  1050. }
  1051. /*--------------------------------------------------------------------------*/
  1052. /*
  1053. Function executed for each pipe's thread. Argument is a pointer to
  1054. the kwsysProcessPipeData instance for this thread.
  1055. */
  1056. DWORD WINAPI kwsysProcessPipeThread(LPVOID ptd)
  1057. {
  1058. kwsysProcessPipeData* td = (kwsysProcessPipeData*)ptd;
  1059. kwsysProcess* cp = td->Process;
  1060. /* Wait for a process to be ready. */
  1061. while((WaitForSingleObject(td->Ready, INFINITE), !cp->Deleting))
  1062. {
  1063. /* Read output from the process for this thread's pipe. */
  1064. kwsysProcessPipeThreadReadPipe(cp, td);
  1065. /* We were signalled to exit with our buffer empty. Reset the
  1066. mutex for a new process. */
  1067. ReleaseSemaphore(td->Empty, 1, 0);
  1068. /* Signal the main thread we have reset for a new process. */
  1069. ReleaseSemaphore(td->Reset, 1, 0);
  1070. }
  1071. return 0;
  1072. }
  1073. /*--------------------------------------------------------------------------*/
  1074. /*
  1075. Function called in each pipe's thread to handle data for one
  1076. execution of a subprocess.
  1077. */
  1078. void kwsysProcessPipeThreadReadPipe(kwsysProcess* cp, kwsysProcessPipeData* td)
  1079. {
  1080. /* Wait for space in the thread's buffer. */
  1081. while((WaitForSingleObject(td->Empty, INFINITE), !td->Closed))
  1082. {
  1083. /* Read data from the pipe. This may block until data are available. */
  1084. if(!ReadFile(td->Read, td->DataBuffer, KWSYSPE_PIPE_BUFFER_SIZE,
  1085. &td->DataLength, 0))
  1086. {
  1087. if(GetLastError() != ERROR_BROKEN_PIPE)
  1088. {
  1089. /* UNEXPECTED failure to read the pipe. */
  1090. }
  1091. /* The pipe closed. There are no more data to read. */
  1092. td->Closed = 1;
  1093. }
  1094. /* Wait for our turn to be handled by the main thread. */
  1095. WaitForSingleObject(cp->SharedIndexMutex, INFINITE);
  1096. /* Tell the main thread we have something to report. */
  1097. cp->SharedIndex = td->Index;
  1098. ReleaseSemaphore(cp->Full, 1, 0);
  1099. }
  1100. }
  1101. /*--------------------------------------------------------------------------*/
  1102. /* Initialize a process control structure for kwsysProcess_Execute. */
  1103. int kwsysProcessInitialize(kwsysProcess* cp)
  1104. {
  1105. /* Reset internal status flags. */
  1106. cp->TimeoutExpired = 0;
  1107. cp->Terminated = 0;
  1108. cp->Killed = 0;
  1109. cp->ExitException = kwsysProcess_Exception_None;
  1110. cp->ExitCode = 1;
  1111. cp->ExitValue = 1;
  1112. /* Reset error data. */
  1113. cp->ErrorMessage[0] = 0;
  1114. /* Allocate process information for each process. */
  1115. cp->ProcessInformation =
  1116. (PROCESS_INFORMATION*)malloc(sizeof(PROCESS_INFORMATION) *
  1117. cp->NumberOfCommands);
  1118. if(!cp->ProcessInformation)
  1119. {
  1120. return 0;
  1121. }
  1122. ZeroMemory(cp->ProcessInformation,
  1123. sizeof(PROCESS_INFORMATION) * cp->NumberOfCommands);
  1124. if(cp->CommandExitCodes)
  1125. {
  1126. free(cp->CommandExitCodes);
  1127. }
  1128. cp->CommandExitCodes = (DWORD*)malloc(sizeof(DWORD)*cp->NumberOfCommands);
  1129. if(!cp->CommandExitCodes)
  1130. {
  1131. return 0;
  1132. }
  1133. ZeroMemory(cp->CommandExitCodes, sizeof(DWORD)*cp->NumberOfCommands);
  1134. /* Allocate event wait array. The first event is cp->Full, the rest
  1135. are the process termination events. */
  1136. cp->ProcessEvents = (PHANDLE)malloc(sizeof(HANDLE)*(cp->NumberOfCommands+1));
  1137. if(!cp->ProcessEvents)
  1138. {
  1139. return 0;
  1140. }
  1141. ZeroMemory(cp->ProcessEvents, sizeof(HANDLE) * (cp->NumberOfCommands+1));
  1142. cp->ProcessEvents[0] = cp->Full;
  1143. cp->ProcessEventsLength = cp->NumberOfCommands+1;
  1144. return 1;
  1145. }
  1146. /*--------------------------------------------------------------------------*/
  1147. int kwsysProcessCreate(kwsysProcess* cp, int index,
  1148. kwsysProcessCreateInformation* si,
  1149. PHANDLE readEnd)
  1150. {
  1151. /* Setup the process's stdin. */
  1152. if(*readEnd)
  1153. {
  1154. /* Create an inherited duplicate of the read end from the output
  1155. pipe of the previous process. This also closes the
  1156. non-inherited version. */
  1157. if(!DuplicateHandle(GetCurrentProcess(), *readEnd,
  1158. GetCurrentProcess(), readEnd,
  1159. 0, TRUE, (DUPLICATE_CLOSE_SOURCE |
  1160. DUPLICATE_SAME_ACCESS)))
  1161. {
  1162. return 0;
  1163. }
  1164. si->StartupInfo.hStdInput = *readEnd;
  1165. /* This function is done with this handle. */
  1166. *readEnd = 0;
  1167. }
  1168. else
  1169. {
  1170. si->StartupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
  1171. }
  1172. /* Setup the process's stdout. */
  1173. {
  1174. DWORD maybeClose = DUPLICATE_CLOSE_SOURCE;
  1175. HANDLE writeEnd;
  1176. /* Create the output pipe for this process. Neither end is directly
  1177. inherited. */
  1178. if(!CreatePipe(readEnd, &writeEnd, 0, 0))
  1179. {
  1180. return 0;
  1181. }
  1182. /* Create an inherited duplicate of the write end. Close the
  1183. non-inherited version unless this is the last process. Save the
  1184. non-inherited write end of the last process. */
  1185. if(index == cp->NumberOfCommands-1)
  1186. {
  1187. cp->Pipe[KWSYSPE_PIPE_STDOUT].Write = writeEnd;
  1188. maybeClose = 0;
  1189. }
  1190. if(!DuplicateHandle(GetCurrentProcess(), writeEnd,
  1191. GetCurrentProcess(), &si->StartupInfo.hStdOutput,
  1192. 0, TRUE, (maybeClose | DUPLICATE_SAME_ACCESS)))
  1193. {
  1194. return 0;
  1195. }
  1196. }
  1197. /* Create the child process. */
  1198. {
  1199. BOOL r;
  1200. char* realCommand;
  1201. if(cp->Win9x)
  1202. {
  1203. /* Create an error reporting pipe for the forwarding executable.
  1204. Neither end is directly inherited. */
  1205. if(!CreatePipe(&si->ErrorPipeRead, &si->ErrorPipeWrite, 0, 0))
  1206. {
  1207. return 0;
  1208. }
  1209. /* Create an inherited duplicate of the write end. This also closes
  1210. the non-inherited version. */
  1211. if(!DuplicateHandle(GetCurrentProcess(), si->ErrorPipeWrite,
  1212. GetCurrentProcess(), &si->ErrorPipeWrite,
  1213. 0, TRUE, (DUPLICATE_CLOSE_SOURCE |
  1214. DUPLICATE_SAME_ACCESS)))
  1215. {
  1216. return 0;
  1217. }
  1218. /* The forwarding executable is given a handle to the error pipe
  1219. and resume and kill events. */
  1220. realCommand = malloc(strlen(cp->Win9x)+strlen(cp->Commands[index])+100);
  1221. if(!realCommand)
  1222. {
  1223. return 0;
  1224. }
  1225. sprintf(realCommand, "%s %p %p %p %d %s", cp->Win9x,
  1226. si->ErrorPipeWrite, cp->Win9xResumeEvent, cp->Win9xKillEvent,
  1227. cp->HideWindow, cp->Commands[index]);
  1228. }
  1229. else
  1230. {
  1231. realCommand = cp->Commands[index];
  1232. }
  1233. /* Create the child in a suspended state so we can wait until all
  1234. children have been created before running any one. */
  1235. r = CreateProcess(0, realCommand, 0, 0, TRUE,
  1236. cp->Win9x? 0 : CREATE_SUSPENDED, 0,
  1237. cp->WorkingDirectory, &si->StartupInfo,
  1238. &cp->ProcessInformation[index]);
  1239. if(cp->Win9x)
  1240. {
  1241. /* Free memory. */
  1242. free(realCommand);
  1243. /* Close the error pipe write end so we can detect when the
  1244. forwarding executable closes it. */
  1245. kwsysProcessCleanupHandle(&si->ErrorPipeWrite);
  1246. if(r)
  1247. {
  1248. /* Wait for the forwarding executable to report an error or
  1249. close the error pipe to report success. */
  1250. DWORD total = 0;
  1251. DWORD n = 1;
  1252. while(total < KWSYSPE_PIPE_BUFFER_SIZE && n > 0)
  1253. {
  1254. if(ReadFile(si->ErrorPipeRead, cp->ErrorMessage+total,
  1255. KWSYSPE_PIPE_BUFFER_SIZE-total, &n, 0))
  1256. {
  1257. total += n;
  1258. }
  1259. else
  1260. {
  1261. n = 0;
  1262. }
  1263. }
  1264. if(total > 0 || GetLastError() != ERROR_BROKEN_PIPE)
  1265. {
  1266. /* The forwarding executable could not run the process, or
  1267. there was an error reading from its error pipe. Preserve
  1268. the last error while cleaning up the forwarding executable
  1269. so the cleanup our caller does reports the proper error. */
  1270. DWORD error = GetLastError();
  1271. kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hThread);
  1272. kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hProcess);
  1273. SetLastError(error);
  1274. return 0;
  1275. }
  1276. }
  1277. kwsysProcessCleanupHandle(&si->ErrorPipeRead);
  1278. }
  1279. if(!r)
  1280. {
  1281. return 0;
  1282. }
  1283. }
  1284. /* Successfully created this child process. */
  1285. if(index > 0)
  1286. {
  1287. /* Close our handle to the input pipe for the current process. */
  1288. kwsysProcessCleanupHandle(&si->StartupInfo.hStdInput);
  1289. }
  1290. /* The parent process does not need the inhertied pipe write end. */
  1291. kwsysProcessCleanupHandle(&si->StartupInfo.hStdOutput);
  1292. return 1;
  1293. }
  1294. /*--------------------------------------------------------------------------*/
  1295. void kwsysProcessDestroy(kwsysProcess* cp, int event)
  1296. {
  1297. int i;
  1298. int index;
  1299. /* Find the process index for the termination event. */
  1300. for(index=0; index < cp->NumberOfCommands; ++index)
  1301. {
  1302. if(cp->ProcessInformation[index].hProcess == cp->ProcessEvents[event])
  1303. {
  1304. break;
  1305. }
  1306. }
  1307. /* Check the exit code of the process. */
  1308. GetExitCodeProcess(cp->ProcessInformation[index].hProcess,
  1309. &cp->CommandExitCodes[index]);
  1310. /* Close the process handle for the terminated process. */
  1311. kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hProcess);
  1312. /* Remove the process from the available events. */
  1313. cp->ProcessEventsLength -= 1;
  1314. for(i=event; i < cp->ProcessEventsLength; ++i)
  1315. {
  1316. cp->ProcessEvents[i] = cp->ProcessEvents[i+1];
  1317. }
  1318. /* Check if all processes have terminated. */
  1319. if(cp->ProcessEventsLength == 1)
  1320. {
  1321. cp->Terminated = 1;
  1322. /* Close our copies of the pipe write handles so the pipe threads
  1323. can detect end-of-data. */
  1324. for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
  1325. {
  1326. kwsysProcessCleanupHandle(&cp->Pipe[i].Write);
  1327. }
  1328. }
  1329. }
  1330. /*--------------------------------------------------------------------------*/
  1331. /* Close the given handle if it is open. Reset its value to 0. */
  1332. void kwsysProcessCleanupHandle(PHANDLE h)
  1333. {
  1334. if(h && *h)
  1335. {
  1336. CloseHandle(*h);
  1337. *h = 0;
  1338. }
  1339. }
  1340. /*--------------------------------------------------------------------------*/
  1341. /* Close all handles created by kwsysProcess_Execute. */
  1342. void kwsysProcessCleanup(kwsysProcess* cp, int error)
  1343. {
  1344. int i;
  1345. /* If this is an error case, report the error. */
  1346. if(error)
  1347. {
  1348. /* Construct an error message if one has not been provided already. */
  1349. if(cp->ErrorMessage[0] == 0)
  1350. {
  1351. /* Format the error message. */
  1352. DWORD original = GetLastError();
  1353. DWORD length = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
  1354. FORMAT_MESSAGE_IGNORE_INSERTS, 0, original,
  1355. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  1356. cp->ErrorMessage, KWSYSPE_PIPE_BUFFER_SIZE, 0);
  1357. if(length < 1)
  1358. {
  1359. /* FormatMessage failed. Use a default message. */
  1360. _snprintf(cp->ErrorMessage, KWSYSPE_PIPE_BUFFER_SIZE,
  1361. "Process execution failed with error 0x%X. "
  1362. "FormatMessage failed with error 0x%X",
  1363. original, GetLastError());
  1364. }
  1365. }
  1366. /* Remove trailing period and newline, if any. */
  1367. kwsysProcessCleanErrorMessage(cp);
  1368. /* Set the error state. */
  1369. cp->State = kwsysProcess_State_Error;
  1370. /* Cleanup any processes already started in a suspended state. */
  1371. if(cp->ProcessInformation)
  1372. {
  1373. if(cp->Win9x)
  1374. {
  1375. SetEvent(cp->Win9xKillEvent);
  1376. }
  1377. else
  1378. {
  1379. for(i=0; i < cp->NumberOfCommands; ++i)
  1380. {
  1381. if(cp->ProcessInformation[i].hProcess)
  1382. {
  1383. TerminateProcess(cp->ProcessInformation[i].hProcess, 255);
  1384. WaitForSingleObject(cp->ProcessInformation[i].hProcess, INFINITE);
  1385. }
  1386. }
  1387. }
  1388. for(i=0; i < cp->NumberOfCommands; ++i)
  1389. {
  1390. kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread);
  1391. kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hProcess);
  1392. }
  1393. }
  1394. }
  1395. /* Free memory. */
  1396. if(cp->ProcessInformation)
  1397. {
  1398. free(cp->ProcessInformation);
  1399. cp->ProcessInformation = 0;
  1400. }
  1401. if(cp->ProcessEvents)
  1402. {
  1403. free(cp->ProcessEvents);
  1404. cp->ProcessEvents = 0;
  1405. }
  1406. /* Close each pipe. */
  1407. for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
  1408. {
  1409. kwsysProcessCleanupHandle(&cp->Pipe[i].Write);
  1410. kwsysProcessCleanupHandle(&cp->Pipe[i].Read);
  1411. }
  1412. }
  1413. /*--------------------------------------------------------------------------*/
  1414. void kwsysProcessCleanErrorMessage(kwsysProcess* cp)
  1415. {
  1416. /* Remove trailing period and newline, if any. */
  1417. int length = strlen(cp->ErrorMessage);
  1418. if(cp->ErrorMessage[length-1] == '\n')
  1419. {
  1420. cp->ErrorMessage[length-1] = 0;
  1421. --length;
  1422. if(length > 0 && cp->ErrorMessage[length-1] == '\r')
  1423. {
  1424. cp->ErrorMessage[length-1] = 0;
  1425. --length;
  1426. }
  1427. }
  1428. if(length > 0 && cp->ErrorMessage[length-1] == '.')
  1429. {
  1430. cp->ErrorMessage[length-1] = 0;
  1431. }
  1432. }
  1433. /*--------------------------------------------------------------------------*/
  1434. /* Get the time at which either the process or user timeout will
  1435. expire. Returns 1 if the user timeout is first, and 0 otherwise. */
  1436. int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
  1437. kwsysProcessTime* timeoutTime)
  1438. {
  1439. /* The first time this is called, we need to calculate the time at
  1440. which the child will timeout. */
  1441. if(cp->Timeout && cp->TimeoutTime.QuadPart < 0)
  1442. {
  1443. kwsysProcessTime length = kwsysProcessTimeFromDouble(cp->Timeout);
  1444. cp->TimeoutTime = kwsysProcessTimeAdd(cp->StartTime, length);
  1445. }
  1446. /* Start with process timeout. */
  1447. *timeoutTime = cp->TimeoutTime;
  1448. /* Check if the user timeout is earlier. */
  1449. if(userTimeout)
  1450. {
  1451. kwsysProcessTime currentTime = kwsysProcessTimeGetCurrent();
  1452. kwsysProcessTime userTimeoutLength = kwsysProcessTimeFromDouble(*userTimeout);
  1453. kwsysProcessTime userTimeoutTime = kwsysProcessTimeAdd(currentTime,
  1454. userTimeoutLength);
  1455. if(kwsysProcessTimeLess(userTimeoutTime, *timeoutTime))
  1456. {
  1457. *timeoutTime = userTimeoutTime;
  1458. return 1;
  1459. }
  1460. }
  1461. return 0;
  1462. }
  1463. /*--------------------------------------------------------------------------*/
  1464. /* Get the length of time before the given timeout time arrives.
  1465. Returns 1 if the time has already arrived, and 0 otherwise. */
  1466. int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime,
  1467. kwsysProcessTime* timeoutLength)
  1468. {
  1469. if(timeoutTime->QuadPart < 0)
  1470. {
  1471. /* No timeout time has been requested. */
  1472. return 0;
  1473. }
  1474. else
  1475. {
  1476. /* Calculate the remaining time. */
  1477. kwsysProcessTime currentTime = kwsysProcessTimeGetCurrent();
  1478. *timeoutLength = kwsysProcessTimeSubtract(*timeoutTime, currentTime);
  1479. if(timeoutLength->QuadPart < 0)
  1480. {
  1481. /* Timeout has already expired. */
  1482. return 1;
  1483. }
  1484. else
  1485. {
  1486. /* There is some time left. */
  1487. return 0;
  1488. }
  1489. }
  1490. }
  1491. /*--------------------------------------------------------------------------*/
  1492. kwsysProcessTime kwsysProcessTimeGetCurrent()
  1493. {
  1494. kwsysProcessTime current;
  1495. FILETIME ft;
  1496. GetSystemTimeAsFileTime(&ft);
  1497. current.LowPart = ft.dwLowDateTime;
  1498. current.HighPart = ft.dwHighDateTime;
  1499. return current;
  1500. }
  1501. /*--------------------------------------------------------------------------*/
  1502. DWORD kwsysProcessTimeToDWORD(kwsysProcessTime t)
  1503. {
  1504. return (DWORD)(t.QuadPart * 0.0001);
  1505. }
  1506. /*--------------------------------------------------------------------------*/
  1507. double kwsysProcessTimeToDouble(kwsysProcessTime t)
  1508. {
  1509. return t.QuadPart * 0.0000001;
  1510. }
  1511. /*--------------------------------------------------------------------------*/
  1512. kwsysProcessTime kwsysProcessTimeFromDouble(double d)
  1513. {
  1514. kwsysProcessTime t;
  1515. t.QuadPart = (LONGLONG)(d*10000000);
  1516. return t;
  1517. }
  1518. /*--------------------------------------------------------------------------*/
  1519. int kwsysProcessTimeLess(kwsysProcessTime in1, kwsysProcessTime in2)
  1520. {
  1521. return in1.QuadPart < in2.QuadPart;
  1522. }
  1523. /*--------------------------------------------------------------------------*/
  1524. kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, kwsysProcessTime in2)
  1525. {
  1526. kwsysProcessTime out;
  1527. out.QuadPart = in1.QuadPart + in2.QuadPart;
  1528. return out;
  1529. }
  1530. /*--------------------------------------------------------------------------*/
  1531. kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProcessTime in2)
  1532. {
  1533. kwsysProcessTime out;
  1534. out.QuadPart = in1.QuadPart - in2.QuadPart;
  1535. return out;
  1536. }