Esempio n. 1
0
void
meta_compat_child(void)
{
    meta_job_child(NULL);
    if (dup2(childPipe[1], 1) < 0 ||
	dup2(1, 2) < 0) {
	execError("dup2", "pipe");
	_exit(1);
    }
}
Esempio n. 2
0
// (call 'any ..) -> flg
any doCall(any ex) {
   pid_t pid;
   any x, y;
   int res, i, ac = length(x = cdr(ex));
   char *av[ac+1];

   if (ac == 0)
      return Nil;
   av[0] = alloc(NULL, pathSize(y = evSym(x))),  pathString(y, av[0]);
   for (i = 1; isCell(x = cdr(x)); ++i)
      av[i] = alloc(NULL, bufSize(y = evSym(x))),  bufString(y, av[i]);
   av[ac] = NULL;
   flushAll();
   if ((pid = fork()) == 0) {
      setpgid(0,0);
      execvp(av[0], av);
      execError(av[0]);
   }
   i = 0;  do
      free(av[i]);
   while (++i < ac);
   if (pid < 0)
      err(ex, NULL, "fork");
   setpgid(pid,0);
   if (Termio)
      tcsetpgrp(0,pid);
   for (;;) {
      while (waitpid(pid, &res, WUNTRACED) < 0) {
         if (errno != EINTR)
            err(ex, NULL, "wait pid");
         if (*Signal)
            sighandler(ex);
      }
      if (Termio)
         tcsetpgrp(0,getpgrp());
      if (!WIFSTOPPED(res))
         return res == 0? T : Nil;
      load(NULL, '+', Nil);
      if (Termio)
         tcsetpgrp(0,pid);
      kill(pid, SIGCONT);
   }
}
Esempio n. 3
0
/*-
 *-----------------------------------------------------------------------
 * CompatRunCommand --
 *	Execute the next command for a target. If the command returns an
 *	error, the node's made field is set to ERROR and creation stops.
 *
 * Input:
 *	cmdp		Command to execute
 *	gnp		Node from which the command came
 *
 * Results:
 *	0 if the command succeeded, 1 if an error occurred.
 *
 * Side Effects:
 *	The node's 'made' field may be set to ERROR.
 *
 *-----------------------------------------------------------------------
 */
