ProcessUNIX.c 44.8 KB
Newer Older
1
2
/*=========================================================================

Brad King's avatar
Brad King committed
3
4
  Program:   KWSys - Kitware System Library
  Module:    ProcessUNIX.c
5

Brad King's avatar
Brad King committed
6
7
  Copyright (c) Kitware, Inc., Insight Consortium.  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
8

Brad King's avatar
Brad King committed
9
10
11
     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

=========================================================================*/
#define KWSYS_IN_PROCESS_C
15
16
#include "kwsysPrivate.h"
#include KWSYS_HEADER(Process.h)
17
18
19
20

/*

Implementation for UNIX
21

22
23
24
25
26
27
28
29
30
31
32
On UNIX, a child process is forked to exec the program.  Three
output pipes from the child are read by the parent process using a
select call to block until data are ready.  Two of the pipes are
stdout and stderr for the child.  The third is a special error pipe
that has two purposes.  First, if the child cannot exec the program,
the error is reported through the error pipe.  Second, the error
pipe is left open until the child exits.  This is used in
conjunction with the timeout on the select call to implement a
timeout for program even when it closes stdout and stderr.
*/

33
34
35
36
37
38
39
40
41
42
43
/*

TODO:

We cannot create the pipeline of processes in suspended states.  How
do we cleanup processes already started when one fails to load?  Right
now we are just killing them, which is probably not the right thing to
do.

*/

44
45
46
47
48
49
#include <stdio.h>     /* snprintf */
#include <stdlib.h>    /* malloc, free */
#include <string.h>    /* strdup, strerror, memset */
#include <sys/time.h>  /* struct timeval */
#include <sys/types.h> /* pid_t, fd_set */
#include <sys/wait.h>  /* waitpid */
50
#include <sys/stat.h>  /* open mode */
51
52
53
54
55
56
57
#include <unistd.h>    /* pipe, close, fork, execvp, select, _exit */
#include <fcntl.h>     /* fcntl */
#include <errno.h>     /* errno */
#include <time.h>      /* gettimeofday */
#include <signal.h>    /* sigaction */

/* The number of pipes for the child's output.  The standard stdout
58
59
60
61
   and stderr pipes are the first two.  One more pipe is used to
   detect when the child process has terminated.  The third pipe is
   not given to the child process, so it cannot close it until it
   terminates.  */
62
63
64
#define KWSYSPE_PIPE_COUNT 3
#define KWSYSPE_PIPE_STDOUT 0
#define KWSYSPE_PIPE_STDERR 1
65
#define KWSYSPE_PIPE_TERM 2
66
67
68
69
70
71

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

typedef struct timeval kwsysProcessTime;

72
73
typedef struct kwsysProcessCreateInformation_s
{
74
75
76
77
78
  int StdIn;
  int StdOut;
  int StdErr;
  int TermPipe;
  int ErrorPipe[2];
79
80
} kwsysProcessCreateInformation;

81
/*--------------------------------------------------------------------------*/
82
static int kwsysProcessInitialize(kwsysProcess* cp);
83
84
static void kwsysProcessCleanup(kwsysProcess* cp, int error);
static void kwsysProcessCleanupDescriptor(int* pfd);
85
86
static int kwsysProcessCreate(kwsysProcess* cp, int index,
                              kwsysProcessCreateInformation* si, int* readEnd);
87
static int kwsysProcessSetupOutputPipeFile(int* p, const char* name);
88
89
90
91
static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
                                      kwsysProcessTime* timeoutTime);
static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime,
                                      kwsysProcessTime* timeoutLength);
92
static kwsysProcessTime kwsysProcessTimeGetCurrent(void);
93
94
95
96
97
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);
98
static void kwsysProcessSetExitException(kwsysProcess* cp, int sig);
99
static void kwsysProcessChildErrorExit(int errorPipe);
100
static void kwsysProcessRestoreDefaultSignalHandlers(void);
101
102
103
104
105

/*--------------------------------------------------------------------------*/
/* Structure containing data used to implement the child's execution.  */
struct kwsysProcess_s
{
106
107
108
  /* The command lines to execute.  */
  char*** Commands;
  int NumberOfCommands;
109
110
111

  /* Descriptors for the read ends of the child's output pipes. */
  int PipeReadEnds[KWSYSPE_PIPE_COUNT];
112

113
114
115
  /* Buffer for pipe data.  */
  char PipeBuffer[KWSYSPE_PIPE_BUFFER_SIZE];

116
117
  /* Process IDs returned by the calls to fork.  */
  pid_t* ForkPIDs;
118

119
120
  /* Flag for whether the children were terminated by a faild select.  */
  int SelectError;
121

122
  /* The timeout length.  */
123
  double Timeout;
124
125
126

  /* The working directory for the process. */
  char* WorkingDirectory;
127

128
129
  /* Time at which the child started.  Negative for no timeout.  */
  kwsysProcessTime StartTime;
130

131
132
  /* Time at which the child will timeout.  Negative for no timeout.  */
  kwsysProcessTime TimeoutTime;
133

134
135
  /* Flag for whether the timeout expired.  */
  int TimeoutExpired;
136

137
138
  /* The old SIGCHLD handler.  */
  struct sigaction OldSigChldAction;
139

140
141
  /* The number of pipes left open during execution.  */
  int PipesLeft;
142

143
144
145
146
147
  /* File descriptor set for call to select.  */
  fd_set PipeSet;

