Changeset 4450 for trunk/Ohana/src/opihi/pantasks/LocalJob.c
- Timestamp:
- Jul 4, 2005, 5:35:47 PM (21 years ago)
- File:
-
- 1 edited
-
trunk/Ohana/src/opihi/pantasks/LocalJob.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Ohana/src/opihi/pantasks/LocalJob.c
r3392 r4450 1 # include "scheduler.h" 1 2 2 /* local jobs are forked in the background */ 3 /* this could be written a just a one-way pipe */ 4 int SubmitLocalJob (Job *job) { 3 5 4 SubmitLocalJob (Job *job) { 6 int status, pid; 7 int stdout_fd[2], stderr_fd[2]; 5 8 6 /* 7 construct the command line 8 fork the command, get back the PID 9 increment local job counter 10 */ 9 bzero (stdout_fd, 2*sizeof(int)); 10 bzero (stderr_fd, 2*sizeof(int)); 11 11 12 if (pipe (stdout_fd) < 0) goto pipe_error; 13 if (pipe (stderr_fd) < 0) goto pipe_error; 14 15 pid = fork (); 16 if (!pid) { /* must be child process */ 17 fprintf (stderr, "starting controller connection\n"); 18 19 /* close the other ends of the pipes */ 20 close (stdout_fd[0]); 21 close (stderr_fd[0]); 22 23 /* tie our ends of the pipes to stdin, stdout, stderr */ 24 dup2 (stdout_fd[1], STDOUT_FILENO); 25 dup2 (stderr_fd[1], STDERR_FILENO); 26 27 /* set all three unblocking */ 28 setvbuf (stdout, (char *) NULL, _IONBF, BUFSIZ); 29 setvbuf (stderr, (char *) NULL, _IONBF, BUFSIZ); 30 31 status = execvp (job[0].argv[0], job[0].argv); 32 exit (1); 33 } 34 35 /* close the other ends of the pipes */ 36 close (stdout_fd[1]); stdout_fd[1] = 0; 37 close (stderr_fd[1]); stderr_fd[1] = 0; 38 39 /* make the pipes non-blocking */ 40 fcntl (stdout_fd[0], F_SETFL, O_NONBLOCK); 41 fcntl (stderr_fd[0], F_SETFL, O_NONBLOCK); 42 43 job[0].stdout_fd = stdout_fd[0]; 44 job[0].stderr_fd = stderr_fd[0]; 45 job[0].pid = pid; 46 47 return (TRUE); 48 49 pipe_error: 50 perror ("pipe error:"); 51 if (stdout_fd[0] != 0) close (stdout_fd[0]); 52 if (stdout_fd[1] != 0) close (stdout_fd[1]); 53 if (stderr_fd[0] != 0) close (stderr_fd[0]); 54 if (stderr_fd[1] != 0) close (stderr_fd[1]); 55 return (FALSE); 12 56 } 13 57 14 CheckLocalJob (Job *job) { 58 /* update current state, drain stdout/stderr buffers */ 59 int CheckLocalJob (Job *job) { 15 60 16 /* 17 61 int Nread; 62 63 // XXX do something useful with exit status? 64 CheckLocalJobStatus (job); 65 66 /* read stdout buffer */ 67 Nread = ReadtoIOBuffer (&job[0].stdout, job[0].stdout_fd); 68 switch (Nread) { 69 case -2: /* error in read (programming error? system level error?) */ 70 fprintf (stderr, "serious IO error\n"); 71 exit (2); 72 case -1: /* no data in pipe */ 73 break; 74 case 0: /* pipe is closed */ 75 /** change child state? **/ 76 break; 77 default: /* data in pipe */ 78 break; 79 } 80 81 /* read stderr buffer */ 82 Nread = ReadtoIOBuffer (&job[0].stderr, job[0].stderr_fd); 83 switch (Nread) { 84 case -2: /* error in read (programming error? system level error?) */ 85 fprintf (stderr, "serious IO error\n"); 86 exit (2); 87 case -1: /* no data in pipe */ 88 break; 89 case 0: /* pipe is closed */ 90 /** change child state? **/ 91 break; 92 default: /* data in pipe */ 93 break; 94 } 95 return (TRUE); 96 } 97 98 int CheckLocalJobStatus (Job *job) { 99 100 int result, waitstatus; 101 102 /* check local job status */ 103 result = waitpid (job[0].pid, &waitstatus, WNOHANG); 104 switch (result) { 105 case -1: /* error with waitpid */ 106 switch (errno) { 107 case ECHILD: 108 fprintf (stderr, "unknown PID, not a child proc\n"); 109 fprintf (stderr, "did process already exit? programming error?\n"); 110 job[0].state = JOB_NONE; 111 job[0].exit_status = 0; 112 return (FALSE); 113 case EINVAL: 114 fprintf (stderr, "error EINVAL (waitpid): programming error\n"); 115 exit (1); 116 case EINTR: 117 fprintf (stderr, "error EINTR (waitpid): programming error\n"); 118 exit (1); 119 default: 120 fprintf (stderr, "unknown error for waitpid (%d): programming error\n", errno); 121 exit (1); 122 } 123 break; 124 125 case 0: /* process not exited */ 126 job[0].state = JOB_BUSY; 127 job[0].exit_status = 0; 128 return (TRUE); 129 130 default: 131 if (result != job[0].pid) { 132 fprintf (stderr, "waitpid error: mis-matched PID (%d vs %d). programming error\n", result, job[0].pid); 133 exit (1); 134 } 135 136 if (WIFEXITED(waitstatus)) { 137 job[0].state = JOB_EXIT; 138 job[0].exit_status = WEXITSTATUS(waitstatus); 139 } 140 if (WIFSIGNALED(waitstatus)) { 141 job[0].state = JOB_CRASH; 142 job[0].exit_status = WTERMSIG(waitstatus); 143 } 144 if (WIFSTOPPED(waitstatus)) { 145 fprintf (stderr, "waitpid returns 'stopped': programming error\n"); 146 exit (1); 147 } 148 } 149 return; 150 }
Note:
See TracChangeset
for help on using the changeset viewer.
