| 1 | /* | 
|---|
| 2 | * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. | 
|---|
| 3 | * Copyright (c) 1988, 1989 by Adam de Boor | 
|---|
| 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 | * Redistribution and use in source and binary forms, with or without | 
|---|
| 11 | * modification, are permitted provided that the following conditions | 
|---|
| 12 | * are met: | 
|---|
| 13 | * 1. Redistributions of source code must retain the above copyright | 
|---|
| 14 | *    notice, this list of conditions and the following disclaimer. | 
|---|
| 15 | * 2. Redistributions in binary form must reproduce the above copyright | 
|---|
| 16 | *    notice, this list of conditions and the following disclaimer in the | 
|---|
| 17 | *    documentation and/or other materials provided with the distribution. | 
|---|
| 18 | * 3. All advertising materials mentioning features or use of this software | 
|---|
| 19 | *    must display the following acknowledgement: | 
|---|
| 20 | *      This product includes software developed by the University of | 
|---|
| 21 | *      California, Berkeley and its contributors. | 
|---|
| 22 | * 4. Neither the name of the University nor the names of its contributors | 
|---|
| 23 | *    may be used to endorse or promote products derived from this software | 
|---|
| 24 | *    without specific prior written permission. | 
|---|
| 25 | * | 
|---|
| 26 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 
|---|
| 27 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
|---|
| 28 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 
|---|
| 29 | * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 
|---|
| 30 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
|---|
| 31 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 
|---|
| 32 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 
|---|
| 33 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 
|---|
| 34 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 
|---|
| 35 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 
|---|
| 36 | * SUCH DAMAGE. | 
|---|
| 37 | * | 
|---|
| 38 | *      from: @(#)job.h 8.1 (Berkeley) 6/6/93 | 
|---|
| 39 | * $FreeBSD: src/usr.bin/make/job.h,v 1.11 2000/01/17 06:43:41 kris Exp $ | 
|---|
| 40 | */ | 
|---|
| 41 |  | 
|---|
| 42 | /*- | 
|---|
| 43 | * job.h -- | 
|---|
| 44 | *      Definitions pertaining to the running of jobs in parallel mode. | 
|---|
| 45 | *      Exported from job.c for the use of remote-execution modules. | 
|---|
| 46 | */ | 
|---|
| 47 | #ifndef _JOB_H_ | 
|---|
| 48 | #define _JOB_H_ | 
|---|
| 49 |  | 
|---|
| 50 | #define TMPPAT  "/tmp/makeXXXXXXXXXX" | 
|---|
| 51 |  | 
|---|
| 52 | /* | 
|---|
| 53 | * The SEL_ constants determine the maximum amount of time spent in select | 
|---|
| 54 | * before coming out to see if a child has finished. SEL_SEC is the number of | 
|---|
| 55 | * seconds and SEL_USEC is the number of micro-seconds | 
|---|
| 56 | */ | 
|---|
| 57 | #define SEL_SEC         0 | 
|---|
| 58 | #define SEL_USEC        100000 | 
|---|
| 59 |  | 
|---|
| 60 |  | 
|---|
| 61 |  | 
|---|
| 62 | /*- | 
|---|
| 63 | * Job Table definitions. | 
|---|
| 64 | * | 
|---|
| 65 | * Each job has several things associated with it: | 
|---|
| 66 | *      1) The process id of the child shell | 
|---|
| 67 | *      2) The graph node describing the target being made by this job | 
|---|
| 68 | *      3) A LstNode for the first command to be saved after the job | 
|---|
| 69 | *         completes. This is NILLNODE if there was no "..." in the job's | 
|---|
| 70 | *         commands. | 
|---|
| 71 | *      4) An FILE* for writing out the commands. This is only | 
|---|
| 72 | *         used before the job is actually started. | 
|---|
| 73 | *      5) A union of things used for handling the shell's output. Different | 
|---|
| 74 | *         parts of the union are used based on the value of the usePipes | 
|---|
| 75 | *         flag. If it is true, the output is being caught via a pipe and | 
|---|
| 76 | *         the descriptors of our pipe, an array in which output is line | 
|---|
| 77 | *         buffered and the current position in that buffer are all | 
|---|
| 78 | *         maintained for each job. If, on the other hand, usePipes is false, | 
|---|
| 79 | *         the output is routed to a temporary file and all that is kept | 
|---|
| 80 | *         is the name of the file and the descriptor open to the file. | 
|---|
| 81 | *      6) An identifier provided by and for the exclusive use of the | 
|---|
| 82 | *         Rmt module. | 
|---|
| 83 | *      7) A word of flags which determine how the module handles errors, | 
|---|
| 84 | *         echoing, etc. for the job | 
|---|
| 85 | * | 
|---|
| 86 | * The job "table" is kept as a linked Lst in 'jobs', with the number of | 
|---|
| 87 | * active jobs maintained in the 'nJobs' variable. At no time will this | 
|---|
| 88 | * exceed the value of 'maxJobs', initialized by the Job_Init function. | 
|---|
| 89 | * | 
|---|
| 90 | * When a job is finished, the Make_Update function is called on each of the | 
|---|
| 91 | * parents of the node which was just remade. This takes care of the upward | 
|---|
| 92 | * traversal of the dependency graph. | 
|---|
| 93 | */ | 
|---|
| 94 | #define JOB_BUFSIZE         1024 | 
|---|
| 95 | #define JOB_TMPFILESIZE     128 | 
|---|
| 96 | typedef struct Job { | 
|---|
| 97 | int         pid;        /* The child's process ID */ | 
|---|
| 98 | char        tfile[JOB_TMPFILESIZE]; | 
|---|
| 99 | /* Temporary file to use for job */ | 
|---|
| 100 | GNode       *node;      /* The target the child is making */ | 
|---|
| 101 | LstNode     tailCmds;   /* The node of the first command to be | 
|---|
| 102 | * saved when the job has been run */ | 
|---|
| 103 | FILE        *cmdFILE;   /* When creating the shell script, this is | 
|---|
| 104 | * where the commands go */ | 
|---|
| 105 | int         rmtID;     /* ID returned from Rmt module */ | 
|---|
| 106 | short       flags;      /* Flags to control treatment of job */ | 
|---|
| 107 | #define JOB_IGNERR      0x001   /* Ignore non-zero exits */ | 
|---|
| 108 | #define JOB_SILENT      0x002   /* no output */ | 
|---|
| 109 | #define JOB_SPECIAL     0x004   /* Target is a special one. i.e. run it locally | 
|---|
| 110 | * if we can't export it and maxLocal is 0 */ | 
|---|
| 111 | #define JOB_IGNDOTS     0x008   /* Ignore "..." lines when processing | 
|---|
| 112 | * commands */ | 
|---|
| 113 | #define JOB_REMOTE      0x010   /* Job is running remotely */ | 
|---|
| 114 | #define JOB_FIRST       0x020   /* Job is first job for the node */ | 
|---|
| 115 | #define JOB_REMIGRATE   0x040   /* Job needs to be remigrated */ | 
|---|
| 116 | #define JOB_RESTART     0x080   /* Job needs to be completely restarted */ | 
|---|
| 117 | #define JOB_RESUME      0x100   /* Job needs to be resumed b/c it stopped, | 
|---|
| 118 | * for some reason */ | 
|---|
| 119 | #define JOB_CONTINUING  0x200   /* We are in the process of resuming this job. | 
|---|
| 120 | * Used to avoid infinite recursion between | 
|---|
| 121 | * JobFinish and JobRestart */ | 
|---|
| 122 | union { | 
|---|
| 123 | struct { | 
|---|
| 124 | int         op_inPipe;      /* Input side of pipe associated | 
|---|
| 125 | * with job's output channel */ | 
|---|
| 126 | int         op_outPipe;     /* Output side of pipe associated with | 
|---|
| 127 | * job's output channel */ | 
|---|
| 128 | char        op_outBuf[JOB_BUFSIZE + 1]; | 
|---|
| 129 | /* Buffer for storing the output of the | 
|---|
| 130 | * job, line by line */ | 
|---|
| 131 | int         op_curPos;      /* Current position in op_outBuf */ | 
|---|
| 132 | }           o_pipe;         /* data used when catching the output via | 
|---|
| 133 | * a pipe */ | 
|---|
| 134 | struct { | 
|---|
| 135 | char        of_outFile[JOB_TMPFILESIZE]; | 
|---|
| 136 | /* Name of file to which shell output | 
|---|
| 137 | * was rerouted */ | 
|---|
| 138 | int         of_outFd;       /* Stream open to the output | 
|---|
| 139 | * file. Used to funnel all | 
|---|
| 140 | * from a single job to one file | 
|---|
| 141 | * while still allowing | 
|---|
| 142 | * multiple shell invocations */ | 
|---|
| 143 | }           o_file;         /* Data used when catching the output in | 
|---|
| 144 | * a temporary file */ | 
|---|
| 145 | }           output;     /* Data for tracking a shell's output */ | 
|---|
| 146 | } Job; | 
|---|
| 147 |  | 
|---|
| 148 | #define outPipe         output.o_pipe.op_outPipe | 
|---|
| 149 | #define inPipe          output.o_pipe.op_inPipe | 
|---|
| 150 | #define outBuf          output.o_pipe.op_outBuf | 
|---|
| 151 | #define curPos          output.o_pipe.op_curPos | 
|---|
| 152 | #define outFile         output.o_file.of_outFile | 
|---|
| 153 | #define outFd           output.o_file.of_outFd | 
|---|
| 154 |  | 
|---|
| 155 |  | 
|---|
| 156 |  | 
|---|
| 157 | /*- | 
|---|
| 158 | * Shell Specifications: | 
|---|
| 159 | * Each shell type has associated with it the following information: | 
|---|
| 160 | *      1) The string which must match the last character of the shell name | 
|---|
| 161 | *         for the shell to be considered of this type. The longest match | 
|---|
| 162 | *         wins. | 
|---|
| 163 | *      2) A command to issue to turn off echoing of command lines | 
|---|
| 164 | *      3) A command to issue to turn echoing back on again | 
|---|
| 165 | *      4) What the shell prints, and its length, when given the echo-off | 
|---|
| 166 | *         command. This line will not be printed when received from the shell | 
|---|
| 167 | *      5) A boolean to tell if the shell has the ability to control | 
|---|
| 168 | *         error checking for individual commands. | 
|---|
| 169 | *      6) The string to turn this checking on. | 
|---|
| 170 | *      7) The string to turn it off. | 
|---|
| 171 | *      8) The command-flag to give to cause the shell to start echoing | 
|---|
| 172 | *         commands right away. | 
|---|
| 173 | *      9) The command-flag to cause the shell to Lib_Exit when an error is | 
|---|
| 174 | *         detected in one of the commands. | 
|---|
| 175 | * | 
|---|
| 176 | * Some special stuff goes on if a shell doesn't have error control. In such | 
|---|
| 177 | * a case, errCheck becomes a printf template for echoing the command, | 
|---|
| 178 | * should echoing be on and ignErr becomes another printf template for | 
|---|
| 179 | * executing the command while ignoring the return status. If either of these | 
|---|
| 180 | * strings is empty when hasErrCtl is FALSE, the command will be executed | 
|---|
| 181 | * anyway as is and if it causes an error, so be it. | 
|---|
| 182 | */ | 
|---|
| 183 | typedef struct Shell { | 
|---|
| 184 | char          *name;        /* the name of the shell. For Bourne and C | 
|---|
| 185 | * shells, this is used only to find the | 
|---|
| 186 | * shell description when used as the single | 
|---|
| 187 | * source of a .SHELL target. For user-defined | 
|---|
| 188 | * shells, this is the full path of the shell. | 
|---|
| 189 | */ | 
|---|
| 190 | Boolean       hasEchoCtl;   /* True if both echoOff and echoOn defined */ | 
|---|
| 191 | char          *echoOff;     /* command to turn off echo */ | 
|---|
| 192 | char          *echoOn;      /* command to turn it back on again */ | 
|---|
| 193 | char          *noPrint;     /* command to skip when printing output from | 
|---|
| 194 | * shell. This is usually the command which | 
|---|
| 195 | * was executed to turn off echoing */ | 
|---|
| 196 | int           noPLen;       /* length of noPrint command */ | 
|---|
| 197 | Boolean       hasErrCtl;    /* set if can control error checking for | 
|---|
| 198 | * individual commands */ | 
|---|
| 199 | char          *errCheck;    /* string to turn error checking on */ | 
|---|
| 200 | char          *ignErr;      /* string to turn off error checking */ | 
|---|
| 201 | /* | 
|---|
| 202 | * command-line flags | 
|---|
| 203 | */ | 
|---|
| 204 | char          *echo;        /* echo commands */ | 
|---|
| 205 | char          *exit;        /* exit on error */ | 
|---|
| 206 | }               Shell; | 
|---|
| 207 |  | 
|---|
| 208 |  | 
|---|
| 209 | extern char     *targFmt;       /* Format string for banner that separates | 
|---|
| 210 | * output from multiple jobs. Contains a | 
|---|
| 211 | * single %s where the name of the node being | 
|---|
| 212 | * made should be put. */ | 
|---|
| 213 | extern GNode    *lastNode;      /* Last node for which a banner was printed. | 
|---|
| 214 | * If Rmt module finds it necessary to print | 
|---|
| 215 | * a banner, it should set this to the node | 
|---|
| 216 | * for which the banner was printed */ | 
|---|
| 217 | extern int      nJobs;          /* Number of jobs running (local and remote) */ | 
|---|
| 218 | extern int      nLocal;         /* Number of jobs running locally */ | 
|---|
| 219 | extern Lst      jobs;           /* List of active job descriptors */ | 
|---|
| 220 | extern Lst      stoppedJobs;    /* List of jobs that are stopped or didn't | 
|---|
| 221 | * quite get started */ | 
|---|
| 222 | extern Boolean  jobFull;        /* Non-zero if no more jobs should/will start*/ | 
|---|
| 223 |  | 
|---|
| 224 |  | 
|---|
| 225 | void Job_Touch __P((GNode *, Boolean)); | 
|---|
| 226 | Boolean Job_CheckCommands __P((GNode *, void (*abortProc )(char *, ...))); | 
|---|
| 227 | void Job_CatchChildren __P((Boolean)); | 
|---|
| 228 | void Job_CatchOutput __P((void)); | 
|---|
| 229 | void Job_Make __P((GNode *)); | 
|---|
| 230 | void Job_Init __P((int, int)); | 
|---|
| 231 | Boolean Job_Full __P((void)); | 
|---|
| 232 | Boolean Job_Empty __P((void)); | 
|---|
| 233 | ReturnStatus Job_ParseShell __P((char *)); | 
|---|
| 234 | int Job_End __P((void)); | 
|---|
| 235 | void Job_Wait __P((void)); | 
|---|
| 236 | void Job_AbortAll __P((void)); | 
|---|
| 237 | void JobFlagForMigration __P((int)); | 
|---|
| 238 |  | 
|---|
| 239 | #endif /* _JOB_H_ */ | 
|---|