ProcessWin32.c 85.8 KB
Newer Older
1
2
/*=========================================================================

Brad King's avatar
Brad King committed
3
4
5
6
7
8
9
10
11
  Program:   KWSys - Kitware System Library
  Module:    ProcessWin32.c

  Copyright (c) Kitware, Inc., Insight Consortium.  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.
12
13

=========================================================================*/
14
15
#include "kwsysPrivate.h"
#include KWSYS_HEADER(Process.h)
16

17
18
19
20
21
22
/* Work-around CMake dependency scanning limitation.  This must
   duplicate the above list of headers.  */
#if 0
# include "Process.h.in"
#endif

23
24
25
/*

Implementation for Windows
26

27
28
29
On windows, a thread is created to wait for data on each pipe.  The
threads are synchronized with the main thread to simulate the use of
a UNIX-style select system call.
30

31
32
33
34
On Windows9x platforms, a small WIN32 console application is spawned
in-between the calling process and the actual child to be executed.
This is to work-around a problem with connecting pipes from WIN16
console applications to WIN32 applications.
35

36
37
38
39
40
For more information, please check Microsoft Knowledge Base Articles
Q190351 and Q150956.

*/

41
42
43
#ifdef _MSC_VER
#pragma warning (push, 1)
#endif
44
45
46
47
#include <windows.h> /* Windows API */
#include <string.h>  /* strlen, strdup */
#include <stdio.h>   /* sprintf */
#include <io.h>      /* _unlink */
48
49
50
#ifdef __WATCOMC__
#define _unlink unlink
#endif
51
52
53
54
55
56
57
58

#ifndef _MAX_FNAME
#define _MAX_FNAME 4096
#endif
#ifndef _MAX_PATH
#define _MAX_PATH 4096
#endif

59
60
61
62
63
#ifdef _MSC_VER
#pragma warning (pop)
#pragma warning (disable: 4514)
#pragma warning (disable: 4706)
#endif
64

65
66
67
68
#if defined(__BORLANDC__)
# pragma warn -8060 /* Assignment inside if() condition.  */
#endif

69
70
/* There are pipes for the process pipeline's stdout and stderr.  */
#define KWSYSPE_PIPE_COUNT 2
71
72
#define KWSYSPE_PIPE_STDOUT 0
#define KWSYSPE_PIPE_STDERR 1
73
74

/* The maximum amount to read from a pipe at a time.  */
75
#define KWSYSPE_PIPE_BUFFER_SIZE 1024
76

77
#define kwsysEncodedWriteArrayProcessFwd9x kwsys_ns(EncodedWriteArrayProcessFwd9x)
78
79
80

typedef LARGE_INTEGER kwsysProcessTime;

81
82
83
84
85
typedef struct kwsysProcessCreateInformation_s
{
  /* Windows child startup control data.  */
  STARTUPINFO StartupInfo;

86
87
88
  /* Special error reporting pipe for Win9x forwarding executable.  */
  HANDLE ErrorPipeRead;
  HANDLE ErrorPipeWrite;
89
90
} kwsysProcessCreateInformation;

91
92
/*--------------------------------------------------------------------------*/
typedef struct kwsysProcessPipeData_s kwsysProcessPipeData;
93
94
95
static DWORD WINAPI kwsysProcessPipeThreadRead(LPVOID ptd);
static void kwsysProcessPipeThreadReadPipe(kwsysProcess* cp,
                                           kwsysProcessPipeData* td);
96
static DWORD WINAPI kwsysProcessPipeThreadWake(LPVOID ptd);
97
98
static void kwsysProcessPipeThreadWakePipe(kwsysProcess* cp,
                                           kwsysProcessPipeData* td);
99
static int kwsysProcessInitialize(kwsysProcess* cp);
100
101
static int kwsysProcessCreate(kwsysProcess* cp, int index,
                              kwsysProcessCreateInformation* si,
102
103
                              PHANDLE readEnd);
static void kwsysProcessDestroy(kwsysProcess* cp, int event);
104
static int kwsysProcessSetupOutputPipeFile(PHANDLE handle, const char* name);
105
static int kwsysProcessSetupSharedPipe(DWORD nStdHandle, PHANDLE handle);
106
static void kwsysProcessCleanupHandle(PHANDLE h);
107
static void kwsysProcessCleanupHandleSafe(PHANDLE h, DWORD nStdHandle);
108
static void kwsysProcessCleanup(kwsysProcess* cp, int error);
109
static void kwsysProcessCleanErrorMessage(kwsysProcess* cp);
110
111
112
113
114
static int kwsysProcessComputeCommandLength(kwsysProcess* cp,
                                            char const* const* command);
static void kwsysProcessComputeCommandLine(kwsysProcess* cp,
                                           char const* const* command,
                                           char* cmd);
115
116
static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
                                      kwsysProcessTime* timeoutTime);
117
static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime,
118
                                      double* userTimeout,
119
                                      kwsysProcessTime* timeoutLength);