  /* The current status of the child process. */
  int State;
148

149
150
151
  /* The exceptional behavior that terminated the child process, if
   * any.  */
  int ExitException;
152

153
  /* The exit code of the child process.  */
154
  int ExitCode;
155

156
157
  /* The exit value of the child process, if any.  */
  int ExitValue;
158

159
160
  /* Whether the process was killed.  */
  int Killed;
161

162
163
  /* Buffer for error message in case of failure.  */
  char ErrorMessage[KWSYSPE_PIPE_BUFFER_SIZE+1];
164

165
166
167
  /* Description for the ExitException.  */
  char ExitExceptionString[KWSYSPE_PIPE_BUFFER_SIZE+1];

168
169
  /* The exit codes of each child process in the pipeline.  */
  int* CommandExitCodes;
170
171
172
173
174
175

  /* Name of files to which stdin and stdout pipes are attached.  */
  char* PipeFileSTDIN;
  char* PipeFileSTDOUT;
  char* PipeFileSTDERR;

176
177
178
179
180
  /* Whether each pipe is shared with the parent process.  */
  int PipeSharedSTDIN;
  int PipeSharedSTDOUT;
  int PipeSharedSTDERR;

181
182
183
  /* The real working directory of this process.  */
  int RealWorkingDirectoryLength;
  char* RealWorkingDirectory;
184
185
186
};

/*--------------------------------------------------------------------------*/
187
kwsysProcess* kwsysProcess_New(void)
188
189
190
191
192
193
194
195
{
  /* Allocate a process control structure.  */
  kwsysProcess* cp = (kwsysProcess*)malloc(sizeof(kwsysProcess));
  if(!cp)
    {
    return 0;
    }
  memset(cp, 0, sizeof(kwsysProcess));
196
197
198
199
200

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

  /* Set initial status.  */
201
  cp->State = kwsysProcess_State_Starting;
202

203
204
205
206
207
208
  return cp;
}

/*--------------------------------------------------------------------------*/
void kwsysProcess_Delete(kwsysProcess* cp)
{
209
210
211
212
213
214
  /* Make sure we have an instance.  */
  if(!cp)
    {
    return;
    }

215
  /* If the process is executing, wait for it to finish.  */
216
  if(cp->State == kwsysProcess_State_Executing)
217
218
219
    {
    kwsysProcess_WaitForExit(cp, 0);
    }
220

221
222
  /* Free memory.  */
  kwsysProcess_SetCommand(cp, 0);
223
  kwsysProcess_SetWorkingDirectory(cp, 0);
224
225
226
  kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDIN, 0);
  kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDOUT, 0);
  kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDERR, 0);
227
228
229
230
  if(cp->CommandExitCodes)
    {
    free(cp->CommandExitCodes);
    }
231
232
233
234
  free(cp);
}

/*--------------------------------------------------------------------------*/
235
int kwsysProcess_SetCommand(kwsysProcess* cp, char const* const* command)
236
{
237
  int i;
238
239
240
241
  if(!cp)
    {
    return 0;
    }
242
  for(i=0; i < cp->NumberOfCommands; ++i)
243
    {
244
    char** c = cp->Commands[i];
245
246
247
248
    while(*c)
      {
      free(*c++);
      }
249
250
251
252
253
254
255
    free(cp->Commands[i]);
    }
  cp->NumberOfCommands = 0;
  if(cp->Commands)
    {
    free(cp->Commands);
    cp->Commands = 0;
256
257
258
    }
  if(command)
    {
259
260
261
262
263
264
265
266
267
268
269
270
    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.  */
271
  if(!cp || !command)
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
    {
    return 0;
    }

  /* Allocate a new array for command pointers.  */
  newNumberOfCommands = cp->NumberOfCommands + 1;
  if(!(newCommands = (char***)malloc(sizeof(char**) * newNumberOfCommands)))
    {
    /* Out of memory.  */
    return 0;
    }

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

  /* Add the new command.  */
  {
  char const* const* c = command;
  int n = 0;
  int i = 0;
  while(*c++);
  n = c - command - 1;
  newCommands[cp->NumberOfCommands] = (char**)malloc((n+1)*sizeof(char*));
  if(!newCommands[cp->NumberOfCommands])
    {
    /* Out of memory.  */
    free(newCommands);
    return 0;
    }
  for(i=0; i < n; ++i)
    {
    newCommands[cp->NumberOfCommands][i] = strdup(command[i]);
    if(!newCommands[cp->NumberOfCommands][i])
311
      {
312
      break;
313
      }
314
    }
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
  if(i < n)
    {
    /* Out of memory.  */
    for(;i > 0; --i)
      {
      free(newCommands[cp->NumberOfCommands][i-1]);
      }
    free(newCommands);
    return 0;
    }
  newCommands[cp->NumberOfCommands][n] = 0;
  }

  /* Successfully allocated new command array.  Free the old array. */
  free(cp->Commands);
  cp->Commands = newCommands;
  cp->NumberOfCommands = newNumberOfCommands;

  return 1;
334
335
336
337
338
}

/*--------------------------------------------------------------------------*/
void kwsysProcess_SetTimeout(kwsysProcess* cp, double timeout)
{
339
340
341
342
  if(!cp)
    {
    return;
    }
343
344
345
346
347
348
349
350
  cp->Timeout = timeout;
  if(cp->Timeout < 0)
    {
    cp->Timeout = 0;
    }
}

/*--------------------------------------------------------------------------*/
351
int kwsysProcess_SetWorkingDirectory(kwsysProcess* cp, const char* dir)
352
{
353
354
  if(!cp)
    {
355
    return 0;
356
    }
357
358
  if(cp->WorkingDirectory == dir)
    {
359
    return 1;
360
361
362
    }
  if(cp->WorkingDirectory && dir && strcmp(cp->WorkingDirectory, dir) == 0)
    {
363
    return 1;
364
365
366
367
368
369
370
371
    }
  if(cp->WorkingDirectory)
    {
    free(cp->WorkingDirectory);
    cp->WorkingDirectory = 0;
    }
  if(dir)
    {
372
    cp->WorkingDirectory = (char*)malloc(strlen(dir) + 1);
373
374
375
376
    if(!cp->WorkingDirectory)
      {
      return 0;
      }
377
378
    strcpy(cp->WorkingDirectory, dir);
    }
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
  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);
    }
