1 /* 2 * Copyright (c) 1988, 1989, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * Copyright (c) 1989 by Berkeley Softworks 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Adam de Boor. 9 * 10 * %sccs.include.redist.c% 11 * 12 * @(#)job.h 8.2 (Berkeley) 04/28/95 13 */ 14 15 /*- 16 * job.h -- 17 * Definitions pertaining to the running of jobs in parallel mode. 18 * Exported from job.c for the use of remote-execution modules. 19 */ 20 #ifndef _JOB_H_ 21 #define _JOB_H_ 22 23 #define TMPPAT "/tmp/makeXXXXX" 24 25 /* 26 * The SEL_ constants determine the maximum amount of time spent in select 27 * before coming out to see if a child has finished. SEL_SEC is the number of 28 * seconds and SEL_USEC is the number of micro-seconds 29 */ 30 #define SEL_SEC 0 31 #define SEL_USEC 500000 32 33 34 /*- 35 * Job Table definitions. 36 * 37 * Each job has several things associated with it: 38 * 1) The process id of the child shell 39 * 2) The graph node describing the target being made by this job 40 * 3) A LstNode for the first command to be saved after the job 41 * completes. This is NILLNODE if there was no "..." in the job's 42 * commands. 43 * 4) An FILE* for writing out the commands. This is only 44 * used before the job is actually started. 45 * 5) A union of things used for handling the shell's output. Different 46 * parts of the union are used based on the value of the usePipes 47 * flag. If it is true, the output is being caught via a pipe and 48 * the descriptors of our pipe, an array in which output is line 49 * buffered and the current position in that buffer are all 50 * maintained for each job. If, on the other hand, usePipes is false, 51 * the output is routed to a temporary file and all that is kept 52 * is the name of the file and the descriptor open to the file. 53 * 6) An identifier provided by and for the exclusive use of the 54 * Rmt module. 55 * 7) A word of flags which determine how the module handles errors, 56 * echoing, etc. for the job 57 * 58 * The job "table" is kept as a linked Lst in 'jobs', with the number of 59 * active jobs maintained in the 'nJobs' variable. At no time will this 60 * exceed the value of 'maxJobs', initialized by the Job_Init function. 61 * 62 * When a job is finished, the Make_Update function is called on each of the 63 * parents of the node which was just remade. This takes care of the upward 64 * traversal of the dependency graph. 65 */ 66 #define JOB_BUFSIZE 1024 67 typedef struct Job { 68 int pid; /* The child's process ID */ 69 GNode *node; /* The target the child is making */ 70 LstNode tailCmds; /* The node of the first command to be 71 * saved when the job has been run */ 72 FILE *cmdFILE; /* When creating the shell script, this is 73 * where the commands go */ 74 int rmtID; /* ID returned from Rmt module */ 75 short flags; /* Flags to control treatment of job */ 76 #define JOB_IGNERR 0x001 /* Ignore non-zero exits */ 77 #define JOB_SILENT 0x002 /* no output */ 78 #define JOB_SPECIAL 0x004 /* Target is a special one. i.e. run it locally 79 * if we can't export it and maxLocal is 0 */ 80 #define JOB_IGNDOTS 0x008 /* Ignore "..." lines when processing 81 * commands */ 82 #define JOB_REMOTE 0x010 /* Job is running remotely */ 83 #define JOB_FIRST 0x020 /* Job is first job for the node */ 84 #define JOB_REMIGRATE 0x040 /* Job needs to be remigrated */ 85 #define JOB_RESTART 0x080 /* Job needs to be completely restarted */ 86 #define JOB_RESUME 0x100 /* Job needs to be resumed b/c it stopped, 87 * for some reason */ 88 #define JOB_CONTINUING 0x200 /* We are in the process of resuming this job. 89 * Used to avoid infinite recursion between 90 * JobFinish and JobRestart */ 91 union { 92 struct { 93 int op_inPipe; /* Input side of pipe associated 94 * with job's output channel */ 95 int op_outPipe; /* Output side of pipe associated with 96 * job's output channel */ 97 char op_outBuf[JOB_BUFSIZE + 1]; 98 /* Buffer for storing the output of the 99 * job, line by line */ 100 int op_curPos; /* Current position in op_outBuf */ 101 } o_pipe; /* data used when catching the output via 102 * a pipe */ 103 struct { 104 char of_outFile[sizeof(TMPPAT)+2]; 105 /* Name of file to which shell output 106 * was rerouted */ 107 int of_outFd; /* Stream open to the output 108 * file. Used to funnel all 109 * from a single job to one file 110 * while still allowing 111 * multiple shell invocations */ 112 } o_file; /* Data used when catching the output in 113 * a temporary file */ 114 } output; /* Data for tracking a shell's output */ 115 } Job; 116 117 #define outPipe output.o_pipe.op_outPipe 118 #define inPipe output.o_pipe.op_inPipe 119 #define outBuf output.o_pipe.op_outBuf 120 #define curPos output.o_pipe.op_curPos 121 #define outFile output.o_file.of_outFile 122 #define outFd output.o_file.of_outFd 123 124 125 /*- 126 * Shell Specifications: 127 * Each shell type has associated with it the following information: 128 * 1) The string which must match the last character of the shell name 129 * for the shell to be considered of this type. The longest match 130 * wins. 131 * 2) A command to issue to turn off echoing of command lines 132 * 3) A command to issue to turn echoing back on again 133 * 4) What the shell prints, and its length, when given the echo-off 134 * command. This line will not be printed when received from the shell 135 * 5) A boolean to tell if the shell has the ability to control 136 * error checking for individual commands. 137 * 6) The string to turn this checking on. 138 * 7) The string to turn it off. 139 * 8) The command-flag to give to cause the shell to start echoing 140 * commands right away. 141 * 9) The command-flag to cause the shell to Lib_Exit when an error is 142 * detected in one of the commands. 143 * 144 * Some special stuff goes on if a shell doesn't have error control. In such 145 * a case, errCheck becomes a printf template for echoing the command, 146 * should echoing be on and ignErr becomes another printf template for 147 * executing the command while ignoring the return status. If either of these 148 * strings is empty when hasErrCtl is FALSE, the command will be executed 149 * anyway as is and if it causes an error, so be it. 150 */ 151 typedef struct Shell { 152 char *name; /* the name of the shell. For Bourne and C 153 * shells, this is used only to find the 154 * shell description when used as the single 155 * source of a .SHELL target. For user-defined 156 * shells, this is the full path of the shell. 157 */ 158 Boolean hasEchoCtl; /* True if both echoOff and echoOn defined */ 159 char *echoOff; /* command to turn off echo */ 160 char *echoOn; /* command to turn it back on again */ 161 char *noPrint; /* command to skip when printing output from 162 * shell. This is usually the command which 163 * was executed to turn off echoing */ 164 int noPLen; /* length of noPrint command */ 165 Boolean hasErrCtl; /* set if can control error checking for 166 * individual commands */ 167 char *errCheck; /* string to turn error checking on */ 168 char *ignErr; /* string to turn off error checking */ 169 /* 170 * command-line flags 171 */ 172 char *echo; /* echo commands */ 173 char *exit; /* exit on error */ 174 } Shell; 175 176 177 extern char *targFmt; /* Format string for banner that separates 178 * output from multiple jobs. Contains a 179 * single %s where the name of the node being 180 * made should be put. */ 181 extern GNode *lastNode; /* Last node for which a banner was printed. 182 * If Rmt module finds it necessary to print 183 * a banner, it should set this to the node 184 * for which the banner was printed */ 185 extern int nJobs; /* Number of jobs running (local and remote) */ 186 extern int nLocal; /* Number of jobs running locally */ 187 extern Lst jobs; /* List of active job descriptors */ 188 extern Lst stoppedJobs; /* List of jobs that are stopped or didn't 189 * quite get started */ 190 extern Boolean jobFull; /* Non-zero if no more jobs should/will start*/ 191 192 193 void Job_Touch __P((GNode *, Boolean)); 194 Boolean Job_CheckCommands __P((GNode *, void (*abortProc )(char *, ...))); 195 void Job_CatchChildren __P((Boolean)); 196 void Job_CatchOutput __P((void)); 197 void Job_Make __P((GNode *)); 198 void Job_Init __P((int, int)); 199 Boolean Job_Full __P((void)); 200 Boolean Job_Empty __P((void)); 201 ReturnStatus Job_ParseShell __P((char *)); 202 int Job_End __P((void)); 203 void Job_Wait __P((void)); 204 void Job_AbortAll __P((void)); 205 void JobFlagForMigration __P((int)); 206 207 #endif /* _JOB_H_ */ 208