IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Oct 9, 2006, 3:01:58 PM (20 years ago)
Author:
magnier
Message:

adding waitpid and program exit status tests, lots of error checks

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/detrend/psPipe.c

    r8848 r9432  
    66#include <string.h>
    77#include <sys/types.h>
     8#include <sys/types.h>
     9#include <sys/wait.h>
    810#include <unistd.h>
    911#include <fcntl.h>
    1012#include <pslib.h>
    11 #include "pmFPA.h"
    12 #include "pmDetrendDB.h"
     13#include <psPipe.h>
    1314
    1415void closePipes (int *stdin_fd, int *stdout_fd, int *stderr_fd)
     
    104105
    105106        status = execvp (argv[0], argv);
    106         // fprintf (stderr, "error starting remote shell process\n");
    107107
    108108        // this statement exits the child, not the parent, process
     
    133133    psPipe *pipe = psPipeAlloc();
    134134
     135    pipe->pid    = pid;
    135136    pipe->stdin  = stdin_fd[1];
    136137    pipe->stdout = stdout_fd[0];
     
    140141}
    141142
    142 bool psPipeClose (psPipe *pipe)
    143 {
    144 
    145     close (pipe->stdin);
    146     close (pipe->stdout);
    147     close (pipe->stderr);
    148     return true;
    149 }
    150 
     143// this function returns the exit status of the called function
     144// or a value > 255 on an error
     145int psPipeClose (psPipe *pipe)
     146{
     147    int close_status;
     148    int exit_status;
     149    int wait_status;
     150    int result;
     151
     152    PS_ASSERT_PTR_NON_NULL(pipe, false);
     153
     154    close_status = true;
     155    if (close (pipe->stdin) != 0) {
     156        psError(PS_ERR_IO, true, "error closing the pipe stdin (pid %d, error %s)\n", pipe->pid, strerror(errno));
     157        close_status = false;
     158    }
     159    if (close (pipe->stdout) != 0) {
     160        psError(PS_ERR_IO, true, "error closing the pipe stdout (pid %d, error %s)\n", pipe->pid, strerror(errno));
     161        close_status = false;
     162    }
     163    if (close (pipe->stderr) != 0) {
     164        psError(PS_ERR_IO, true, "error closing the pipe sterr (pid %d, error %s)\n", pipe->pid, strerror(errno));
     165        close_status = false;
     166    }
     167
     168    // we expect the child process to have exited.
     169    // wait for the exit condition, but no longer than 100ms
     170    for (int i = 0; i < 10; i++) {
     171        result = waitpid (pipe->pid, &wait_status, WNOHANG);
     172        switch (result) {
     173        case -1:   // error on waitpid
     174            switch (errno) {
     175            case ECHILD:
     176                psError(PS_ERR_IO, true, "unknown PID, not a child process: %d\n", pipe->pid);
     177                return 0x100;
     178            default:
     179                psAbort ("psPipeClose", "unexpected response to waitpid: %d\n", result);
     180            }
     181            break;
     182
     183        case 0:   // child not yet exited
     184            usleep (10000);
     185            continue;
     186
     187        default:
     188            if (result != pipe->pid) {
     189                psAbort ("psPipeClose", "waitpid error: mis-matched PID (%d vs %d).  programming error\n", result, pipe->pid);
     190            }
     191            if (WIFEXITED(wait_status)) {
     192                exit_status = WEXITSTATUS(wait_status);
     193                if (close_status) {
     194                    return exit_status;
     195                } else {
     196                    return (0x100);
     197                }
     198            }
     199            if (WIFSIGNALED(wait_status)) {
     200                psError(PS_ERR_IO, true, "job %d exited on signal %d\n", pipe->pid, WTERMSIG(wait_status));
     201                return (0x100 + WTERMSIG(wait_status));
     202            }
     203            if (WIFSTOPPED(wait_status)) {
     204                psAbort ("psPipeClose", "waitpid returns 'stopped' programming error\n");
     205            }
     206        }
     207    }
     208    psError(PS_ERR_IO, true, "child process pid %d did not exit\n", pipe->pid);
     209    return 0x100;
     210}
Note: See TracChangeset for help on using the changeset viewer.