411
412
413
414
415
416

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

420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
/*--------------------------------------------------------------------------*/
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);
    }
}

443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
/*--------------------------------------------------------------------------*/
int kwsysProcess_GetOption(kwsysProcess* cp, int optionId)
{
  (void)cp;
  (void)optionId;
  return 0;
}

/*--------------------------------------------------------------------------*/
void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, int value)
{
  (void)cp;
  (void)optionId;
  (void)value;
}

459
/*--------------------------------------------------------------------------*/
460
461
int kwsysProcess_GetState(kwsysProcess* cp)
{
462
  return cp? cp->State : kwsysProcess_State_Error;
463
464
}

465
466
467
/*--------------------------------------------------------------------------*/
int kwsysProcess_GetExitException(kwsysProcess* cp)
{
468
  return cp? cp->ExitException : kwsysProcess_Exception_Other;
469
470
}

471
472
473
/*--------------------------------------------------------------------------*/
int kwsysProcess_GetExitCode(kwsysProcess* cp)
{
474
  return cp? cp->ExitCode : 0;
475
476
}

477
478
479
/*--------------------------------------------------------------------------*/
int kwsysProcess_GetExitValue(kwsysProcess* cp)
{
480
  return cp? cp->ExitValue : -1;
481
482
}

483
484
485
/*--------------------------------------------------------------------------*/
const char* kwsysProcess_GetErrorString(kwsysProcess* cp)
{
486
487
  if(!cp)
    {
488
    return "Process management structure could not be allocated";
489
490
    }
  else if(cp->State == kwsysProcess_State_Error)
491
    {
492
    return cp->ErrorMessage;
493
    }
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
  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";
509
510
511
512
513
514
515
}

/*--------------------------------------------------------------------------*/
void kwsysProcess_Execute(kwsysProcess* cp)
{
  int i;
  struct sigaction newSigChldAction;
516
  kwsysProcessCreateInformation si = {-1, -1, -1, -1, {-1, -1}};
517

518
  /* Do not execute a second copy simultaneously.  */
519
  if(!cp || cp->State == kwsysProcess_State_Executing)
520
521
522
    {
    return;
    }
523

524
  /* Initialize the control structure for a new process.  */
525
526
527
528
529
530
  if(!kwsysProcessInitialize(cp))
    {
    strcpy(cp->ErrorMessage, "Out of memory");
    cp->State = kwsysProcess_State_Error;
    return;
    }
531

532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
  /* 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)
    {
    int r;
    if(!getcwd(cp->RealWorkingDirectory, cp->RealWorkingDirectoryLength))
      {
      kwsysProcessCleanup(cp, 1);
      return;
      }

    /* Some platforms specify that the chdir call may be
       interrupted.  Repeat the call until it finishes.  */
    while(((r = chdir(cp->WorkingDirectory)) < 0) && (errno == EINTR));
    if(r < 0)
      {
      kwsysProcessCleanup(cp, 1);
550
      return;
551
552
553
      }
    }

554
555
  /* We want no special handling of SIGCHLD.  Repeat call until it is
     not interrupted.  */
556
  memset(&newSigChldAction, 0, sizeof(struct sigaction));
557
558
559
  newSigChldAction.sa_handler = SIG_DFL;
  while((sigaction(SIGCHLD, &newSigChldAction, &cp->OldSigChldAction) < 0) &&
        (errno == EINTR));
560

561
562
  /* Setup the stderr and termination pipes to be shared by all processes.  */
  for(i=KWSYSPE_PIPE_STDERR; i < KWSYSPE_PIPE_COUNT; ++i)