120
static kwsysProcessTime kwsysProcessTimeGetCurrent(void);
121
122
123
124
125
126
static DWORD kwsysProcessTimeToDWORD(kwsysProcessTime t);
static double kwsysProcessTimeToDouble(kwsysProcessTime t);
static kwsysProcessTime kwsysProcessTimeFromDouble(double d);
static int kwsysProcessTimeLess(kwsysProcessTime in1, kwsysProcessTime in2);
static kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, kwsysProcessTime in2);
static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProcessTime in2);
127
static void kwsysProcessSetExitException(kwsysProcess* cp, int code);
128
static void kwsysProcessKillTree(int pid);
129
static void kwsysProcessDisablePipeThreads(kwsysProcess* cp);
Brad King's avatar
Brad King committed
130
extern kwsysEXPORT int kwsysEncodedWriteArrayProcessFwd9x(const char* fname);
131
132

/*--------------------------------------------------------------------------*/
133
134
135
/* A structure containing synchronization data for each thread.  */
typedef struct kwsysProcessPipeSync_s kwsysProcessPipeSync;
struct kwsysProcessPipeSync_s
136
{
137
  /* Handle to the thread.  */
138
  HANDLE Thread;
139

140
  /* Semaphore indicating to the thread that a process has started.  */
141
  HANDLE Ready;
142

143
144
  /* Semaphore indicating to the thread that it should begin work.  */
  HANDLE Go;
145

146
  /* Semaphore indicating thread has reset for another process.  */
147
  HANDLE Reset;
148
};
149

150
151
152
153
154
155
156
157
/*--------------------------------------------------------------------------*/
/* A structure containing data for each pipe's threads.  */
struct kwsysProcessPipeData_s
{
  /* ------------- Data managed per instance of kwsysProcess ------------- */

  /* Synchronization data for reading thread.  */
  kwsysProcessPipeSync Reader;
158

159
160
  /* Synchronization data for waking thread.  */
  kwsysProcessPipeSync Waker;
161

162
163
164
165
166
  /* Index of this pipe.  */
  int Index;

  /* The kwsysProcess instance owning this pipe.  */
  kwsysProcess* Process;
167

168
  /* ------------- Data managed per call to Execute ------------- */
169

170
  /* Buffer for data read in this pipe's thread.  */
171
  char DataBuffer[KWSYSPE_PIPE_BUFFER_SIZE];
172

173
174
  /* The length of the data stored in the buffer.  */
  DWORD DataLength;
175

176
177
  /* Whether the pipe has been closed.  */
  int Closed;
178

179
180
  /* Handle for the read end of this pipe. */
  HANDLE Read;
181

182
183
  /* Handle for the write end of this pipe. */
  HANDLE Write;
184
};
185
186
187
188
189
190

/*--------------------------------------------------------------------------*/
/* Structure containing data used to implement the child's execution.  */
struct kwsysProcess_s
{
  /* ------------- Data managed per instance of kwsysProcess ------------- */
191

192
  /* The status of the process structure.  */
193
  int State;
194

195
196
197
198
199
200
  /* The command lines to execute.  */
  char** Commands;
  int NumberOfCommands;

  /* The exit code of each command.  */
  DWORD* CommandExitCodes;
201

202
203
  /* The working directory for the child process.  */
  char* WorkingDirectory;
204

205
206
207
208
209
210
  /* Whether to create the child as a detached process.  */
  int OptionDetach;

  /* Whether the child was created as a detached process.  */
  int Detached;

211
212
  /* Whether to hide the child process's window.  */
  int HideWindow;
213

214
215
216
  /* Whether to treat command lines as verbatim.  */
  int Verbatim;

217
218
  /* On Win9x platforms, the path to the forwarding executable.  */
  char* Win9x;
219

220
221
  /* On Win9x platforms, the resume event for the forwarding executable.  */
  HANDLE Win9xResumeEvent;
222

223
224
  /* On Win9x platforms, the kill event for the forwarding executable.  */
  HANDLE Win9xKillEvent;
225

226
227
  /* Mutex to protect the shared index used by threads to report data.  */
  HANDLE SharedIndexMutex;
228

229
230
  /* Semaphore used by threads to signal data ready.  */
  HANDLE Full;
231

232
233
  /* Whether we are currently deleting this kwsysProcess instance.  */
  int Deleting;
234

235
  /* Data specific to each pipe and its thread.  */
236
237
  kwsysProcessPipeData Pipe[KWSYSPE_PIPE_COUNT];

238
239
240
241
242
  /* Name of files to which stdin and stdout pipes are attached.  */
  char* PipeFileSTDIN;
  char* PipeFileSTDOUT;
  char* PipeFileSTDERR;

243
244
245
246
247
  /* Whether each pipe is shared with the parent process.  */
  int PipeSharedSTDIN;
  int PipeSharedSTDOUT;
  int PipeSharedSTDERR;

248
249
250
  /* Handle to automatically delete the Win9x forwarding executable.  */
  HANDLE Win9xHandle;

251
  /* ------------- Data managed per call to Execute ------------- */
252

253
254
  /* The exceptional behavior that terminated the process, if any.  */
  int ExitException;
255

256
  /* The process exit code.  */
257
  DWORD ExitCode;
258

259
260
  /* The process return code, if any.  */
  int ExitValue;
261

262
263
  /* Index of last pipe to report data, if any.  */
  int CurrentIndex;
264
265