int
CompatRunCommand(void *cmdp, void *gnp)
{
    char    	  *cmdStart;	/* Start of expanded command */
    char 	  *cp, *bp;
    Boolean 	  silent,   	/* Don't print command */
	    	  doIt;		/* Execute even if -n */
    volatile Boolean errCheck; 	/* Check errors */
    WAIT_T 	  reason;   	/* Reason for child's death */
    int	    	  status;   	/* Description of child's death */
    pid_t	  cpid;	    	/* Child actually found */
    pid_t	  retstat;    	/* Result of wait */
    LstNode 	  cmdNode;  	/* Node where current command is located */
    const char  ** volatile av;	/* Argument vector for thing to exec */
    char	** volatile mav;/* Copy of the argument vector for freeing */
    int	    	  argc;	    	/* Number of arguments in av or 0 if not
				 * dynamically allocated */
    Boolean 	  local;    	/* TRUE if command should be executed
				 * locally */
    Boolean 	  useShell;    	/* TRUE if command should be executed
				 * using a shell */
    char	  * volatile cmd = (char *)cmdp;
    GNode	  *gn = (GNode *)gnp;

    silent = gn->type & OP_SILENT;
    errCheck = !(gn->type & OP_IGNORE);
    doIt = FALSE;
    
    cmdNode = Lst_Member(gn->commands, cmd);
    cmdStart = Var_Subst(NULL, cmd, gn, FALSE);

    /*
     * brk_string will return an argv with a NULL in av[0], thus causing
     * execvp to choke and die horribly. Besides, how can we execute a null
     * command? In any case, we warn the user that the command expanded to
     * nothing (is this the right thing to do?).
     */

    if (*cmdStart == '\0') {
	free(cmdStart);
	Error("%s expands to empty string", cmd);
	return(0);
    }
    cmd = cmdStart;
    Lst_Replace(cmdNode, cmdStart);

    if ((gn->type & OP_SAVE_CMDS) && (gn != ENDNode)) {
	(void)Lst_AtEnd(ENDNode->commands, cmdStart);
	return(0);
    }
    if (strcmp(cmdStart, "...") == 0) {
	gn->type |= OP_SAVE_CMDS;
	return(0);
    }

    while ((*cmd == '@') || (*cmd == '-') || (*cmd == '+')) {
	switch (*cmd) {
	case '@':
	    silent = DEBUG(LOUD) ? FALSE : TRUE;
	    break;
	case '-':
	    errCheck = FALSE;
	    break;
	case '+':
	    doIt = TRUE;
	    if (!meta[0])		/* we came here from jobs */
		Compat_Init();
	    break;
	}
	cmd++;
    }

    while (isspace((unsigned char)*cmd))
	cmd++;

#if !defined(MAKE_NATIVE)
    /*
     * In a non-native build, the host environment might be weird enough
     * that it's necessary to go through a shell to get the correct
     * behaviour.  Or perhaps the shell has been replaced with something
     * that does extra logging, and that should not be bypassed.
     */
    useShell = TRUE;
#else
    /*
     * Search for meta characters in the command. If there are no meta
     * characters, there's no need to execute a shell to execute the
     * command.
     */
    for (cp = cmd; !meta[(unsigned char)*cp]; cp++) {
	continue;
    }
    useShell = (*cp != '\0');
#endif

    /*
     * Print the command before echoing if we're not supposed to be quiet for
     * this one. We also print the command if -n given.
     */
    if (!silent || NoExecute(gn)) {
	printf("%s\n", cmd);
	fflush(stdout);
    }

    /*
     * If we're not supposed to execute any commands, this is as far as
     * we go...
     */
    if (!doIt && NoExecute(gn)) {
	return (0);
    }
    if (DEBUG(JOB))
	fprintf(debug_file, "Execute: '%s'\n", cmd);

again:
    if (useShell) {
	/*
	 * We need to pass the command off to the shell, typically
	 * because the command contains a "meta" character.
	 */
	static const char *shargv[4];

	shargv[0] = shellPath;
	/*
	 * The following work for any of the builtin shell specs.
	 */
	if (DEBUG(SHELL))
		shargv[1] = "-xc";
	else
		shargv[1] = "-c";
	shargv[2] = cmd;
	shargv[3] = NULL;
	av = shargv;
	argc = 0;
	bp = NULL;
	mav = NULL;
    } else {
	/*
	 * No meta-characters, so no need to exec a shell. Break the command
	 * into words to form an argument vector we can execute.
	 */
	mav = brk_string(cmd, &argc, TRUE, &bp);
	if (mav == NULL) {
		useShell = 1;
		goto again;
	}
	av = (const char **)mav;
    }

    local = TRUE;

#ifdef USE_META
    if (useMeta) {
	meta_compat_start();
    }
#endif
    
    /*
     * Fork and execute the single command. If the fork fails, we abort.
     */
    cpid = vFork();
    if (cpid < 0) {
	Fatal("Could not fork");
    }
    if (cpid == 0) {
	Check_Cwd(av);
	Var_ExportVars();
#ifdef USE_META
	if (useMeta) {
	    meta_compat_child();
	}
#endif
	if (local)
	    (void)execvp(av[0], (char *const *)UNCONST(av));
	else
	    (void)execv(av[0], (char *const *)UNCONST(av));
	execError("exec", av[0]);
	_exit(1);
    }
    if (mav)
	free(mav);
    if (bp)
	free(bp);
    Lst_Replace(cmdNode, NULL);

#ifdef USE_META
    if (useMeta) {
	meta_compat_parent();
    }
#endif

    /*
     * The child is off and running. Now all we can do is wait...
     */
    while (1) {

	while ((retstat = wait(&reason)) != cpid) {
	    if (retstat > 0)
		JobReapChild(retstat, reason, FALSE); /* not ours? */
	    if (retstat == -1 && errno != EINTR) {
		break;
	    }
	}

	if (retstat > -1) {
	    if (WIFSTOPPED(reason)) {
		status = WSTOPSIG(reason);		/* stopped */
	    } else if (WIFEXITED(reason)) {
		status = WEXITSTATUS(reason);		/* exited */
#if defined(USE_META) && defined(USE_FILEMON_ONCE)
		if (useMeta) {
		    meta_cmd_finish(NULL);
		}
#endif
		if (status != 0) {
		    if (DEBUG(ERROR)) {
		        fprintf(debug_file, "\n*** Failed target:  %s\n*** Failed command: ",
			    gn->name);
		        for (cp = cmd; *cp; ) {
    			    if (isspace((unsigned char)*cp)) {
				fprintf(debug_file, " ");
			        while (isspace((unsigned char)*cp))
				    cp++;
			    } else {
				fprintf(debug_file, "%c", *cp);
			        cp++;
			    }
		        }
			fprintf(debug_file, "\n");
		    }
		    printf("*** Error code %d", status);
		}
	    } else {
		status = WTERMSIG(reason);		/* signaled */
		printf("*** Signal %d", status);
	    }


	    if (!WIFEXITED(reason) || (status != 0)) {
		if (errCheck) {
#ifdef USE_META
		    if (useMeta) {
			meta_job_error(NULL, gn, 0, status);
		    }
#endif
		    gn->made = ERROR;
		    if (keepgoing) {
			/*
			 * Abort the current target, but let others
			 * continue.
			 */
			printf(" (continuing)\n");
		    }
		} else {
		    /*
		     * Continue executing commands for this target.
		     * If we return 0, this will happen...
		     */
		    printf(" (ignored)\n");
		    status = 0;
		}
	    }
	    break;
	} else {
	    Fatal("error in wait: %d: %s", retstat, strerror(errno));
	    /*NOTREACHED*/
	}
    }
    free(cmdStart);

    return (status);
}
Esempio n. 4
0
void CNotify::execLinkError(int number){
    switch(number){
    case 1:
        execError("Not super-user (Not owner)");
        break;
    case 2:
        execError("No such file or directory");
        break;
    case 3:
        execError("No such process");
        break;
    case 4:
        execError("Interrupted system call");
        break;
    case 5:
        execError("IO error");
        break;
    case 6:
        execError("No such device or address");
        break;
    case 7:
        execError("Argument list too long");
        break;
    case 8:
        execError("Bad executable format (ensure app signature matches kernel signature)");
        break;
    case 9:
        execError("Bad file number");
        break;
    case 10:
        execError("No childer");
        break;
    case 11:
        execError("Resource temporarily unavailable");
        break;
    case 12:
        execError("No more memory");
        break;
    case 13:
        execError("Permission denied");
        break;
    case 14:
        execError("Bad address");
        break;
    case 15:
        execError("Block device required");
        break;
    case 16:
        execError("Mount device busy");
        break;
    case 17:
        execError("File exists");
        break;
    case 18:
        execError("Cross-device link");
        break;
    case 19:
        execError("No such device");
        break;
    case 20:
        execError("Not a directory");
        break;
    case 21:
        execError("Permission denied");
        break;
    case 22:
        execError("Invalid argument");
        break;
    case 23:
        execError("Too many open files on device");
        break;
    case 24:
        execError("Too many open files");
        break;
    case 25:
        execError("Not a character device");
        break;
    case 26:
        execError("Text file busy");
        break;
    case 27:
        execError("File too large");
        break;
    case 28:
        execError("No space left on device");
        break;
    case 29:
        execError("Illegal seek");
        break;
    case 30:
        execError("Read-only filesystem");
        break;
    case 31:
        execError("Too many links");
        break;
    case 32:
        execError("Broken pipe");
        break;
    case 57:
        execError("Bad font file format");
        break;
    case 61:
        execError("No data (for no delay IO)");
        break;
    case 62:
        execError("Timer expired");
        break;
    case 64:
        execError("Machine is not on the network");
        break;
    case 65:
        execError("Package not installed");
        break;
    case 66:
        execError("The object is remote");
        break;
    case 67:
        execError("The link has been severed");
        break;
    case 68:
        execError("Advertise error");
        break;
    case 69:
        execError("Srmount error");
        break;
    case 70:
        execError("Communication error on send");
        break;
    case 71:
        execError("Protocol error");
        break;
    case 74:
        execError("Multihop attempted");
        break;
    case 75:
        execError("Inode is remote (not really error)");
        break;
    case 88:
        execError("Function is not implemented");
        break;
    case 89:
        execError("No more files");
        break;
    case 90:
        execError("Directory not empty");
        break;
    case 91:
        execError("File or path name too long");
        break;
    case 92:
        execError("Too many symbolic links");
        break;
    case 109:
        execError("Protocol not available");
        break;
    case 134:
        execError("This operation is not supported");
        break;
    default:
        execError("Failed with error code " + QString::number(number));
    }

}
Esempio n. 5
0
void CNotify::execNotConnected(){
    execError("Device is Not Connected");
}