The Machine Perception Toolbox

[Introduction]- [News]- [Download]- [Screenshots]- [Manual (pdf)]- [Forums]- [API Reference]- [Repository ]

 

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

execunix.c File Reference

#include "jam.h"
#include "lists.h"
#include "execcmd.h"
#include <errno.h>

Include dependency graph for execunix.c:

Include dependency graph

Go to the source code of this file.

Functions

void execcmd (char *string, void(*func)(void *closure, int status), void *closure, LIST *shell)
int execwait ()
void onintr (int disp)

Variables

int cmdsrunning = 0
int intr = 0
void(* istat )(int)
struct {
   void *   closure
   void(*   func )(void *closure, int status)
   int   pid
MAXJOBS


Function Documentation

void execcmd char *  string,
void(*)(void *closure, int status)  func,
void *  closure,
LIST shell
 

Definition at line 99 of file execunix.c.

References cmdsrunning, execwait(), EXITBAD, f(), fclose(), i, istat, LIST, list_next, MAXARGC, MAXJOBS, MAXLINE, onintr(), p, pid, sprintf(), and string.

Referenced by make1c().

00104 {
00105         int pid;
00106         int slot;
00107         char *argv[ MAXARGC + 1 ];      /* +1 for NULL */
00108 
00109 # ifdef USE_EXECNT
00110         char *p;
00111 # endif
00112 
00113         /* Find a slot in the running commands table for this one. */
00114 
00115         for( slot = 0; slot < MAXJOBS; slot++ )
00116             if( !cmdtab[ slot ].pid )
00117                 break;
00118 
00119         if( slot == MAXJOBS )
00120         {
00121             printf( "no slots for child!\n" );
00122             exit( EXITBAD );
00123         }
00124 
00125 # ifdef USE_EXECNT
00126         if( !cmdtab[ slot ].tempfile )
00127         {
00128             char *tempdir;
00129 
00130             if( !( tempdir = getenv( "TEMP" ) ) &&
00131                 !( tempdir = getenv( "TMP" ) ) )
00132                     tempdir = "\\temp";
00133 
00134             cmdtab[ slot ].tempfile = malloc( strlen( tempdir ) + 14 );
00135 
00136             sprintf( cmdtab[ slot ].tempfile, "%s\\jamtmp%02d.bat", 
00137                                 tempdir, slot );
00138         }
00139 
00140         /* Trim leading, ending white space */
00141 
00142         while( isspace( *string ) )
00143                 ++string;
00144 
00145         p = strchr( string, '\n' );
00146 
00147         while( p && isspace( *p ) )
00148                 ++p;
00149 
00150         /* If multi line, or too long, or JAMSHELL is set, write to bat file. */
00151         /* Otherwise, exec directly. */
00152         /* Frankly, if it is a single long line I don't think the */
00153         /* command interpreter will do any better -- it will fail. */
00154 
00155         if( p && *p || strlen( string ) > MAXLINE || shell )
00156         {
00157             FILE *f;
00158 
00159             /* Write command to bat file. */
00160 
00161             f = fopen( cmdtab[ slot ].tempfile, "w" );
00162             fputs( string, f );
00163             fclose( f );
00164 
00165             string = cmdtab[ slot ].tempfile;
00166         }
00167 # endif
00168 
00169         /* Forumulate argv */
00170         /* If shell was defined, be prepared for % and ! subs. */
00171         /* Otherwise, use stock /bin/sh (on unix) or cmd.exe (on NT). */
00172 
00173         if( shell )
00174         {
00175             int i;
00176             char jobno[4];
00177             int gotpercent = 0;
00178 
00179             sprintf( jobno, "%d", slot + 1 );
00180 
00181             for( i = 0; shell && i < MAXARGC; i++, shell = list_next( shell ) )
00182             {
00183                 switch( shell->string[0] )
00184                 {
00185                 case '%':       argv[i] = string; gotpercent++; break;
00186                 case '!':       argv[i] = jobno; break;
00187                 default:        argv[i] = shell->string;
00188                 }
00189                 if( DEBUG_EXECCMD )
00190                     printf( "argv[%d] = '%s'\n", i, argv[i] );
00191             }
00192 
00193             if( !gotpercent )
00194                 argv[i++] = string;
00195 
00196             argv[i] = 0;
00197         }
00198         else
00199         {
00200 # ifdef USE_EXECNT
00201             argv[0] = "cmd.exe";
00202             argv[1] = "/Q/C";           /* anything more is non-portable */
00203 # else
00204             argv[0] = "/bin/sh";
00205             argv[1] = "-c";
00206 # endif
00207             argv[2] = string;
00208             argv[3] = 0;
00209         }
00210 
00211         /* Catch interrupts whenever commands are running. */
00212 
00213         if( !cmdsrunning++ )
00214             istat = signal( SIGINT, onintr );
00215 
00216         /* Start the command */
00217 
00218 # ifdef USE_EXECNT
00219         if( ( pid = spawnvp( P_NOWAIT, argv[0], argv ) ) == -1 )
00220         {
00221             perror( "spawn" );
00222             exit( EXITBAD );
00223         }
00224 # else
00225         if ((pid = vfork()) == 0) 
00226         {
00227                 execvp( argv[0], argv );
00228                 _exit(127);
00229         }
00230 
00231         if( pid == -1 )
00232         {
00233             perror( "vfork" );
00234             exit( EXITBAD );
00235         }
00236 # endif
00237         /* Save the operation for execwait() to find. */
00238 
00239         cmdtab[ slot ].pid = pid;
00240         cmdtab[ slot ].func = func;
00241         cmdtab[ slot ].closure = closure;
00242 
00243         /* Wait until we're under the limit of concurrent commands. */
00244         /* Don't trust globs.jobs alone. */
00245 
00246         while( cmdsrunning >= MAXJOBS || cmdsrunning >= globs.jobs )
00247             if( !execwait() )
00248                 break;
00249 }

Here is the call graph for this function:

int execwait  ) 
 

