Example #1
0
int
main(int argc, char *argv[], char *envp[])
{
	char buff[BUFSIZ];
    int rc;

    signal(SIGTTOU, SIG_IGN);
    signal(SIGINT, sigint_handler);

    rc = setpgid(0, 0);
    assert(rc != -1);


    builtin_init();
    history_init();

    job_init();

    
    print_prompt();
	while (fgets(buff, BUFSIZ, stdin)) {
		job_run_command(buff, envp);

        job_wait();

        print_prompt();
	}

    job_finalize();

    history_finalize();
    builtin_finalize();

    return 0;
}
Example #2
0
File: misc.c Project: att/ast
//
// Builtin `jobs`.
//
int b_jobs(int n, char *argv[], Shbltin_t *context) {
    int flag = 0;
    Shell_t *shp = context->shp;
    while ((n = optget(argv, sh_optjobs))) {
        switch (n) {
            case 'l': {
                flag = JOB_LFLAG;
                break;
            }
            case 'n': {
                flag = JOB_NFLAG;
                break;
            }
            case 'p': {
                flag = JOB_PFLAG;
                break;
            }
            case ':': {
                errormsg(SH_DICT, 2, "%s", opt_info.arg);
                break;
            }
            case '?': {
                errormsg(SH_DICT, ERROR_usage(2), "%s", opt_info.arg);
                __builtin_unreachable();
            }
            default: { break; }
        }
    }

    argv += opt_info.index;
    if (error_info.errors) {
        errormsg(SH_DICT, ERROR_usage(2), "%s", optusage(NULL));
        __builtin_unreachable();
    }

    if (*argv == 0) argv = NULL;
    if (job_walk(shp, sfstdout, job_list, flag, argv)) {
        errormsg(SH_DICT, ERROR_exit(1), e_no_job);
        __builtin_unreachable();
    }
    job_wait((pid_t)0);
    return shp->exitval;
}
Example #3
0
int task_wait(struct task **tasks, struct task *t, int async)
{
	struct proc *p;
	struct job *j;

	for(j = t->jobs; j; j = j->next)
		while(!job_complete(j)){
			/* TODO: term_give_to() */
			job_wait(j, async);

			if(async && j->state == JOB_RUNNING)
				/* no change */
				return 0;
			else if(j->state == JOB_COMPLETE){
				/* changed to complete, next job in the list */
				if(j->next){
					job_start(j->next);
					if(async)
						return 0;
					continue;
				}else{
					task_rm(tasks, t);
					return 1;
				}
			}

			/*
			* check for a stopped proc
			* if we find one, it's
			* been ^Z'd, stop other procs and return
			*/
			for(p = j->proc; p; p = p->next)
				if(p->state == PROC_STOP){
					job_sig(j, SIGSTOP);
					return 0;
					/* don't attempt to move onto any other jobs */
				}
		}

	return 0;
}
Example #4
0
/*
 * used with command -x to run the command in multiple passes
 * spawn is non-zero when invoked via spawn
 * the exitval is set to the maximum for each execution
 */