  /* Index shared by threads to report data.  */
266
  int SharedIndex;
267

268
269
  /* The timeout length.  */
  double Timeout;
270

271
272
  /* Time at which the child started.  */
  kwsysProcessTime StartTime;
273

274
275
  /* Time at which the child will timeout.  Negative for no timeout.  */
  kwsysProcessTime TimeoutTime;
276

277
278
  /* Flag for whether the process was killed.  */
  int Killed;
279

280
281
  /* Flag for whether the timeout expired.  */
  int TimeoutExpired;
282

283
284
  /* Flag for whether the process has terminated.  */
  int Terminated;
285

286
287
288
  /* The number of pipes still open during execution and while waiting
     for pipes to close after process termination.  */
  int PipesLeft;
289

290
  /* Buffer for error messages (possibly from Win9x child).  */
291
  char ErrorMessage[KWSYSPE_PIPE_BUFFER_SIZE+1];
292

293
294
295
  /* Description for the ExitException.  */
  char ExitExceptionString[KWSYSPE_PIPE_BUFFER_SIZE+1];

296
  /* Windows process information data.  */
297
298
299
300
301
  PROCESS_INFORMATION* ProcessInformation;

  /* Data and process termination events for which to wait.  */
  PHANDLE ProcessEvents;
  int ProcessEventsLength;
302
303
304
305

  /* Real working directory of our own process.  */
  DWORD RealWorkingDirectoryLength;
  char* RealWorkingDirectory;
306
307
308
};