Definition at line 256 of file execunix.c.

References EXITBAD, i, and istat.

Referenced by execcmd(), and make1().

00257 {
00258         int i;
00259         int status, w;
00260         int rstat;
00261 
00262         /* Handle naive make1() which doesn't know if cmds are running. */
00263 
00264         if( !cmdsrunning )
00265             return 0;
00266 
00267         /* Pick up process pid and status */
00268     
00269         while( ( w = wait( &status ) ) == -1 && errno == EINTR )
00270                 ;
00271 
00272         if( w == -1 )
00273         {
00274             printf( "child process(es) lost!\n" );
00275             perror("wait");
00276             exit( EXITBAD );
00277         }
00278 
00279         /* Find the process in the cmdtab. */
00280 
00281         for( i = 0; i < MAXJOBS; i++ )
00282             if( w == cmdtab[ i ].pid )
00283                 break;
00284 
00285         if( i == MAXJOBS )
00286         {
00287             printf( "waif child found!\n" );
00288             exit( EXITBAD );
00289         }
00290 
00291         /* Drive the completion */
00292 
00293         if( !--cmdsrunning )
00294             signal( SIGINT, istat );
00295 
00296         if( intr )
00297             rstat = EXEC_CMD_INTR;
00298         else if( w == -1 || status != 0 )
00299             rstat = EXEC_CMD_FAIL;
00300         else
00301             rstat = EXEC_CMD_OK;
00302 
00303         cmdtab[ i ].pid = 0;
00304 
00305         (*cmdtab[ i ].func)( cmdtab[ i ].closure, rstat );
00306 
00307         return 1;
00308 }

void onintr int  disp  ) 
 

Definition at line 88 of file execunix.c.

References intr.

Referenced by execcmd().

00089 {
00090         intr++;
00091         printf( "...interrupted\n" );
00092 }


Variable Documentation

void* closure
 

Definition at line 75 of file execunix.c.

Referenced by make_closure().

int cmdsrunning = 0 [static]
 

Definition at line 68 of file execunix.c.

Referenced by execcmd().

void(* func)(void *closure, int status)
 

int intr = 0 [static]
 

Definition at line 67 of file execunix.c.

Referenced by onintr().

void(* istat)(int) [static]
 

Definition at line 69 of file execunix.c.

Referenced by execcmd(), and execwait().

struct { ... } MAXJOBS [static]
 

int pid
 

Definition at line 73 of file execunix.c.

Referenced by execcmd().


Generated on Mon Nov 8 17:07:58 2004 for MPT by  doxygen 1.3.9.1