static pid_t path_xargs(Shell_t *shp,const char *path, char *argv[],char *const envp[], int spawn)
{
	register char *cp, **av, **xv;
	char **avlast= &argv[shp->xargmax], **saveargs=0;
	char *const *ev;
	long size, left;
	int nlast=1,n,exitval=0;
	pid_t pid;
	if(shp->xargmin < 0)
		return((pid_t)-1);
	size = shp->gd->lim.arg_max-1024;
	for(ev=envp; cp= *ev; ev++)
		size -= strlen(cp)-1;
	for(av=argv; (cp= *av) && av< &argv[shp->xargmin]; av++)  
		size -= strlen(cp)-1;
	for(av=avlast; cp= *av; av++,nlast++)  
		size -= strlen(cp)-1;
	av =  &argv[shp->xargmin];
	if(!spawn)
		job_clear();
	shp->exitval = 0;
	while(av<avlast)
	{
		for(xv=av,left=size; left>0 && av<avlast;)
			left -= strlen(*av++)+1;
		/* leave at least two for last */
		if(left<0 && (avlast-av)<2)
			av--;
		if(xv==&argv[shp->xargmin])
		{
			n = nlast*sizeof(char*);
			saveargs = (char**)malloc(n);
			memcpy((void*)saveargs, (void*)av, n);
			memcpy((void*)av,(void*)avlast,n);
		}
		else
		{
			for(n=shp->xargmin; xv < av; xv++)
				argv[n++] = *xv;
			for(xv=avlast; cp=  *xv; xv++)
				argv[n++] = cp;
			argv[n] = 0;
		}
		if(saveargs || av<avlast || (exitval && !spawn))
		{
			if((pid=_spawnveg(shp,path,argv,envp,0)) < 0)
				return(-1);
			job_post(shp,pid,0);
			job_wait(pid);
			if(shp->exitval>exitval)
				exitval = shp->exitval;
			if(saveargs)
			{
				memcpy((void*)av,saveargs,n);
				free((void*)saveargs);
				saveargs = 0;
			}
		}
		else if(spawn && !sh_isoption(SH_PFSH))
		{
			shp->xargexit = exitval;
			if(saveargs)
				free((void*)saveargs);
			return(_spawnveg(shp,path,argv,envp,spawn>>1));
		}
		else
		{
			if(saveargs)
Example #5
0
void bq_thr_t::impl_t::fini() {
	poke();
	job_wait(thread);
	thread = 0;
}
Example #6
0
/* execute another program, possibly searching for it first
 * 
 * if the 'exec' argument is set it will never return
 * ----------------------------------------------------------------------- */
int exec_program(char *path, char **argv, int exec, union node *redir) {
  int ret = 0;
  sigset_t nset, oset;
  
  /* if we're gonna execve() a program and 'exec' isn't 
     set or we aren't in the root shell environment we
     have to fork() so we can return */
  if(!exec || sh->parent) {
    pid_t pid;
    struct fdstack io;
    unsigned int n;

    fdstack_push(&io);

    /* buffered fds which have not a real effective file descriptor,
       like here-docs which are read from strallocs and command
       expansions, which write to strallocs can't be shared across
       different process spaces, so we have to establish pipes */
    if((n = fdstack_npipes(FD_HERE|FD_SUBST)))
      fdstack_pipe(n, fdstack_alloc(n));

    /* block child and interrupt signal, so we won't terminate ourselves
       when the child does */
    /*
    sigemptyset(&nset);
    sigaddset(&nset, SIGINT);

#ifdef SIGCHLD
    sigaddset(&nset, SIGCHLD);
#endif
    sigemptyset(&oset);
    sigprocmask(SIG_BLOCK, &nset, &oset);
*/
    sig_block();

    /* in the parent wait for the child to finish and then return 
       or exit, according to the 'exec' argument */
    if((pid = fork())) {
      int status = 1;

      /* this will close child ends of the pipes and read data from the parent end :) */
      fdstack_pop(&io);
      fdstack_data();

      
      job_wait(NULL, pid, &status, 0);
      job_status(pid, status);

      ret = WEXITSTATUS(status);

#ifndef __MINGW32__
      sigprocmask(SIG_SETMASK, &oset, NULL);
#endif
      
      /* exit if 'exec' is set, otherwise return */
      if(exec) sh_exit(ret);
      return ret;
    }

    /* ...in the child we always exit */
    sh_forked();
  }

  fdtable_exec();
  fdstack_flatten();

  /* when there is a path then we gotta execute a command,
     otherwise we exit/return immediately */
  if(path) {
    /* export environment */
    char **envp;
    unsigned long envn = var_count(V_EXPORT) + 1;
    envp = var_export(alloca(envn * sizeof(char *)));

    /* try to execute the program */
    execve(path, argv, envp);

    /* execve() returned so it failed, we're gonna map 
       the error code to the appropriate POSIX errors */
    ret = exec_error();

    /* yield an error message */
    sh_error(path);
  }

  /* we never return at this point! */
  exit(ret);
}
Example #7
0
/* evaluate a pipeline (3.9.2)
 * ----------------------------------------------------------------------- */
int eval_pipeline(struct eval *e, struct npipe *npipe) {
  struct job *job;
  union node *node;
  struct fdstack st;
  unsigned int n;
  int pid = 0;
  int prevfd = -1;
  int status = -1;

/*  job = (e->flags & E_JCTL) ? job_new(npipe->ncmd) : NULL;*/
  job = job_new(npipe->ncmd);
  
  if(job == NULL) {
    buffer_puts(fd_err->w, "no job control");
    buffer_putnlflush(fd_err->w);
  }
  
  
  for(node = npipe->cmds; node; node = node->list.next) {
    fdstack_push(&st);
    
    /* if there was a previous command we read input from pipe */
    if(prevfd >= 0) {
      struct fd *in;
      
      fd_alloca(in);
      fd_push(in, STDIN_FILENO, FD_READ|FD_PIPE);
      fd_setfd(in, prevfd);
    }
    
    /* if it isn't the last command we have to create a pipe
       to pass output to the next command */
    if(node->list.next) {
      struct fd *out;
      
      fd_alloca(out);
      fd_push(out, STDOUT_FILENO, FD_WRITE|FD_PIPE);
      prevfd = fd_pipe(out);
      
      if(prevfd == -1) {
        close(prevfd);
        sh_error("pipe creation failed");
      }
    }

    if((n = fdstack_npipes(FD_HERE|FD_SUBST)))
      fdstack_pipe(n, fdstack_alloc(n));
    
    pid = job_fork(job, node, npipe->bgnd);
    
    if(!pid) {
      /* no job control for commands inside pipe */
/*      e->mode &= E_JCTL;*/
      
      /* exit after evaluating this subtree */
      exit(eval_tree(e, node, E_EXIT));
    }
    
    fdstack_pop(&st);
    fdstack_data();
  }
  
  if(!npipe->bgnd) {
    job_wait(job, 0, &status, 0);
  }

/*  if(job)
    shell_free(job);*/
 
	return WEXITSTATUS(status);
}