/*--------------------------------------------------------------------------*/
309
kwsysProcess* kwsysProcess_New(void)
310
311
312
313
314
315
316
317
318
319
320
{
  int i;

  /* Process control structure.  */
  kwsysProcess* cp;

  /* Path to Win9x forwarding executable.  */
  char* win9x = 0;

  /* Windows version number data.  */
  OSVERSIONINFO osv;
321

322
323
  /* Allocate a process control structure.  */
  cp = (kwsysProcess*)malloc(sizeof(kwsysProcess));
324
325
326
327
328
  if(!cp)
    {
    /* Could not allocate memory for the control structure.  */
    return 0;
    }
329
  ZeroMemory(cp, sizeof(*cp));
330

331
332
333
  /* Share stdin with the parent process by default.  */
  cp->PipeSharedSTDIN = 1;

334
  /* Set initial status.  */
335
  cp->State = kwsysProcess_State_Starting;
336

337
338
339
340
341
  /* Choose a method of running the child based on version of
     windows.  */
  ZeroMemory(&osv, sizeof(osv));
  osv.dwOSVersionInfoSize = sizeof(osv);
  GetVersionEx(&osv);
342
  if(osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
343
344
345
346
347
    {
    /* This is Win9x.  We need the console forwarding executable to
       work-around a Windows 9x bug.  */
    char fwdName[_MAX_FNAME+1] = "";
    char tempDir[_MAX_PATH+1] = "";
348

349
    /* We will try putting the executable in the system temp
350
351
352
       directory.  Note that the returned path already has a trailing
       slash.  */
    DWORD length = GetTempPath(_MAX_PATH+1, tempDir);
353

354
355
    /* Construct the executable name from the process id and kwsysProcess
       instance.  This should be unique.  */
356
357
    sprintf(fwdName, KWSYS_NAMESPACE_STRING "pew9xfwd_%u_%p.exe",
            GetCurrentProcessId(), cp);
358

359
    /* If we have a temp directory, use it.  */
360
361
362
    if(length > 0 && length <= _MAX_PATH)
      {
      /* Allocate a buffer to hold the forwarding executable path.  */
363
      size_t tdlen = strlen(tempDir);
364
365
366
367
368
369
      win9x = (char*)malloc(tdlen + strlen(fwdName) + 2);
      if(!win9x)
        {
        kwsysProcess_Delete(cp);
        return 0;
        }
370

371
      /* Construct the full path to the forwarding executable.  */
372
      sprintf(win9x, "%s%s", tempDir, fwdName);
373
      }
374

375
376
377
378
379
380
381
382
383
384
385
    /* If we found a place to put the forwarding executable, try to
       write it. */
    if(win9x)
      {
      if(!kwsysEncodedWriteArrayProcessFwd9x(win9x))
        {
        /* Failed to create forwarding executable.  Give up.  */
        free(win9x);
        kwsysProcess_Delete(cp);
        return 0;
        }
386
387
388
389
390
391
392
393
394
395
396
397
398

      /* Get a handle to the file that will delete it when closed.  */
      cp->Win9xHandle = CreateFile(win9x, GENERIC_READ, FILE_SHARE_READ, 0,
                                   OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0);
      if(cp->Win9xHandle == INVALID_HANDLE_VALUE)
        {
        /* We were not able to get a read handle for the forwarding
           executable.  It will not be deleted properly.  Give up.  */
        _unlink(win9x);
        free(win9x);
        kwsysProcess_Delete(cp);
        return 0;
        }
399
400
401
402
403
404
405
406
      }
    else
      {
      /* Failed to find a place to put forwarding executable.  */
      kwsysProcess_Delete(cp);
      return 0;
      }
    }
407

408
  /* Save the path to the forwarding executable.  */
409
  cp->Win9x = win9x;
410

411
412
413
414
415
416
  /* Initially no thread owns the mutex.  Initialize semaphore to 1.  */
  if(!(cp->SharedIndexMutex = CreateSemaphore(0, 1, 1, 0)))
    {
    kwsysProcess_Delete(cp);
    return 0;
    }
417

418
419
420
421
422
423
424
425
426
427
428
429
430
  /* Initially no data are available.  Initialize semaphore to 0.  */
  if(!(cp->Full = CreateSemaphore(0, 0, 1, 0)))
    {
    kwsysProcess_Delete(cp);
    return 0;
    }

  if(cp->Win9x)
    {
    SECURITY_ATTRIBUTES sa;
    ZeroMemory(&sa, sizeof(sa));
    sa.nLength = sizeof(sa);
    sa.bInheritHandle = TRUE;
431
432
433
434
435
436
437
438
439
440
441

    /* Create an event to tell the forwarding executable to resume the
       child.  */
    if(!(cp->Win9xResumeEvent = CreateEvent(&sa, TRUE, 0, 0)))
      {
      kwsysProcess_Delete(cp);
      return 0;
      }

    /* Create an event to tell the forwarding executable to kill the
       child.  */
442
443
444
445
446
447
    if(!(cp->Win9xKillEvent = CreateEvent(&sa, TRUE, 0, 0)))
      {
      kwsysProcess_Delete(cp);
      return 0;
      }
    }
448

449
  /* Create the thread to read each pipe.  */
450
  for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
451
452
    {
    DWORD dummy=0;
453

454
455
    /* Assign the thread its index.  */
    cp->Pipe[i].Index = i;
456

457
458
    /* Give the thread a pointer back to the kwsysProcess instance.  */
    cp->Pipe[i].Process = cp;
459

460
461
    /* No process is yet running.  Initialize semaphore to 0.  */
    if(!(cp->Pipe[i].Reader.Ready = CreateSemaphore(0, 0, 1, 0)))
462
463
464
465
      {
      kwsysProcess_Delete(cp);
      return 0;
      }
466

467
    /* The pipe is not yet reset.  Initialize semaphore to 0.  */
468
    if(!(cp->Pipe[i].Reader.Reset = CreateSemaphore(0, 0, 1, 0)))
469
470
471
472
      {
      kwsysProcess_Delete(cp);
      return 0;
      }
473

474
    /* The thread's buffer is initially empty.  Initialize semaphore to 1.  */
475
    if(!(cp->Pipe[i].Reader.Go = CreateSemaphore(0, 1, 1, 0)))
476
477
478
479
      {
      kwsysProcess_Delete(cp);
      return 0;
      }
480

481
482
483
484
485
486
    /* Create the reading thread.  It will block immediately.  The
       thread will not make deeply nested calls, so we need only a
       small stack.  */
    if(!(cp->Pipe[i].Reader.Thread = CreateThread(0, 1024,
                                                  kwsysProcessPipeThreadRead,
                                                  &cp->Pipe[i], 0, &dummy)))
487
488
489
490
      {
      kwsysProcess_Delete(cp);
      return 0;
      }
491

492
493
    /* No process is yet running.  Initialize semaphore to 0.  */
    if(!(cp->Pipe[i].Waker.Ready = CreateSemaphore(0, 0, 1, 0)))
494
495
496
497
498
      {
      kwsysProcess_Delete(cp);
      return 0;
      }

499
500
    /* The pipe is not yet reset.  Initialize semaphore to 0.  */
    if(!(cp->Pipe[i].Waker.Reset = CreateSemaphore(0, 0, 1, 0)))
501
502
503
504
505
      {
      kwsysProcess_Delete(cp);
      return 0;
      }

506
507
    /* The waker should not wake immediately.  Initialize semaphore to 0.  */
    if(!(cp->Pipe[i].Waker.Go = CreateSemaphore(0, 0, 1, 0)))
508
509
510
511
512
513
514
515
      {
      kwsysProcess_Delete(cp);
      return 0;
      }

    /* Create the waking thread.  It will block immediately.  The
       thread will not make deeply nested calls, so we need only a
       small stack.  */
516
517
518
    if(!(cp->Pipe[i].Waker.Thread = CreateThread(0, 1024,
                                                 kwsysProcessPipeThreadWake,
                                                 &cp->Pipe[i], 0, &dummy)))
519
520
521
522
      {
      kwsysProcess_Delete(cp);
      return 0;
      }
523
    }
524

525
526
527
528
529
530
531
532
  return cp;
}

/*--------------------------------------------------------------------------*/
void kwsysProcess_Delete(kwsysProcess* cp)
{
  int i;

533
534
535
536
537
538
  /* Make sure we have an instance.  */
  if(!cp)
    {
    return;
    }

539
  /* If the process is executing, wait for it to finish.  */
540
  if(cp->State == kwsysProcess_State_Executing)
541
    {
542
543
544
545
546
547
548
549
    if(cp->Detached)
      {
      kwsysProcess_Disown(cp);
      }
    else
      {
      kwsysProcess_WaitForExit(cp, 0);
      }
550
    }
551

552
553
  /* We are deleting the kwsysProcess instance.  */
  cp->Deleting = 1;
554

555
  /* Terminate each of the threads.  */
556
  for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
557
    {
558
559
    /* Terminate this reading thread.  */
    if(cp->Pipe[i].Reader.Thread)
560
561
562
      {
      /* Signal the thread we are ready for it.  It will terminate
         immediately since Deleting is set.  */
563
      ReleaseSemaphore(cp->Pipe[i].Reader.Ready, 1, 0);
564

565
      /* Wait for the thread to exit.  */
566
      WaitForSingleObject(cp->Pipe[i].Reader.Thread, INFINITE);
567

568
      /* Close the handle to the thread. */
569
      kwsysProcessCleanupHandle(&cp->Pipe[i].Reader.Thread);
570
      }
571

572
573
    /* Terminate this waking thread.  */
    if(cp->Pipe[i].Waker.Thread)
574
575
576
      {
      /* Signal the thread we are ready for it.  It will terminate
         immediately since Deleting is set.  */
577
      ReleaseSemaphore(cp->Pipe[i].Waker.Ready, 1, 0);
578
579

      /* Wait for the thread to exit.  */
580
      WaitForSingleObject(cp->Pipe[i].Waker.Thread, INFINITE);
581
582

      /* Close the handle to the thread. */
583
      kwsysProcessCleanupHandle(&cp->Pipe[i].Waker.Thread);
584
585
      }

586
    /* Cleanup the pipe's semaphores.  */
587
588
589
590
591
592
    kwsysProcessCleanupHandle(&cp->Pipe[i].Reader.Ready);
    kwsysProcessCleanupHandle(&cp->Pipe[i].Reader.Go);
    kwsysProcessCleanupHandle(&cp->Pipe[i].Reader.Reset);
    kwsysProcessCleanupHandle(&cp->Pipe[i].Waker.Ready);
    kwsysProcessCleanupHandle(&cp->Pipe[i].Waker.Go);
    kwsysProcessCleanupHandle(&cp->Pipe[i].Waker.Reset);
593
594
    }

595
596
597
  /* Close the shared semaphores.  */
  kwsysProcessCleanupHandle(&cp->SharedIndexMutex);
  kwsysProcessCleanupHandle(&cp->Full);
598

599
  /* Close the Win9x resume and kill event handles.  */
600
601
  if(cp->Win9x)
    {
602
    kwsysProcessCleanupHandle(&cp->Win9xResumeEvent);
603
604
    kwsysProcessCleanupHandle(&cp->Win9xKillEvent);
    }
605

606
607
  /* Free memory.  */
  kwsysProcess_SetCommand(cp, 0);
608
  kwsysProcess_SetWorkingDirectory(cp, 0);
609
610
611
  kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDIN, 0);
  kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDOUT, 0);
  kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDERR, 0);
