struct cmd*
parseexec(char **ps, char *es)
{
  char *q, *eq;
  int tok, argc;
  struct execcmd *cmd;
  struct cmd *ret;
  
  ret = execcmd();
  cmd = (struct execcmd*)ret;

  argc = 0;
  ret = parseredirs(ret, ps, es);
  while(!peek(ps, es, "|")){
    if((tok=gettoken(ps, es, &q, &eq)) == 0)
      break;
    if(tok != 'a') {
      fprintf(stderr, "syntax error\n");
      exit(-1);
    }
    cmd->argv[argc] = mkcopy(q, eq);
    argc++;
    if(argc >= MAXARGS) {
      fprintf(stderr, "too many args\n");
      exit(-1);
    }
    ret = parseredirs(ret, ps, es);
  }
  cmd->argv[argc] = 0;
  return ret;
}
示例#2
0
文件: sh.c 项目: Sunella/xv6
struct cmd*
parseexec(char **ps, char *es)
{
  char *q, *eq;
  int tok, argc;
  struct execcmd *cmd;
  struct cmd *ret;
  
  if(peek(ps, es, "("))
    return parseblock(ps, es);

  ret = execcmd();
  cmd = (struct execcmd*)ret;

  argc = 0;
  ret = parseredirs(ret, ps, es);
  while(!peek(ps, es, "|)&;")){
    if((tok=gettoken(ps, es, &q, &eq)) == 0)
      break;
    if(tok != 'a')
      panic("syntax");
    cmd->argv[argc] = q;
    cmd->eargv[argc] = eq;
    argc++;
    if(argc >= MAXARGS)
      panic("too many args");
    ret = parseredirs(ret, ps, es);
  }
  cmd->argv[argc] = 0;
  cmd->eargv[argc] = 0;
  return ret;
}
示例#3
0
static void clear_screen(void)
{  char *argv[2];

   argv[0] = "clear";
   argv[1] = NULL;
   execcmd( argv );
}
示例#4
0
文件: vm.c 项目: graue/intp
s v execwd(t word *wd)
{
	if (wd->bltn)
		wd->meat.fun();
	l
	{
		cmd *cd;
		for (cd = wd->meat.cmds; cd->ctyp != CMDEND; cd++)
			execcmd(cd, cd[1].ctyp == CMDEND);
	}
}
示例#5
0
文件: sckif.c 项目: pioto/shell-fm
void sckif(int timeout, int sck) {

	/* If the given socket is -1, try both sockets, unix and tcp. */
	if(sck == -1) {
		if(stcpsck != -1)
			sckif(timeout, stcpsck);

		if(sunixsck != -1)
			sckif(timeout, sunixsck);

		return;
	}

	signal(SIGPIPE, SIG_IGN);

	if(waitread(sck, timeout, 0)) {
		struct sockaddr client;
		socklen_t scksize = sizeof(struct sockaddr);

		int csck = accept(sck, & client, & scksize);

		if(-1 != csck) {
			if(waitread(csck, 0, 100000)) {
				FILE * fd = fdopen(csck, "r");

				if(fd) {
					char * line = NULL, * ptr = NULL, reply[REPLYBUFSIZE];
					unsigned size = 0;

					getln(& line, & size, fd);

					if(line && size > 0 && !ferror(fd)) {
						if((ptr = strchr(line, 13)) || (ptr = strchr(line, 10)))
							* ptr = 0;

						execcmd(line, reply);
					}

					if(line)
						free(line);

					if(strlen(reply)) {
						write(csck, reply, strlen(reply));
					}

					fclose(fd);
				}
			}

			shutdown(csck, SHUT_RDWR);
			close(csck);
		}
	}
}
示例#6
0
/* terminal mode */
void terminal(void)
{
	for (;;) {
		printf("%s", prompt);

		getcmd();

		/* execute a user command */
		if (cmd_buf[0])
			execcmd();
	}
}
示例#7
0
static void
set_portsdir(struct options_t *opts)
{
	char		*cmd = "make";
	char *const	args[] = {cmd,
		"-f", DATADIR "/Makefile", "-V", "PORTSDIR", NULL};

	execcmd(cmd, args, _set_portsdir, opts);

	if (opts->portsdir[0] == '\0')
		opts->portsdir = "/usr/ports";
}
示例#8
0
void handle_client(int client_socket) {
	static FILE * fd = NULL;
	int disconnect = 0;

	if (!fd)
		fd = fdopen(client_socket, "rw");

	signal(SIGPIPE, SIG_IGN);

	if(fd != NULL && !feof(fd)) {
		debug("client socket is ok and readable: %i\n", client_socket);
		char line[BUFSIZE];

		if(fgets(line, sizeof(line), fd) == NULL) {
			disconnect = 1;
		}
		else {
			if(!ferror(fd)) {
				unsigned chunks, i;
				char ** lines = split(line, "\n", & chunks);

				for(i = 0; i < chunks && !disconnect; ++i) {
					char reply[BUFSIZE] = { 0, };
					debug("client message: <%s>\n", lines[i]);

					disconnect = execcmd(lines[i], reply);

					if(strlen(reply)) {
						strncat(reply, "\n", BUFSIZE - strlen(reply));
						write(client_socket, reply, strlen(reply));
					}
				}
			}

			else {
				debug("fd error: %i\n", ferror(fd));
				disconnect = 1;
			}

		}
	}

	if(disconnect) {
		debug("removing client\n");
		fshutdown(& fd);
		remove_handle(client_socket);
	}
}
示例#9
0
int main() {
  struct cmd_result *result;
  struct ports_table *table;
  int port;
  int i;
  int sockid;
  int ires;

  table = init_ports_table("/opt/pyrame/ports.txt");
  if (table->names == NULL || table->values == NULL) { return -1; }
  port = get_port("TEST_PORT",table);
  if (port == -1) {
    printf("Error getting port number\n");
    return -1;
  }
  free_ports_table(table);

// SENDCMD
  result = sendcmd("localhost",port,"twoargs_test","arg1","arg2","end");
  printf("sendcmd: retcode=%d res=%s\n",result->retcode,result->str);
  if (result->retcode==1) {
    ires=0;
  } else {
    ires=1;
  }
  
  //free the result
  free_cmd_result(result);

// EXECCMD
  sockid = open_socket("localhost",port);
  result = execcmd(sockid,"twoargs_test","arg1","arg2","end");
  close(sockid);
  printf("execcmd: retcode=%d res=%s\n",result->retcode,result->str);
  if (result->retcode==1) {
    ires=0|ires;
  } else {
    ires=1;
  }

  //free the result
  free_cmd_result(result);

  close(sockid);
  return ires;
}
示例#10
0
int main(void)
{
	int pid;
	char *argv[MAX_ARG];
	char buf[100];

	printf("\n\n\rWelcome To FireKylin 0.1 !\n\n\r");
	printf("More info:http://firekylin.freekj.cn\n\n\r");

	while (1) {
		printf("%s", ps1);
		if (get_cmd(buf)) {
			parcmd(buf, argv);
			execcmd(argv);
		}
	}
}
示例#11
0
文件: sh.c 项目: xinpengliu/firekylin
int main(void)
{
	char *argv[MAX_ARG];
	int argc;
	char buf[100];

	printf("\n\rWelcome To FireKylin 0.1 !\n\r");
	printf("More info:http://bbs.firekylin.cc\n\r");

	while (1) {

		printf("%s", ps1);
		if (get_cmd(buf)) {
			argc = parcmd(buf, argv);
			execcmd(argc, argv);
		}
	}
}
示例#12
0
文件: builtins.c 项目: larus/jamplus
LIST *
builtin_shell(
	PARSE	*parse,
	LOL	*args,
	int	*jmp )
{
    LIST *l = lol_get( args, 0 );
    LIST *shell = var_get( "JAMSHELL" );	/* shell is per-target */

    LIST *output = L0;

    exec_init();
    for( ; l; l = list_next( l ) ) {
        execcmd( l->string, shell_done, &output, shell, 1 );
	execwait();
    }
    exec_done();

    return output;
}
示例#13
0
void			ft_display(char *buf, int sock)
{
	int		ret;
	int		n;

	ft_bzero(buf, 1024);
	ft_putstr("\x1B[31mft_p> \x1B[0m");
	ret = read(0, buf, 1024);
	buf[ret] = '\0';
	if ((n = send(sock, buf, ft_strlen(buf), 0)) < 0)
		error_display("ERROR: send()");
	else if (n > 1)
	{
		if (ft_strncmp(buf, "put", 3) == 0
			|| ft_strncmp(buf, "get", 3) == 0
			|| ft_strncmp(buf, "help", 4) == 0)
			execcmd(buf, sock);
		else
			ft_display_norme(n, sock, buf);
	}
}
示例#14
0
int main() {

	// install signal handler
	struct sigaction sa;
	sa.sa_handler = sig_handler;
	sigemptyset(&sa.sa_mask);
	int sig;
	for(sig = 0; sig < 32; sig++) {
		if(sig != SIGQUIT)				// allow SIGQUIT to exit as expected
			sigaction(sig, &sa, NULL);
	}
	
	// prompt and get input
	printf("%s", SHELL_PROMPT);
	fflush(stdout);

	int r;
	int const buffSize = 64;
	char buff[buffSize];
	while( (r = read(fileno(stdin), buff, buffSize)) > 0 || interrupted ) {
		
		if(r > 1 && !interrupted) {
			// replace line termination with a null termination
			char *newline = strchr( buff, '\n' );
			if ( newline ) *newline = '\0';
		
			recordcmd(buff, r);
			execcmd(buff);
		}

		interrupted = 0;
		printf("%s", SHELL_PROMPT);
		fflush(stdout);
	}

	cleanup();

	return 0;
}
示例#15
0
static void		ft_display_norme(int n, int sock, char *buf)
{
	int		error;

	error = 0;
	while ((n = recv(sock, buf, 1023, 0)) > 1)
	{
		if (n < 0)
			break ;
		buf[n] = '\0';
		ft_printf("%s\n", buf);
		if (ft_strcmp(buf, "quit") == 0)
			execcmd(buf, sock);
		if (ft_strncmp(buf, "ERROR", 5) == 0)
			error++;
		ft_bzero(buf, 1024);
	}
	if (n < 0)
		error_display("ERROR: recv()");
	if (error == 0)
	{
		ft_putendl("SUCCESS");
	}
}
示例#16
0
int GetIdentPort(pid_t childPid)
{
  string lsof = StringFormat::Fmt("lsof -p %d -a -i 4 -F n", (int)childPid);
  string result = execcmd(lsof.c_str());

  // Parse the result expecting:
  // p<PID>
  // n*:<PORT>

  const size_t len = result.length();
  bool found = false;
  if(result[0] == 'p')
  {
    size_t i = 1;
    for(; i < len; i++)
    {
      if(result[i] < '0' || result[i] > '9')
        break;
    }
    result[i++] = 0;

    if(isNewline(result[i]))
      i++;

    const int pid = std::stoi(&result[1]);
    if(pid == (int)childPid)
    {
      while(i < len)
      {
        if(result[i] == 'n')
        {
          char *portStr = NULL;
          for(; i < len; i++)
          {
            if(result[i] == ':')
            {
              portStr = &result[i + 1];
            }
            if(isNewline(result[i]))
            {
              result[i++] = 0;
              if(i < len && isNewline(result[i]))
                result[i++] = 0;
              break;
            }
          }

          const int port = std::stoi(portStr);
          if(port >= RenderDoc_FirstTargetControlPort && port <= RenderDoc_LastTargetControlPort)
          {
            return port;
          }

          // continue on to next port
        }
        else
        {
          RDCERR("Malformed line - expected 'n':\n%s", &result[i]);
          break;
        }
      }
    }
    else
    {
      RDCERR("pid from lsof output doesn't match childPid");
    }
  }
  else
  {
    RDCERR("lsof output doesn't begin with p<PID>:\n%s", &result[0]);
  }

  return 0;
}
示例#17
0
文件: make1.c 项目: Albermg7/boost
static void
make1c( state *pState )
{
	CMD	*cmd = (CMD *)pState->t->cmds;

	/* If there are (more) commands to run to build this target */
	/* (and we haven't hit an error running earlier comands) we */
	/* launch the command with execcmd(). */
	
	/* If there are no more commands to run, we collect the status */
	/* from all the actions then report our completion to all the */
	/* parents. */

	if( cmd && pState->t->status == EXEC_CMD_OK )
	{
		if( DEBUG_MAKEQ || 
            ! ( cmd->rule->actions->flags & RULE_QUIETLY ) && DEBUG_MAKE)
	    {
		printf( "%s ", cmd->rule->name );
		list_print( lol_get( &cmd->args, 0 ) );
		printf( "\n" );
	    }

	    if( DEBUG_EXEC )
		printf( "%s\n", cmd->buf );

	    if( globs.cmdout )
		fprintf( globs.cmdout, "%s", cmd->buf );

	    if( globs.noexec )
	    {
			pState->curstate = T_STATE_MAKE1D;
			pState->status = EXEC_CMD_OK;
	    } 
	    else
	    {
			TARGET *t = pState->t;
			fflush( stdout );

			pop_state(&state_stack); /* pop state first because execcmd could push state */
			execcmd( cmd->buf, make_closure, t, cmd->shell );
	    }
	}
	else
	{
	    TARGETS	*c;
	    ACTIONS	*actions;

	    /* Collect status from actions, and distribute it as well */

	    for( actions = pState->t->actions; actions; actions = actions->next )
		if( actions->action->status > pState->t->status )
		    pState->t->status = actions->action->status;

	    for( actions = pState->t->actions; actions; actions = actions->next )
		if( pState->t->status > actions->action->status )
		    actions->action->status = pState->t->status;

	    /* Tally success/failure for those we tried to update. */

	    if( pState->t->progress == T_MAKE_RUNNING )
		switch( pState->t->status )
	    {
	    case EXEC_CMD_OK:
		++counts->made;
		break;
	    case EXEC_CMD_FAIL:
		++counts->failed;
		break;
	    }

	    /* Tell parents dependent has been built */
		{
			stack temp_stack = { NULL };
			TARGET *t = pState->t;            
            TARGET* additional_includes = NULL;

			t->progress = T_MAKE_DONE;

            /* Target was updated. Rescan dependencies. */
            if (t->fate >= T_FATE_MISSING &&
                t->status == EXEC_CMD_OK &&
                !t->rescanned) {

                TARGET *target_to_rescan = t;
                SETTINGS *s;               

                target_to_rescan->rescanned = 1;

                if (target_to_rescan->flags & T_FLAG_INTERNAL) {
                    target_to_rescan = t->original_target;                    
                }

                /* Clean current includes */
                if (target_to_rescan->includes) {
                    target_to_rescan->includes = 0;
                }

                s = copysettings( target_to_rescan->settings );
                pushsettings( s );
                headers(target_to_rescan);
                popsettings( s );
                freesettings( s );

                if (target_to_rescan->includes) {
                    target_to_rescan->includes->rescanned = 1;
                    /* Tricky. The parents were already processed, but they
                       did not seen the internal node, because it was just 
                       created. We need to make the calls to make1a that would
                       have been done by parents here, and also make sure all
                       unprocessed parents will pick up the includes. We must
                       make sure processing of the additional make1a invocations
                       is done before make1b which means this target is built,
                       otherwise the parent will be considered built before this
                       make1a processing is even started.
                    */
                    make0(target_to_rescan->includes, target_to_rescan->parents->target, 0, 0, 0);
                    for( c = target_to_rescan->parents; c; c = c->next) {
                        c->target->depends = targetentry( c->target->depends, 
                                                          target_to_rescan->includes );
                    }
                    /* Will be processed below. */
                    additional_includes = target_to_rescan->includes;
                }                
            }

            if (additional_includes)
                for ( c = t->parents; c; c = c->next ) {                            
                    push_state(&temp_stack, additional_includes, c->target, T_STATE_MAKE1A);
                    
                }

			for( c = t->parents; c; c = c->next ) {
				push_state(&temp_stack, c->target, NULL, T_STATE_MAKE1B);
            }
             


#ifdef OPT_SEMAPHORE
	    /* If there is a semaphore, its now free */
	    if( t->semaphore )
	    {
		assert( t->semaphore->asynccnt == 1 );
		--(t->semaphore->asynccnt);

		if( DEBUG_EXECCMD )
		    printf( "SEM: %s is now free\n", t->semaphore->name);

		/* If anything is waiting, notify the next target. There's no
            point in notifying all waiting targets, since they'll be
            serialized again. */
		if( t->semaphore->parents )
		{
		    TARGETS *first = t->semaphore->parents;
		    if( first->next )
			first->next->tail = first->tail;
		    t->semaphore->parents = first->next;

		    if( DEBUG_EXECCMD )
			printf( "SEM: placing %s on stack\n", first->target->name);
            push_state(&temp_stack, first->target, NULL, T_STATE_MAKE1B);
		    free( first );
		}
	    }
#endif

		
			/* must pop state before pushing any more */
			pop_state(&state_stack);
		
			/* using stacks reverses the order of execution. Reverse it back */
			push_stack_on_stack(&state_stack, &temp_stack);

		}
	}
}
示例#18
0
void listener_loop(void) 
{
  int i,n,addr;
  unsigned int sock_size;
  fd_set fds;
  struct timeval tv;
  char cmd[1024];
  struct sockaddr_in sa;
#ifdef __CYGWIN__
  WORD verreq;
  WSADATA wsadata;
#endif

  /* catch broken pipe ! */

#ifdef __SVR4 
  sigignore(SIGPIPE);
  sigset(SIGCHLD,cleanchild);
#else
  signal(SIGPIPE,SIG_IGN);
  signal(SIGCHLD,cleanchild);
#endif

  /*
  myip=getmyip();
  if (myip==NULL) {
    printf("Determining localhost-IP failed.\n");
    exit(1);
  }

#ifdef DEBUG
  printf("My IP is: %d.%d.%d.%d\n",
	 myip[0],myip[1],myip[2],myip[3]);
#endif
  */

  /* server init */

#ifdef __CYGWIN__
  verreq=MAKEWORD(1,1);
  i=WSAStartup(verreq,&wsadata);
  if (i!=0) {
    printf("Error: winsock-lib couldn't be initialized.");
  }
#endif

  if (!daemonmode)
    printf("Starting server ... ");
  if ((server_socket=socket(PF_INET,SOCK_STREAM,0))==INVALID_SOCKET) {
#ifdef __CYGWIN__
    i=WSAGetLastError();
#else
    i=errno;
#endif
    printf("Error: could not create server socket (%d).\n",i);
    exit(1);
  }

  i=1;
  if (setsockopt(server_socket,SOL_SOCKET,SO_REUSEADDR,(void *)&i,sizeof(i))<0)
    printf("setsockopt failed.\n");
  
  sock_size=sizeof(struct sockaddr_in);
  memset(&sa,0,sock_size);
  
  sa.sin_family=PF_INET;
  sa.sin_port=htons(serverport);
  addr=INADDR_ANY;
  memcpy(&sa.sin_addr.s_addr,&addr,sizeof(int));
  
  if (bind(server_socket,(struct sockaddr *)&sa,sock_size)<0) {
    printf("Error: bind failed.\n");
    printf("       port %i already in use ?\n",serverport);
    exit(1);
  }

  if (listen(server_socket,5)<0) {
    printf("Error: listen failed.\n");
    exit(1);
  }

  if (!daemonmode) {
    printf("OK\n\n");
    out_prompt();
  }

#ifdef DEBUG
  printf("Listening ...\n");
#endif

  serverstop=0;
  while (!serverstop) {
    FD_ZERO(&fds);
    if (!daemonmode) FD_SET(1,&fds);
    FD_SET(server_socket,&fds);
    for (i=0;i<maxusers;i++)
      if (pchild[i]->sock)
	FD_SET(pchild[i]->sock,&fds);

    /*    memset(&tv,0,sizeof(struct timeval)); */
    tv.tv_sec=REACTION_TIME;tv.tv_usec=0L;
    n=select(32+maxusers*4,&fds,NULL,NULL,&tv);

    if (n<0) {
      if (errno==EINTR) continue;
      if (
#ifdef __CYGWIN__
	  1) {
	i=WSAGetLastError();
#else
	!daemonmode) {
	i=errno;
#endif
	fprintf(stderr,"*** Fehler: select (ret: %d,errno=%d).\n",n,i);
      }
      exit(1);
    }

    if (!daemonmode)
      if (FD_ISSET(1,&fds)) {
	i=read(1,cmd,sizeof(cmd));
	if (i<1) continue;
	cmd[i-1]=0;
	execcmd(cmd);
	if (serverstop) break;
	out_prompt();
      }

    if (FD_ISSET(server_socket,&fds)) init_login();

    for (i=0;i<maxusers;i++) {
      if (pchild[i]->sock) {
	if (FD_ISSET(pchild[i]->sock,&fds))
	  serve_child(i);
      }
    }

    check_timeouts();
  }

  close(server_socket);
#ifdef __CYGWIN__
  WSACleanup();
#endif

  if (!daemonmode)
    printf("Server stopped.\n");
}
示例#19
0
文件: make1.c 项目: Karlan88/xray
static void
make1c( state *pState )
{
	CMD	*cmd = (CMD *)pState->t->cmds;

	/* If there are (more) commands to run to build this target */
	/* (and we haven't hit an error running earlier comands) we */
	/* launch the command with execcmd(). */
	
	/* If there are no more commands to run, we collect the status */
	/* from all the actions then report our completion to all the */
	/* parents. */

	if( cmd && pState->t->status == EXEC_CMD_OK )
	{
		if( DEBUG_MAKEQ || 
            ! ( cmd->rule->actions->flags & RULE_QUIETLY ) && DEBUG_MAKE)
	    {
		printf( "%s ", cmd->rule->name );
		list_print( lol_get( &cmd->args, 0 ) );
		printf( "\n" );
	    }

	    if( DEBUG_EXEC )
		printf( "%s\n", cmd->buf );

	    if( globs.cmdout )
		fprintf( globs.cmdout, "%s", cmd->buf );

	    if( globs.noexec )
	    {
			pState->curstate = T_STATE_MAKE1D;
			pState->status = EXEC_CMD_OK;
	    } 
	    else
	    {
			TARGET *t = pState->t;
			fflush( stdout );

			pop_state(&state_stack); /* pop state first because execcmd could push state */
			execcmd( cmd->buf, make_closure, t, cmd->shell );
	    }
	}
	else
	{
	    TARGETS	*c;
	    ACTIONS	*actions;

	    /* Collect status from actions, and distribute it as well */

	    for( actions = pState->t->actions; actions; actions = actions->next )
		if( actions->action->status > pState->t->status )
		    pState->t->status = actions->action->status;

	    for( actions = pState->t->actions; actions; actions = actions->next )
		if( pState->t->status > actions->action->status )
		    actions->action->status = pState->t->status;

	    /* Tally success/failure for those we tried to update. */

	    if( pState->t->progress == T_MAKE_RUNNING )
		switch( pState->t->status )
	    {
	    case EXEC_CMD_OK:
		++counts->made;
		break;
	    case EXEC_CMD_FAIL:
		++counts->failed;
		break;
	    }

	    /* Tell parents dependent has been built */
		{
			stack temp_stack = { NULL };
			TARGET *t = pState->t;

			t->progress = T_MAKE_DONE;

			for( c = t->parents; c; c = c->next )
				push_state(&temp_stack, c->target, NULL, T_STATE_MAKE1B);

#ifdef OPT_SEMAPHORE
	    /* If there is a semaphore, its now free */
	    if( t->semaphore )
	    {
		assert( t->semaphore->asynccnt == 1 );
		--(t->semaphore->asynccnt);

		if( DEBUG_EXECCMD )
		    printf( "SEM: %s is now free\n", t->semaphore->name);

		/* If anything is waiting, notify the next target. There's no
            point in notifying all waiting targets, since they'll be
            serialized again. */
		if( t->semaphore->parents )
		{
		    TARGETS *first = t->semaphore->parents;
		    if( first->next )
			first->next->tail = first->tail;
		    t->semaphore->parents = first->next;

		    if( DEBUG_EXECCMD )
			printf( "SEM: placing %s on stack\n", first->target->name);
            push_state(&temp_stack, first->target, NULL, T_STATE_MAKE1B);
		    free( first );
		}
	    }
#endif

		
			/* must pop state before pushing any more */
			pop_state(&state_stack);
		
			/* using stacks reverses the order of execution. Reverse it back */
			push_stack_on_stack(&state_stack, &temp_stack);

		}
	}
}
示例#20
0
文件: make1.c 项目: 0xb1dd1e/jamplus
static void
make1c( TARGET *t )
{
	CMD	*cmd = (CMD *)t->cmds;

#ifdef OPT_DEBUG_MAKE1_LOG_EXT
	if (DEBUG_MAKE1) {
	    printf( "make1c\t--\t%s (status %d)\n" ,
		    t->name, t->status );
	}
#endif
	/* If there are (more) commands to run to build this target */
	/* (and we haven't hit an error running earlier comands) we */
	/* launch the command with execcmd(). */

	/* If there are no more commands to run, we collect the status */
	/* from all the actions then report our completion to all the */
	/* parents. */

	if( cmd && t->status == EXEC_CMD_OK )
	{
#ifdef OPT_DEBUG_MAKE1_LOG_EXT
	    if (DEBUG_MAKE1) {
		printf( "make1c\t--\t%s (more to do)\n" ,
			t->name );
	    }
#endif
#ifndef OPT_SERIAL_OUTPUT_EXT
	    if( DEBUG_MAKE )
		if( DEBUG_MAKEQ || ! ( cmd->rule->flags & RULE_QUIETLY ) )
	    {
#ifdef OPT_PERCENT_DONE_EXT
		/* CWM - added '@' and %done to front of output */
		int done = counts->skipped + counts->failed + counts->made;
		float percent = (done * 99.0f) / globs.updating;
		printf( "@ %2.0f%% %s ", percent, cmd->rule->name );
#else
		/* CWM - added '@' to front of output */
		printf( "@ %s ", cmd->rule->name );
#endif
#ifdef OPT_DEBUG_MAKE_PRINT_TARGET_NAME
		if (globs.printtarget) {
		    printf("%s ", t->name);
		} else {
		    list_print( lol_get( &cmd->args, 0 ) );
		}
#else
		list_print( lol_get( &cmd->args, 0 ) );
#endif
		printf( "\n" );
	    }

	    if( DEBUG_EXEC )
		printf( "%s\n", buffer_ptr( &cmd->commandbuff ) );
#endif /* !OPT_SERIAL_OUTPUT_EXT */
#ifdef OPT_RESPONSE_FILES
	    if (DEBUG_EXEC)
	    {
		printResponseFiles(cmd);
	    }
#endif

	    if( globs.cmdout )
		fprintf( globs.cmdout, "%s", buffer_ptr(&cmd->commandbuff) );

#ifdef OPT_BUILTIN_LUA_SUPPORT_EXT
	    if ( cmd->rule->flags & RULE_LUA )
	    {
		execlua( cmd->luastring, make1d, t );
	    }
	    else
#endif
#ifdef OPT_ACTIONS_DUMP_TEXT_EXT
	    if (cmd->rule->flags & RULE_WRITEFILE)
	    {
#ifdef OPT_SERIAL_OUTPUT_EXT
		make1d( 0, t, EXEC_CMD_OK );
#else
		make1d( t, EXEC_CMD_OK );
#endif
	    }
	    else
#endif
	    if( globs.noexec )
	    {
#ifdef OPT_SERIAL_OUTPUT_EXT
		make1d( 0, t, EXEC_CMD_OK );
#else
		make1d( t, EXEC_CMD_OK );
#endif
	    }
	    else
	    {
		fflush( stdout );
		execcmd( buffer_ptr(&cmd->commandbuff), make1d, t, cmd->shell, (cmd->rule->flags & RULE_SCREENOUTPUT) == 0 );
	    }
	}
	else
	{
	    TARGETS	*c;
	    ACTIONS	*actions;

#ifdef OPT_DEBUG_MAKE1_LOG_EXT
	    if (DEBUG_MAKE1) {
		printf( "make1c\t--\t%s (no more to do)\n" ,
			t->name );
	    }
#endif
	    /* Collect status from actions, and distribute it as well */

#ifdef OPT_MULTIPASS_EXT
		{
			int previousPassStatus = -1;
			int currentPassStatus = -1;
			for( actions = t->actions; actions; actions = actions->next )
				if( actions->action->pass < actionpass  &&  actions->action->status > previousPassStatus )
					previousPassStatus = actions->action->status;

			for( actions = t->actions; actions; actions = actions->next )
				if( actions->action->pass == actionpass  &&  actions->action->status > currentPassStatus )
					currentPassStatus = actions->action->status;

			if (currentPassStatus == -1  &&  previousPassStatus != -1)
				t->status = previousPassStatus;
			else if (currentPassStatus != -1  &&  currentPassStatus > t->status)
				t->status = currentPassStatus;

		    for( actions = t->actions; actions; actions = actions->next )
				if( actions->action->pass == actionpass  &&  t->status > actions->action->status )
				    actions->action->status = t->status;
		}
#else
	    for( actions = t->actions; actions; actions = actions->next )
		if( actions->action->status > t->status )
		    t->status = actions->action->status;

	    for( actions = t->actions; actions; actions = actions->next )
		if( t->status > actions->action->status )
		    actions->action->status = t->status;

#endif

#ifdef OPT_MULTIPASS_EXT
		if ( t->fate == T_FATE_MISSING  &&  !( t->flags & T_FLAG_NOCARE )  &&  !t->actions  &&  queuedjamfiles )
		{
			t->status = EXEC_CMD_NEXTPASS;
		}
#endif

	    /* Tally success/failure for those we tried to update. */

	    if( t->progress == T_MAKE_RUNNING )
		switch( t->status )
	    {
	    case EXEC_CMD_OK:
		++counts->made;
		break;
	    case EXEC_CMD_FAIL:
		++counts->failed;
		break;
	    }

	    /* Tell parents dependent has been built */

	    t->progress = T_MAKE_DONE;

#ifdef OPT_BUILTIN_MD5CACHE_EXT
	    /* Update the file cache. */
	    if ( t->flags & T_FLAG_USECOMMANDLINE )
		hcache_finalizerulemd5sum( t );
#endif

#ifdef OPT_SEMAPHORE
	    /* If there is a semaphore, its now free */
	    if( t->semaphore )
	    {
		--(t->semaphore->asynccnt);

		if( DEBUG_EXECCMD )
		    printf( "SEM: %s is now free\n", t->semaphore->name);

		/* If anything is waiting, notify the next target */
		if( t->semaphore->parents )
		{
		    TARGETS *first = t->semaphore->parents;
		    if( first->next )
			first->next->tail = first->tail;
		    t->semaphore->parents = first->next;

		    if( DEBUG_EXECCMD )
			printf( "SEM: now launching %s\n", first->target->name);
		    make1b( first->target );
#ifndef OPT_IMPROVED_MEMUSE_EXT
		    free( first );
#endif
		}
	    }
#endif
	    for( c = t->parents; c; c = c->next )
		make1b( c->target );
	}
}