563
564
    {
    /* Create the pipe.  */
565
    int p[2];
566
567
568
569
570
    if(pipe(p) < 0)
      {
      kwsysProcessCleanup(cp, 1);
      return;
      }
571

572
573
574
575
    /* Store the pipe.  */
    cp->PipeReadEnds[i] = p[0];
    if(i == KWSYSPE_PIPE_STDERR)
      {
576
      si.StdErr = p[1];
577
578
579
      }
    else
      {
580
      si.TermPipe = p[1];
581
582
      }

583
584
585
586
587
    /* Set close-on-exec flag on the pipe's ends.  */
    if((fcntl(p[0], F_SETFD, FD_CLOEXEC) < 0) ||
       (fcntl(p[1], F_SETFD, FD_CLOEXEC) < 0))
      {
      kwsysProcessCleanup(cp, 1);
588
589
      kwsysProcessCleanupDescriptor(&si.StdErr);
      kwsysProcessCleanupDescriptor(&si.TermPipe);
590
591
592
      return;
      }
    }
593

594
595
596
597
598
599
600
601
602
603
604
605
606
  /* Replace the stderr pipe with a file if requested.  In this case
     the select call will report that stderr is closed immediately.  */
  if(cp->PipeFileSTDERR)
    {
    if(!kwsysProcessSetupOutputPipeFile(&si.StdErr, cp->PipeFileSTDERR))
      {
      kwsysProcessCleanup(cp, 1);
      kwsysProcessCleanupDescriptor(&si.StdErr);
      kwsysProcessCleanupDescriptor(&si.TermPipe);
      return;
      }
    }

607
608
609
610
611
612
613
614
  /* Replace the stderr pipe with the parent's if requested.  In this
     case the select call will report that stderr is closed
     immediately.  */
  if(cp->PipeSharedSTDERR)
    {
    kwsysProcessCleanupDescriptor(&si.StdErr);
    si.StdErr = 2;
    }
615

616
617
618
619
  /* The timeout period starts now.  */
  cp->StartTime = kwsysProcessTimeGetCurrent();
  cp->TimeoutTime.tv_sec = -1;
  cp->TimeoutTime.tv_usec = -1;
620

621
622
  /* Create the pipeline of processes.  */
  {
623
  int readEnd = -1;
624
  for(i=0; i < cp->NumberOfCommands; ++i)
625
    {
626
    if(!kwsysProcessCreate(cp, i, &si, &readEnd))
627
      {
628
629
630
631
      kwsysProcessCleanup(cp, 1);

      /* Release resources that may have been allocated for this
         process before an error occurred.  */
632
633
      kwsysProcessCleanupDescriptor(&readEnd);
      if(si.StdIn != 0)
634
        {
635
        kwsysProcessCleanupDescriptor(&si.StdIn);
636
        }
637
638
639
640
641
642
643
644
      if(si.StdOut != 1)
        {
        kwsysProcessCleanupDescriptor(&si.StdOut);
        }
      if(si.StdErr != 2)
        {
        kwsysProcessCleanupDescriptor(&si.StdErr);
        }
645
646
647
      kwsysProcessCleanupDescriptor(&si.TermPipe);
      kwsysProcessCleanupDescriptor(&si.ErrorPipe[0]);
      kwsysProcessCleanupDescriptor(&si.ErrorPipe[1]);
648
      return;
649
      }
650
    }
651
652
653
  /* Save a handle to the output pipe for the last process.  */
  cp->PipeReadEnds[KWSYSPE_PIPE_STDOUT] = readEnd;
  }
654

655
  /* The parent process does not need the output pipe write ends.  */
656
657
  kwsysProcessCleanupDescriptor(&si.StdErr);
  kwsysProcessCleanupDescriptor(&si.TermPipe);
658

659
660
661
662
663
664
665
666
667
668
  /* Restore the working directory. */
  if(cp->RealWorkingDirectory)
    {
    /* Some platforms specify that the chdir call may be
       interrupted.  Repeat the call until it finishes.  */
    while((chdir(cp->RealWorkingDirectory) < 0) && (errno == EINTR));
    free(cp->RealWorkingDirectory);
    cp->RealWorkingDirectory = 0;
    }

669
670
  /* All the pipes are now open.  */
  cp->PipesLeft = KWSYSPE_PIPE_COUNT;
671

672
  /* The process has now started.  */
673
  cp->State = kwsysProcess_State_Executing;
674
675
676
}

/*--------------------------------------------------------------------------*/
677
678
int kwsysProcess_WaitForData(kwsysProcess* cp, char** data, int* length,
                             double* userTimeout)