612
613
614
615
  if(cp->CommandExitCodes)
    {
    free(cp->CommandExitCodes);
    }
616
617
  if(cp->Win9x)
    {
Brad King's avatar
Brad King committed
618
    /* Close our handle to the forwarding executable file.  This will
619
620
       cause it to be deleted.  */
    kwsysProcessCleanupHandle(&cp->Win9xHandle);
621
622
623
624
625
    }
  free(cp);
}

/*--------------------------------------------------------------------------*/
626
int kwsysProcess_SetCommand(kwsysProcess* cp, char const* const* command)
627
{
628
  int i;
629
630
631
632
  if(!cp)
    {
    return 0;
    }
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
  for(i=0; i < cp->NumberOfCommands; ++i)
    {
    free(cp->Commands[i]);
    }
  cp->NumberOfCommands = 0;
  if(cp->Commands)
    {
    free(cp->Commands);
    cp->Commands = 0;
    }
  if(command)
    {
    return kwsysProcess_AddCommand(cp, command);
    }
  return 1;
}

/*--------------------------------------------------------------------------*/
int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
{
  int newNumberOfCommands;
  char** newCommands;

  /* Make sure we have a command to add.  */
657
  if(!cp || !command || !*command)
658
659
660
661
662
663
664
    {
    return 0;
    }

  /* Allocate a new array for command pointers.  */
  newNumberOfCommands = cp->NumberOfCommands + 1;
  if(!(newCommands = (char**)malloc(sizeof(char*) * newNumberOfCommands)))
665
    {
666
667
    /* Out of memory.  */
    return 0;
668
    }
669
670
671
672
673
674
675
676
677
678

  /* Copy any existing commands into the new array.  */
  {
  int i;
  for(i=0; i < cp->NumberOfCommands; ++i)
    {
    newCommands[i] = cp->Commands[i];
    }
  }

679
  /* We need to construct a single string representing the command
680
681
682
683
684
685
     and its arguments.  We will surround each argument containing
     spaces with double-quotes.  Inside a double-quoted argument, we
     need to escape double-quotes and all backslashes before them.
     We also need to escape backslashes at the end of an argument
     because they come before the closing double-quote for the
     argument.  */
686
687
  {
  /* First determine the length of the final string.  */
688
  int length = kwsysProcessComputeCommandLength(cp, command);
689

690
  /* Allocate enough space for the command.  We do not need an extra
691
692
     byte for the terminating null because we allocated a space for
     the first argument that we will not use.  */
693
694
695
696
697
698
699
  newCommands[cp->NumberOfCommands] = (char*)malloc(length);
  if(!newCommands[cp->NumberOfCommands])
    {
    /* Out of memory.  */
    free(newCommands);
    return 0;
    }
700

701
  /* Construct the command line in the allocated buffer.  */
702
703
  kwsysProcessComputeCommandLine(cp, command,
                                 newCommands[cp->NumberOfCommands]);
704
705
  }

706
707
708
709
710
  /* Save the new array of commands.  */
  free(cp->Commands);
  cp->Commands = newCommands;
  cp->NumberOfCommands = newNumberOfCommands;
  return 1;
711
712
713
714
715
}