679
680
681
682
683
684
685
686
687
{
  int i;
  int max = -1;
  kwsysProcessTime* timeout = 0;
  kwsysProcessTime timeoutLength;
  kwsysProcessTime timeoutTime;
  kwsysProcessTime userStartTime;
  int user = 0;
  int expired = 0;
Brad King's avatar
Brad King committed
688
  int pipeId = kwsysProcess_Pipe_None;
689
  int numReady = 0;
690

691
692
693
694
695
696
697
  /* Make sure we are executing a process.  */
  if(!cp || cp->State != kwsysProcess_State_Executing || cp->Killed ||
     cp->TimeoutExpired)
    {
    return kwsysProcess_Pipe_None;
    }

698
699
700
701
702
  /* Record the time at which user timeout period starts.  */
  if(userTimeout)
    {
    userStartTime = kwsysProcessTimeGetCurrent();
    }
703

704
705
706
  /* Calculate the time at which a timeout will expire, and whether it
     is the user or process timeout.  */
  user = kwsysProcessGetTimeoutTime(cp, userTimeout, &timeoutTime);
707

708
709
710
711
712
713
714
715
716
717
718
719
  /* Data can only be available when pipes are open.  If the process
     is not running, cp->PipesLeft will be 0.  */
  while(cp->PipesLeft > 0)
    {
    /* Check for any open pipes with data reported ready by the last
       call to select.  */
    for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
      {
      if(cp->PipeReadEnds[i] >= 0 &&
         FD_ISSET(cp->PipeReadEnds[i], &cp->PipeSet))
        {
        int n;
720

721
722
        /* We are handling this pipe now.  Remove it from the set.  */
        FD_CLR(cp->PipeReadEnds[i], &cp->PipeSet);
723

724
725
726
727
728
729
730
        /* The pipe is ready to read without blocking.  Keep trying to
           read until the operation is not interrupted.  */
        while(((n = read(cp->PipeReadEnds[i], cp->PipeBuffer,
                         KWSYSPE_PIPE_BUFFER_SIZE)) < 0) && (errno == EINTR));
        if(n > 0)
          {
          /* We have data on this pipe.  */
731
          if(i == KWSYSPE_PIPE_TERM)
732
            {
733
            /* This is data on the special termination pipe.  Ignore it.  */
734
            }
735
          else if(data && length)
736
            {
737
            /* Report this data.  */
738
739
            *data = cp->PipeBuffer;
            *length = n;
Brad King's avatar
Brad King committed
740
741
742
743
744
745
746
            switch(i)
              {
              case KWSYSPE_PIPE_STDOUT:
                pipeId = kwsysProcess_Pipe_STDOUT; break;
              case KWSYSPE_PIPE_STDERR:
                pipeId = kwsysProcess_Pipe_STDERR; break;
              };
747
748
749
750
751
752
753
754
755
756
757
            break;
            }
          }
        else
          {
          /* We are done reading from this pipe.  */
          kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]);
          --cp->PipesLeft;
          }
        }
      }
758

759
760
761
762
763
    /* If we have data, break early.  */
    if(pipeId)
      {
      break;
      }
764

765
766
767
    /* Make sure the set is empty (it should always be empty here
       anyway).  */
    FD_ZERO(&cp->PipeSet);
768

769
770
771
772
773
774
775
776
777
778
779
780
781
    /* Add the pipe reading ends that are still open.  */
    max = -1;
    for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
      {
      if(cp->PipeReadEnds[i] >= 0)
        {
        FD_SET(cp->PipeReadEnds[i], &cp->PipeSet);
        if(cp->PipeReadEnds[i] > max)
          {
          max = cp->PipeReadEnds[i];
          }
        }
      }
782

783
784
785
786
787
788
    /* Make sure we have a non-empty set.  */
    if(max < 0)
      {
      /* All pipes have closed.  Child has terminated.  */
      break;
      }
789

790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
    /* Setup a timeout if required.  */
    if(timeoutTime.tv_sec < 0)
      {
      timeout = 0;
      }
    else
      {
      timeout = &timeoutLength;
      }
    if(kwsysProcessGetTimeoutLeft(&timeoutTime, &timeoutLength))
      {
      /* Timeout has already expired.  */
      expired = 1;
      break;
      }
805

806
807
808
809
    /* Run select to block until data are available.  Repeat call
       until it is not interrupted.  */
    while(((numReady = select(max+1, &cp->PipeSet, 0, 0, timeout)) < 0) &&
          (errno == EINTR));
810

811
812
813
814
815
816
817
818
819
820
821
    /* Check result of select.  */
    if(numReady == 0)
      {
      /* Select's timeout expired.  */
      expired = 1;
      break;
      }
    else if(numReady < 0)
      {
      /* Select returned an error.  Leave the error description in the
         pipe buffer.  */
822
      strncpy(cp->ErrorMessage, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE);
823

824
      /* Kill the children now.  */
825
826
      kwsysProcess_Kill(cp);
      cp->Killed = 0;
827
      cp->SelectError = 1;
828
829
830
      cp->PipesLeft = 0;
      }
    }
831

832
833
834
835
836
837
838
839
840
841
842
843
844
  /* Update the user timeout.  */
  if(userTimeout)
    {
    kwsysProcessTime userEndTime = kwsysProcessTimeGetCurrent();
    kwsysProcessTime difference = kwsysProcessTimeSubtract(userEndTime,
                                                     userStartTime);
    double d = kwsysProcessTimeToDouble(difference);
    *userTimeout -= d;
    if(*userTimeout < 0)
      {
      *userTimeout = 0;
      }
    }
845