/*--------------------------------------------------------------------------*/
void kwsysProcess_SetTimeout(kwsysProcess* cp, double timeout)
{
716
717
718
719
  if(!cp)
    {
    return;
    }
720
  cp->Timeout = timeout;
721
722
723
724
  if(cp->Timeout < 0)
    {
    cp->Timeout = 0;
    }
725
726
}

727
/*--------------------------------------------------------------------------*/
728
int kwsysProcess_SetWorkingDirectory(kwsysProcess* cp, const char* dir)
729
{
730
731
  if(!cp)
    {
732
    return 0;
733
    }
734
735
736
737
738
739
740
741
742
743
744
745
  if(cp->WorkingDirectory)
    {
    free(cp->WorkingDirectory);
    cp->WorkingDirectory = 0;
    }
  if(dir && dir[0])
    {
    /* We must convert the working directory to a full path.  */
    DWORD length = GetFullPathName(dir, 0, 0, 0);
    if(length > 0)
      {
      cp->WorkingDirectory = (char*)malloc(length);
746
747
748
749
      if(!cp->WorkingDirectory)
        {
        return 0;
        }
750
751
752
753
      if(!GetFullPathName(dir, length, cp->WorkingDirectory, 0))
        {
        free(cp->WorkingDirectory);
        cp->WorkingDirectory = 0;
754
        return 0;
755
756
757
        }
      }
    }
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
  return 1;
}

/*--------------------------------------------------------------------------*/
int kwsysProcess_SetPipeFile(kwsysProcess* cp, int pipe, const char* file)
{
  char** pfile;
  if(!cp)
    {
    return 0;
    }
  switch(pipe)
    {
    case kwsysProcess_Pipe_STDIN: pfile = &cp->PipeFileSTDIN; break;
    case kwsysProcess_Pipe_STDOUT: pfile = &cp->PipeFileSTDOUT; break;
    case kwsysProcess_Pipe_STDERR: pfile = &cp->PipeFileSTDERR; break;
    default: return 0;
    }
  if(*pfile)
    {
    free(*pfile);
    *pfile = 0;
    }
  if(file)
    {
    *pfile = malloc(strlen(file)+1);
    if(!*pfile)
      {
      return 0;
      }
    strcpy(*pfile, file);
    }
790
791
792
793
794
795
796

  /* If we are redirecting the pipe, do not share it.  */
  if(*pfile)
    {
    kwsysProcess_SetPipeShared(cp, pipe, 0);
    }

797
  return 1;
798
799
}

800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
/*--------------------------------------------------------------------------*/
void kwsysProcess_SetPipeShared(kwsysProcess* cp, int pipe, int shared)
{
  if(!cp)
    {
    return;
    }

  switch(pipe)
    {
    case kwsysProcess_Pipe_STDIN: cp->PipeSharedSTDIN = shared?1:0; break;
    case kwsysProcess_Pipe_STDOUT: cp->PipeSharedSTDOUT = shared?1:0; break;
    case kwsysProcess_Pipe_STDERR: cp->PipeSharedSTDERR = shared?1:0; break;
    default: return;
    }

  /* If we are sharing the pipe, do not redirect it to a file.  */
  if(shared)
    {
    kwsysProcess_SetPipeFile(cp, pipe, 0);
    }
}

823
824
825
/*--------------------------------------------------------------------------*/
int kwsysProcess_GetOption(kwsysProcess* cp, int optionId)
{
826
827
828
829
830
  if(!cp)
    {
    return 0;
    }

831
832
  switch(optionId)
    {
833
    case kwsysProcess_Option_Detach: return cp->OptionDetach;
834
    case kwsysProcess_Option_HideWindow: return cp->HideWindow;
835
    case kwsysProcess_Option_Verbatim: return cp->Verbatim;
836
837
    default: return 0;
    }
838
839
840
841
842
}

/*--------------------------------------------------------------------------*/
void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, int value)
{
843
844
845
846
847
  if(!cp)
    {
    return;
    }

848
849
  switch(optionId)
    {
850
    case kwsysProcess_Option_Detach: cp->OptionDetach = value; break;
851
    case kwsysProcess_Option_HideWindow: cp->HideWindow = value; break;
852
    case kwsysProcess_Option_Verbatim: cp->Verbatim = value; break;
853
854
    default: break;
    }
855
856
}

857
858
859
/*--------------------------------------------------------------------------*/
int kwsysProcess_GetState(kwsysProcess* cp)
{
860
  return cp? cp->State : kwsysProcess_State_Error;
861
862
}

863
864
865
/*--------------------------------------------------------------------------*/
int kwsysProcess_GetExitException(kwsysProcess* cp)
{
866
  return cp? cp->ExitException : kwsysProcess_Exception_Other;
867
868
869
870
871
}

/*--------------------------------------------------------------------------*/
int kwsysProcess_GetExitValue(kwsysProcess* cp)
{
872
  return cp? cp->ExitValue : -1;
873
874
}

875
876
877
/*--------------------------------------------------------------------------*/
int kwsysProcess_GetExitCode(kwsysProcess* cp)
{
878
  return cp? cp->ExitCode : 0;
879
880
881
882
883
}

/*--------------------------------------------------------------------------*/
const char* kwsysProcess_GetErrorString(kwsysProcess* cp)
{
884
885
  if(!cp)
    {
886
    return "Process management structure could not be allocated";
887
888
    }
  else if(cp->State == kwsysProcess_State_Error)
889
890
891
    {
    return cp->ErrorMessage;
    }
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
  return "Success";
}

/*--------------------------------------------------------------------------*/
const char* kwsysProcess_GetExceptionString(kwsysProcess* cp)
{
  if(!cp)
    {
    return "GetExceptionString called with NULL process management structure";
    }
  else if(cp->State == kwsysProcess_State_Exception)
    {
    return cp->ExitExceptionString;
    }
  return "No exception";
907
908
909
910
911
}

/*--------------------------------------------------------------------------*/
void kwsysProcess_Execute(kwsysProcess* cp)
{
912
  int i;
913

914
915
  /* Child startup control data.  */
  kwsysProcessCreateInformation si;
916

917
  /* Do not execute a second time.  */
918
  if(!cp || cp->State == kwsysProcess_State_Executing)
919
920
921
    {
    return;
    }
922
923
924

  /* Initialize the control structure for a new process.  */
  if(!kwsysProcessInitialize(cp))
925
    {
926
927
    strcpy(cp->ErrorMessage, "Out of memory");
    cp->State = kwsysProcess_State_Error;
928
929
    return;
    }
930

931
932
933
934
935
936
937
938
939
940
941
942
943
944
  /* Save the real working directory of this process and change to
     the working directory for the child processes.  This is needed
     to make pipe file paths evaluate correctly.  */
  if(cp->WorkingDirectory)
    {
    if(!GetCurrentDirectory(cp->RealWorkingDirectoryLength,
                            cp->RealWorkingDirectory))
      {
      kwsysProcessCleanup(cp, 1);
      return;
      }
    SetCurrentDirectory(cp->WorkingDirectory);
    }

945
  /* Reset the Win9x resume and kill events.  */
946
947
  if(cp->Win9x)
    {
948
949
950
951
952
    if(!ResetEvent(cp->Win9xResumeEvent))
      {
      kwsysProcessCleanup(cp, 1);
      return;
      }
953
954
955
956
957
958
    if(!ResetEvent(cp->Win9xKillEvent))
      {
      kwsysProcessCleanup(cp, 1);
      return;
      }
    }
959
960
961

  /* Initialize startup info data.  */
  ZeroMemory(&si, sizeof(si));
962
  si.StartupInfo.cb = sizeof(si.StartupInfo);
963

964
  /* Decide whether a child window should be shown.  */
965
966
967
  si.StartupInfo.dwFlags |= STARTF_USESHOWWINDOW;
  si.StartupInfo.wShowWindow =
    (unsigned short)(cp->HideWindow?SW_HIDE:SW_SHOWDEFAULT);
968

969
  /* Connect the child's output pipes to the threads.  */
970
  si.StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
971

972
973
974
975
  /* Create stderr pipe to be shared by all processes in the pipeline.
     Neither end is directly inherited.  */
  if(!CreatePipe(&cp->Pipe[KWSYSPE_PIPE_STDERR].Read,
                 &cp->Pipe[KWSYSPE_PIPE_STDERR].Write, 0, 0))
976
    {
977
978
979
    kwsysProcessCleanup(cp, 1);
    return;
    }
980

981
982
983
984
985
986
987
988
989
990
  /* Create an inherited duplicate of the write end, but do not
     close the non-inherited version.  We need to keep it open
     to use in waking up the pipe threads.  */
  if(!DuplicateHandle(GetCurrentProcess(), cp->Pipe[KWSYSPE_PIPE_STDERR].Write,
                      GetCurrentProcess(), &si.StartupInfo.hStdError,
                      0, TRUE, DUPLICATE_SAME_ACCESS))
    {
    kwsysProcessCleanup(cp, 1);
    kwsysProcessCleanupHandle(&si.StartupInfo.hStdError);
    return;
991
    }
992

993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
  /* Replace the stderr pipe with a file if requested.  In this case
     the pipe thread will still run but never report data.  */
  if(cp->PipeFileSTDERR)
    {
    if(!kwsysProcessSetupOutputPipeFile(&si.StartupInfo.hStdError,
                                        cp->PipeFileSTDERR))
      {
      kwsysProcessCleanup(cp, 1);
      kwsysProcessCleanupHandle(&si.StartupInfo.hStdError);
      return;
      }
    }

1006
1007
1008
1009
1010
  /* Replace the stderr pipe with the parent process's if requested.
     In this case the pipe thread will still run but never report
     data.  */
  if(cp->PipeSharedSTDERR)
    {
1011
1012
1013
1014
    if(!kwsysProcessSetupSharedPipe(STD_ERROR_HANDLE,
                                    &si.StartupInfo.hStdError))
      {
      kwsysProcessCleanup(cp, 1);
1015
1016
      kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdError,
                                    STD_ERROR_HANDLE);
1017
1018
      return;
      }
1019
1020
    }