846
847
848
849
850
851
852
853
854
855
856
857
  /* Check what happened.  */
  if(pipeId)
    {
    /* Data are ready on a pipe.  */
    return pipeId;
    }
  else if(expired)
    {
    /* A timeout has expired.  */
    if(user)
      {
      /* The user timeout has expired.  It has no time left.  */
858
      return kwsysProcess_Pipe_Timeout;
859
860
861
      }
    else
      {
862
      /* The process timeout has expired.  Kill the children now.  */
863
864
865
866
      kwsysProcess_Kill(cp);
      cp->Killed = 0;
      cp->TimeoutExpired = 1;
      cp->PipesLeft = 0;
Brad King's avatar
Brad King committed
867
      return kwsysProcess_Pipe_None;
868
869
870
871
872
      }
    }
  else
    {
    /* No pipes are left open.  */
Brad King's avatar
Brad King committed
873
    return kwsysProcess_Pipe_None;
874
875
876
877
878
879
880
881
882
    }
}

/*--------------------------------------------------------------------------*/
int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
{
  int result = 0;
  int status = 0;
  int pipe = 0;
883

884
  /* Make sure we are executing a process.  */
885
  if(!cp || cp->State != kwsysProcess_State_Executing)
886
887
888
    {
    return 1;
    }
889

890
  /* Wait for all the pipes to close.  Ignore all data.  */
891
  while((pipe = kwsysProcess_WaitForData(cp, 0, 0, userTimeout)) > 0)
892
    {
893
    if(pipe == kwsysProcess_Pipe_Timeout)
894
895
896
897
898
      {
      return 0;
      }
    }

899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
  /* Wait for each child to terminate.  The process should have
     already exited because KWSYSPE_PIPE_TERM has been closed by this
     point.  Repeat the call until it is not interrupted.  */
  {
  int i;
  for(i=0; i < cp->NumberOfCommands; ++i)
    {
    while(((result = waitpid(cp->ForkPIDs[i],
                             &cp->CommandExitCodes[i], 0)) < 0) &&
          (errno == EINTR));
    if(result <= 0 && cp->State != kwsysProcess_State_Error)
      {
      /* Unexpected error.  Report the first time this happens.  */
      strncpy(cp->ErrorMessage, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE);
      cp->State = kwsysProcess_State_Error;
      }
    }
  }

  /* Check if there was an error in one of the waitpid calls.  */
  if(cp->State == kwsysProcess_State_Error)
920
    {
921
922
923
    /* The error message is already in its buffer.  Tell
       kwsysProcessCleanup to not create it.  */
    kwsysProcessCleanup(cp, 0);
924
925
    return 1;
    }
926

927
  /* Check whether the child reported an error invoking the process.  */
928
  if(cp->SelectError)
929
930
931
932
    {
    /* The error message is already in its buffer.  Tell
       kwsysProcessCleanup to not create it.  */
    kwsysProcessCleanup(cp, 0);
933
    cp->State = kwsysProcess_State_Error;
934
935
    return 1;
    }
936

937
938
939
  /* Use the status of the last process in the pipeline.  */
  status = cp->CommandExitCodes[cp->NumberOfCommands-1];

940
941
942
943
  /* Determine the outcome.  */
  if(cp->Killed)
    {
    /* We killed the child.  */
944
    cp->State = kwsysProcess_State_Killed;
945
946
947
948
    }
  else if(cp->TimeoutExpired)
    {
    /* The timeout expired.  */
949
    cp->State = kwsysProcess_State_Expired;
950
951
952
    }
  else if(WIFEXITED(status))
    {
953
954
955
956
957
    /* The child exited normally.  */
    cp->State = kwsysProcess_State_Exited;
    cp->ExitException = kwsysProcess_Exception_None;
    cp->ExitCode = status;
    cp->ExitValue = (int)WEXITSTATUS(status);
958
959
960
961
    }
  else if(WIFSIGNALED(status))
    {
    /* The child received an unhandled signal.  */
962
963
    cp->State = kwsysProcess_State_Exception;
    cp->ExitCode = status;
964
    kwsysProcessSetExitException(cp, (int)WTERMSIG(status));
965
966
967
968
969
    }
  else
    {
    /* Error getting the child return code.  */
    strcpy(cp->ErrorMessage, "Error getting child return code.");
970
    cp->State = kwsysProcess_State_Error;
971
    }
972

973
974
975
976
977
978
979
  /* Normal cleanup.  */
  kwsysProcessCleanup(cp, 0);
  return 1;
}

/*--------------------------------------------------------------------------*/
void kwsysProcess_Kill(kwsysProcess* cp)
980
{
981
982
  int i;

983
  /* Make sure we are executing a process.  */
984
  if(!cp || cp->State != kwsysProcess_State_Executing)
985
986
987
    {
    return;
    }
988

989
  /* Kill the children.  */
990
  cp->Killed = 1;
991
992
993
994
995
996
997
  for(i=0; i < cp->NumberOfCommands; ++i)
    {
    if(cp->ForkPIDs[i])
      {
      kill(cp->ForkPIDs[i], SIGKILL);
      }
    }
998
999
1000
1001
}