1021
1022
1023
1024
1025
1026
  /* Create the pipeline of processes.  */
  {
  HANDLE readEnd = 0;
  for(i=0; i < cp->NumberOfCommands; ++i)
    {
    if(kwsysProcessCreate(cp, i, &si, &readEnd))
1027
      {
1028
      cp->ProcessEvents[i+1] = cp->ProcessInformation[i].hProcess;
1029
      }
1030
    else
1031
1032
      {
      kwsysProcessCleanup(cp, 1);
1033
1034
1035
1036

      /* Release resources that may have been allocated for this
         process before an error occurred.  */
      kwsysProcessCleanupHandle(&readEnd);
1037
1038
1039
1040
1041
1042
      kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdInput,
                                    STD_INPUT_HANDLE);
      kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdOutput,
                                    STD_OUTPUT_HANDLE);
      kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdError,
                                    STD_ERROR_HANDLE);
1043
1044
      kwsysProcessCleanupHandle(&si.ErrorPipeRead);
      kwsysProcessCleanupHandle(&si.ErrorPipeWrite);
1045
1046
1047
      return;
      }
    }
1048
1049

  /* Save a handle to the output pipe for the last process.  */
1050
  cp->Pipe[KWSYSPE_PIPE_STDOUT].Read = readEnd;
1051
1052
  }

1053
  /* Close the inherited handles to the stderr pipe shared by all
1054
1055
1056
     processes in the pipeline.  The stdout and stdin pipes are not
     shared among all children and are therefore closed by
     kwsysProcessCreate after each child is created.  */
1057
  kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdError, STD_ERROR_HANDLE);
1058

1059
1060
1061
1062
1063
1064
1065
1066
  /* Restore the working directory.  */
  if(cp->RealWorkingDirectory)
    {
    SetCurrentDirectory(cp->RealWorkingDirectory);
    free(cp->RealWorkingDirectory);
    cp->RealWorkingDirectory = 0;
    }

1067
1068
1069
  /* The timeout period starts now.  */
  cp->StartTime = kwsysProcessTimeGetCurrent();
  cp->TimeoutTime = kwsysProcessTimeFromDouble(-1);
1070

1071
1072
  /* All processes in the pipeline have been started in suspended
     mode.  Resume them all now.  */
1073
1074
  if(cp->Win9x)
    {
1075
    SetEvent(cp->Win9xResumeEvent);
1076
1077
1078
    }
  else
    {
1079
1080
1081
1082
    for(i=0; i < cp->NumberOfCommands; ++i)
      {
      ResumeThread(cp->ProcessInformation[i].hThread);
      }
1083
    }
1084

1085
  /* ---- It is no longer safe to call kwsysProcessCleanup. ----- */
1086
  /* Tell the pipe threads that a process has started.  */
1087
  for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
1088
    {
1089
1090
    ReleaseSemaphore(cp->Pipe[i].Reader.Ready, 1, 0);
    ReleaseSemaphore(cp->Pipe[i].Waker.Ready, 1, 0);
1091
    }
1092
1093
1094
1095
1096
1097