/*--------------------------------------------------------------------------*/
/* Initialize a process control structure for kwsysProcess_Execute.  */
1002
static int kwsysProcessInitialize(kwsysProcess* cp)
1003
1004
1005
1006
1007
1008
{
  int i;
  for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
    {
    cp->PipeReadEnds[i] = -1;
    }
1009
  cp->SelectError = 0;
1010
1011
1012
1013
1014
1015
1016
  cp->StartTime.tv_sec = -1;
  cp->StartTime.tv_usec = -1;
  cp->TimeoutTime.tv_sec = -1;
  cp->TimeoutTime.tv_usec = -1;
  cp->TimeoutExpired = 0;
  cp->PipesLeft = 0;
  FD_ZERO(&cp->PipeSet);
1017
  cp->State = kwsysProcess_State_Starting;
1018
  cp->Killed = 0;
1019
1020
1021
  cp->ExitException = kwsysProcess_Exception_None;
  cp->ExitCode = 1;
  cp->ExitValue = 1;
1022
  cp->ErrorMessage[0] = 0;
1023
  strcpy(cp->ExitExceptionString, "No exception");
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046

  if(cp->ForkPIDs)
    {
    free(cp->ForkPIDs);
    }
  cp->ForkPIDs = (pid_t*)malloc(sizeof(pid_t)*cp->NumberOfCommands);
  if(!cp->ForkPIDs)
    {
    return 0;
    }
  memset(cp->ForkPIDs, 0, sizeof(pid_t)*cp->NumberOfCommands);

  if(cp->CommandExitCodes)
    {
    free(cp->CommandExitCodes);
    }
  cp->CommandExitCodes = (int*)malloc(sizeof(int)*cp->NumberOfCommands);
  if(!cp->CommandExitCodes)
    {
    return 0;
    }
  memset(cp->CommandExitCodes, 0, sizeof(int)*cp->NumberOfCommands);

1047
  /* Allocate memory to save the real working directory.  */
1048
1049
  if ( cp->WorkingDirectory )
    {
1050
#if defined(MAXPATHLEN)
1051
    cp->RealWorkingDirectoryLength = MAXPATHLEN;
1052
#elif defined(PATH_MAX)
1053
    cp->RealWorkingDirectoryLength = PATH_MAX;
1054
#else
1055
    cp->RealWorkingDirectoryLength = 4096;
1056
#endif
1057
1058
1059
1060
1061
    cp->RealWorkingDirectory = malloc(cp->RealWorkingDirectoryLength);
    if(!cp->RealWorkingDirectory)
      {
      return 0;
      }
1062
1063
    }

1064
  return 1;
1065
1066
1067
1068
1069
}

/*--------------------------------------------------------------------------*/
/* Free all resources used by the given kwsysProcess instance that were
   allocated by kwsysProcess_Execute.  */
1070
static void kwsysProcessCleanup(kwsysProcess* cp, int error)
1071
1072
{
  int i;
1073

1074
1075
  if(error)
    {
1076
1077
1078
1079
1080
1081
1082
1083
    /* We are cleaning up due to an error.  Report the error message
       if one has not been provided already.  */
    if(cp->ErrorMessage[0] == 0)
      {
      strncpy(cp->ErrorMessage, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE);
      }

    /* Set the error state.  */
1084
    cp->State = kwsysProcess_State_Error;
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096

    /* Kill any children already started.  */
    if(cp->ForkPIDs)
      {
      for(i=0; i < cp->NumberOfCommands; ++i)
        {
        if(cp->ForkPIDs[i])
          {
          kill(cp->ForkPIDs[i], SIGKILL);
          }
        }
      }
1097
1098
1099
1100
1101
1102

    /* Restore the working directory.  */
    if(cp->RealWorkingDirectory)
      {
      while((chdir(cp->RealWorkingDirectory) < 0) && (errno == EINTR));
      }
1103
    }
1104

1105
1106
1107
  /* Restore the SIGCHLD handler.  */
  while((sigaction(SIGCHLD, &cp->OldSigChldAction, 0) < 0) &&
        (errno == EINTR));
1108

1109
1110
1111
1112
1113
1114
  /* Free memory.  */
  if(cp->ForkPIDs)
    {
    free(cp->ForkPIDs);
    cp->ForkPIDs = 0;
    }
1115
1116
1117
1118
1119
  if(cp->RealWorkingDirectory)
    {
    free(cp->RealWorkingDirectory);
    cp->RealWorkingDirectory = 0;
    }
1120

1121
1122
1123
1124
1125
1126
1127
1128
1129
  /* Close pipe handles.  */
  for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
    {
    kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]);
    }
}

/*--------------------------------------------------------------------------*/
/* Close the given file descriptor if it is open.  Reset its value to -1.  */
1130
static void kwsysProcessCleanupDescriptor(int* pfd)
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
{
  if(pfd && *pfd >= 0)
    {
    /* Keep trying to close until it is not interrupted by a
     * signal.  */
    while((close(*pfd) < 0) && (errno == EINTR));
    *pfd = -1;
    }
}

1141
/*--------------------------------------------------------------------------*/
1142
1143
static int kwsysProcessCreate(kwsysProcess* cp, int index,
                              kwsysProcessCreateInformation* si, int* readEnd)
1144
1145
1146
1147
{
  /* Setup the process's stdin.  */
  if(index > 0)
    {
1148
    si->StdIn = *readEnd;
1149
1150
    *readEnd = 0;
    }
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
  else if(cp->PipeFileSTDIN)
    {
    /* Open a file for the child's stdin to read.  */
    si->StdIn = open(cp->PipeFileSTDIN, O_RDONLY);
    if(si->StdIn < 0)
      {
      return 0;
      }

    /* Set close-on-exec flag on the pipe's end.  */
    if(fcntl(si->StdIn, F_SETFD, FD_CLOEXEC) < 0)
      {
      return 0;
      }
    }
1166
  else if(cp->PipeSharedSTDIN)
1167
    {
1168
    si->StdIn = 0;
1169
    }
1170
1171
1172
1173
  else
    {
    si->StdIn = -1;
    }
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183

  /* Setup the process's stdout.  */
  {
  /* Create the pipe.  */
  int p[2];
  if(pipe(p) < 0)
    {
    return 0;
    }
  *readEnd = p[0];
1184
  si->StdOut = p[1];
1185
1186
1187
1188
1189
1190
1191
1192
1193

  /* Set close-on-exec flag on the pipe's ends.  */
  if((fcntl(p[0], F_SETFD, FD_CLOEXEC) < 0) ||
     (fcntl(p[1], F_SETFD, FD_CLOEXEC) < 0))
    {
    return 0;
    }
  }

1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
  /* Replace the stdout pipe with a file if requested.  In this case
     the select call will report that stdout is closed immediately.  */
  if(index == cp->NumberOfCommands-1 && cp->PipeFileSTDOUT)
    {
    if(!kwsysProcessSetupOutputPipeFile(&si->StdOut, cp->PipeFileSTDOUT))
      {
      return 0;
      }
    }

1204
1205
1206
1207
1208
1209
1210
1211
1212
  /* Replace the stdout pipe with the parent's if requested.  In this
     case the select call will report that stderr is closed
     immediately.  */
  if(index == cp->NumberOfCommands-1 && cp->PipeSharedSTDOUT)
    {
    kwsysProcessCleanupDescriptor(&si->StdOut);
    si->StdOut = 1;
    }

1213
  /* Create the error reporting pipe.  */
1214
  if(pipe(si->ErrorPipe) < 0)
1215
1216
1217
1218
1219
    {
    return 0;
    }

  /* Set close-on-exec flag on the error pipe's write end.  */
1220
  if(fcntl(si->ErrorPipe[1], F_SETFD, FD_CLOEXEC) < 0)
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
    {
    return 0;
    }

  /* Fork off a child process.  */
  cp->ForkPIDs[index] = fork();
  if(cp->ForkPIDs[index] < 0)
    {
    return 0;
    }

  if(cp->ForkPIDs[index] == 0)
    {
    /* Close the read end of the error reporting pipe.  */
1235
    close(si->ErrorPipe[0]);
1236
1237

    /* Setup the stdin, stdout, and stderr pipes.  */
1238
    if(si->StdIn > 0)
1239
      {
1240
      dup2(si->StdIn, 0);
1241
      }
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
    else if(si->StdIn < 0)
      {
      close(0);
      }
    if(si->StdOut != 1)
      {
      dup2(si->StdOut, 1);
      }
    if(si->StdErr != 2)
      {
      dup2(si->StdErr, 2);
      }
1254
1255
1256
1257
1258
1259
1260

    /* Clear the close-on-exec flag for stdin, stdout, and stderr.
       Also clear it for the termination pipe.  All other pipe handles
       will be closed when exec succeeds.  */
    fcntl(0, F_SETFD, 0);
    fcntl(1, F_SETFD, 0);
    fcntl(2, F_SETFD, 0);
1261
    fcntl(si->TermPipe, F_SETFD, 0);
1262
1263
1264
1265
1266
1267
1268
1269

    /* Restore all default signal handlers. */
    kwsysProcessRestoreDefaultSignalHandlers();

    /* Execute the real process.  If successful, this does not return.  */
    execvp(cp->Commands[index][0], cp->Commands[index]);

    /* Failure.  Report error to parent and terminate.  */
1270
    kwsysProcessChildErrorExit(si->ErrorPipe[1]);
1271
1272
    }

1273
  /* We are done with the error reporting pipe write end.  */
1274
  kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
1275
1276
1277
1278

  /* Block until the child's exec call succeeds and closes the error
     pipe or writes data to the pipe to report an error.  */
  {
1279
1280
1281
1282
1283
1284
  int total = 0;
  int n = 1;
  /* Read the entire error message up to the length of our buffer.  */
  while(total < KWSYSPE_PIPE_BUFFER_SIZE && n > 0)
    {
    /* Keep trying to read until the operation is not interrupted.  */
1285
    while(((n = read(si->ErrorPipe[0], cp->ErrorMessage+total,
1286
1287
1288
1289
1290
1291
1292
1293
1294
                     KWSYSPE_PIPE_BUFFER_SIZE-total)) < 0) &&
          (errno == EINTR));
    if(n > 0)
      {
      total += n;
      }
    }

  /* We are done with the error reporting pipe read end.  */
1295
  kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
1296
1297

  if(total > 0)
1298
1299
1300
1301
1302
1303
1304
    {
    /* The child failed to execute the process.  */
    return 0;
    }
  }

  /* Successfully created this child process.  */
1305
  if(index > 0 || si->StdIn > 0)
Brad King's avatar