コード例 #1
0
ファイル: build_action.c プロジェクト: gitter-badger/arkade
void build_action(vector_t *arguments) {
    load_t *loader = load_project_config();
    if (!loader) {
        printf("error: are you sure the current directory contains an Ark project?\n");
        return;
    }

    table_t *package = get_table(loader, "package");

    // check for a custom build method and use it if it
    // exists.
    char *build_method = get_string_contents("build", package);
    if (build_method) {
        // note we're using system calls, this isn't a good idea
        // at all, we're also just throwing in some random variable
        // that should probably be sanitized?
        // same applies for the one below
        exec_process(build_method);
        sdsfree(build_method);
    }
    else {
        exec_process("ark build src/*.ark");
    }

    destroy_loader(loader);
}
コード例 #2
0
ファイル: fetch_action.c プロジェクト: gitter-badger/arkade
int dependencies_iterate(any_t data, any_t item_p) {
	bare_key_t *item = item_p;

	array_t *depedency_data = item->value->array_expr;

	char *url = get_array_value(0, depedency_data);
    char *version = get_array_value(1, depedency_data);
    char *folder = item->name;

    if (chdir("_deps") == -1) {
        printf("error: are you in the Ark project directory?\n");
        return -1;
    }

    DIR *dir = opendir(folder);
    if (dir) {
        if(chdir(folder) == 0) {
            FILE *fp;
            char output[128];
            fp = popen("git tag", "r");
            if (fp == NULL) {
                // TODO better error handling
                printf("screwed up with git tag checking.");
                return -2;
            }
            while (fgets(output, sizeof(output) - 1, fp) != NULL) {
                if (strcmp(version, output)) {
                    // since we know that the version is the same
                    // just update the repo with a git pull
                    printf("git pulling...\n");
                    char *proc = sdsnew("git pull");
                    exec_process(proc);
                    sdsfree(proc);
                    break;
                }
                // else: we now know that the versions are different
                // TODO check if remote is greater than local
                // and perform operation
            }
            pclose(fp);
            closedir(dir);
            chdir("../");
            return MAP_OK;
        }
    }

    // TODO fix this, for some reason concat
    // crashes and burns if you give it more
    // than 5 arguments, so we concat twice
	char *clone_temp = concat("git clone -b ", version, " --depth 1 ", url, " ");
    char *clone_process = concat(clone_temp, folder);

	exec_process(clone_process);

	sdsfree(clone_process);
    sdsfree(clone_temp);

	return MAP_OK;
}
コード例 #3
0
ファイル: server.c プロジェクト: sjclijie/KB-PM
void server_start_process(process_s *process, int with_log)
{
    int res;
    pid_t pid;

    pid = fork();
    if(pid < 0)
    {
        syslog(LOG_ERR, "cannot fork(), error: %s", strerror(errno));
        syslog(LOG_ERR, "server unexpected exit.");
        unlink(LOCAL_SOCKET_FILE);
        exit(EXIT_FAILURE);
    }
    else if(pid == 0)/*the child process*/
    {
        ignore_signals();
        /*exec the child process.*/
        exec_process(process, &res);
        syslog(LOG_ERR, "%s unexpected exit: %s.", process->app_name, strerror(errno));
        exit(EXIT_FAILURE);
    }
    else/*the parent process*/
    {
        process->pid = pid;
        process->is_running = 1;
        time(&process->start_time);
        if(with_log)
        {
            syslog(LOG_INFO, "Starting %s with pid:%d.",process->app_name, process->pid);
        }
    }
}
コード例 #4
0
ファイル: parser.c プロジェクト: Zethir/42sh
static void		launch_process(t_shell *sh, t_job *job)
{
	t_process	*process;
	int			iofile[2];
	int			pipefd[2];
	int			i;

	process = job->process;
	iofile[0] = 0;
	i = get_num_process(job->process);
	while (job->process)
	{
		if (job->process->next)
		{
			pipe(pipefd);
			iofile[1] = pipefd[1];
		}
		else
			iofile[1] = 1;
		exec_process(sh, job, iofile);
		iofile[0] = pipefd[0];
		job->process = job->process->next;
	}
	job->process = process;
	wait_for_job(sh, job, i);
}
コード例 #5
0
void
file_cleanup(FILE *fp)
{
	char *trafficPath;
	trafficPath = malloc(WFA_BUFF_1K);
	fclose(fp);
	strcpy(trafficPath,"rm -f ");
	strncat(trafficPath,TEMP_FILE_PATH, strlen(TEMP_FILE_PATH));
	exec_process(trafficPath);
	free(trafficPath);
}
コード例 #6
0
ファイル: exec_process.c プロジェクト: Tastyep/42sh
void	cmd_execution(t_cmd *cmd, t_fds *fd, t_sh *shell)
{
  cmd->pid.pid = -1;

  if (cmd->argv != NULL)
    {
      if (is_cmd_a_builtin(cmd, fd, shell, 1) == 0)
        exec_process(cmd, fd, shell, &my_execve);
    }
  close_fds(fd);
}
コード例 #7
0
ファイル: autorestart.c プロジェクト: Toonerz/TTRInjector
int
spawn_process() {
  /* Spawns the child process.  Returns true if the process terminated
     by itself and should be respawned, false if it was explicitly
     killed (or some other error condition exists), and it should not
     respawn any more. */
  pid_t wresult;
  int status;

  child_pid = fork();
  if (child_pid < 0) {
    /* Fork error. */
    perror("fork");
    return 0;
  }

  if (child_pid == 0) {
    /* Child.  Exec the process. */
    fprintf(stderr, "Child pid is %d.\n", getpid());
    exec_process();
    /* Shouldn't get here. */
    exit(1);
  }

  /* Parent.  Wait for the child to terminate, then diagnose the reason. */
  wresult = waitpid(child_pid, &status, 0);
  if (wresult < 0) {
    perror("waitpid");
    return 0;
  }

  /* Now that we've returned from waitpid, clear the child pid number
     so our signal handler doesn't get too confused. */
  child_pid = 0;

  if (WIFSIGNALED(status)) {
    int signal = WTERMSIG(status);
    fprintf(stderr, "\nprocess caught signal %d.\n\n", signal);
    /* A signal exit is a reason to respawn unless the signal is TERM
       or KILL. */
    return !stop_on_terminate || (signal != SIGTERM && signal != SIGKILL);

  } else {
    int exit_status = WEXITSTATUS(status);
    fprintf(stderr, "\nprocess exited with status %d.\n\n", WEXITSTATUS(status));
    /* Normal exit is a reason to respawn if the status indicates failure. */
    return !stop_on_terminate || (exit_status != 0);
  }
}
コード例 #8
0
ファイル: history.c プロジェクト: EPITECH-Bordeaux/42sh
void	builtin_history(t_cmd *cmd, t_fds *fd, t_sh *shell)
{
  if (cmd->argv[1] == NULL)
    {
      exec_process(cmd, fd, shell,  &view_history);
      return ;
    }
  if (cmd->argv[1] != NULL && str_cmp(cmd->argv[1], "-c") == 1)
    {
      clear_history((shell->history));
      shell->history = NULL;
      return ;
    }
  if (cmd->argv[1] != NULL && str_cmp(cmd->argv[1], "-d") == 1 &&
      cmd->argv[2] != NULL)
    {
      rm_history_d(&(shell->history), my_getnbr(cmd->argv[2]));
      return ;
    }
  my_putstr("history: usage: history [-c] [-d offset]\n", 1, -1);
}
コード例 #9
0
ファイル: plainprpl.c プロジェクト: mwarning/plain-prpl
static void plainprpl_close(PurpleConnection *gc)
{
	purple_debug_info("plainprpl", "plainprpl_close\n");

	PurpleAccount *account;
	PurpleBuddy *buddy;
	plain_plugin_state *pstate;
	plain_buddy_state *bstate;
	const char *on_logout;

	/* notify other plainprpl accounts */
	account = purple_connection_get_account(gc);
	pstate = purple_connection_get_protocol_data(gc);

	/* Notifiy all buddies that we are gone */
	GSList *iter = pstate->all_buddies;
	while (iter) {
		buddy = iter->data;
		bstate = purple_buddy_get_protocol_data(buddy);

		PurplePresence *presence = purple_buddy_get_presence(buddy);
		PurpleStatus *status = purple_presence_get_active_status(presence);
		PurpleStatusType *status_type = purple_status_get_type(status);
		PurpleStatusPrimitive status_primitive = purple_status_type_get_primitive(status_type);
		if (bstate && status_primitive == PURPLE_STATUS_AVAILABLE) {
			send_msg(pstate, bstate, "/bye");
		}

		iter = iter->next;
	}

	//remove timers
	purple_timeout_remove(pstate->receive_timer);

	on_logout = purple_account_get_string(account, "on_logout", NULL);
	exec_process(on_logout, NULL, NULL, gc, NULL);

	free_plugin_data(pstate);
}
コード例 #10
0
ファイル: plainprpl.c プロジェクト: mwarning/plain-prpl
static void plainprpl_login(PurpleAccount *account)
{
	PurpleConnection *gc = purple_account_get_connection(account);

	purple_debug_info("plainprpl", "logging in %s\n", account->username);

	purple_connection_update_progress(gc, _("Connecting"), 0, 2);
	purple_connection_update_progress(gc, _("Connected"), 1, 2);
	purple_connection_set_state(gc, PURPLE_CONNECTED);

	/* Setup plugin data */
	plain_plugin_state *pstate = g_new0(plain_plugin_state, 1);

	/* General account data */
	const char *listen_af = purple_account_get_string(account, "listen_af", NULL);
	const char *listen_port = purple_account_get_string(account, "listen_port", NULL);

	//check port
	if (listen_port == NULL || atoi(listen_port) < 1 || atoi(listen_port) >= 65535) {
		listen_port = PLAIN_DEFAULT_PORT_STR;
		purple_account_set_string(account, "listen_port", listen_port);
	}

	//check protocol
	if (listen_af == NULL || (strcmp(listen_af, "ipv4") && strcmp(listen_af, "ipv6"))) {
		listen_af = "ipv4";
		purple_account_set_string(account, "listen_port", listen_af);
	}

	/* Select the address to listen on */
	const char *listen_addr = (strcmp(listen_af, "ipv4") == 0) ? "0.0.0.0" : "::1";
	pstate->sockaf = str_to_af(listen_af);
	pstate->sockfd = net_bind("plainprpl", listen_addr, listen_port, NULL, IPPROTO_UDP, pstate->sockaf);

	if (pstate->sockfd < 0) {
		purple_debug_info("plainprpl", "Failed to bind to %s\n", listen_addr);
		g_free(pstate);
		//TODO: diable plugin
		return;
	} else {
		purple_debug_info("plainprpl", "Bind to %s\n", listen_addr);
	}

	pstate->receive_timer = purple_timeout_add(80, plain_receive, gc);

	purple_connection_set_protocol_data(gc, pstate);

	/* Attach buddy data to each buddy */
	GSList *list = purple_find_buddies(account, NULL);
	purple_debug_info("plainprpl", "Buddies to load: %d\n", g_slist_length(list));

	GSList *iter = list;
	while (iter) {
		PurpleBuddy *buddy = iter->data;
		//purple_debug_info("plainprpl", "#plainprpl_login: attach custom data to buddy: %s\n", buddy->name);
		assert(purple_buddy_get_protocol_data(buddy) == NULL);

		const char *addr_str = purple_blist_node_get_string(PURPLE_BLIST_NODE(buddy), "addr_str");
		if (addr_str != NULL && strlen(addr_str)) {
			add_buddy_sdata(buddy, pstate);
		} else {
			purple_debug_info("plainprpl", "Empty address for buddy: %s\n", buddy->name);
		}

		/* Set offline by default */
		purple_prpl_got_user_status(account, buddy->name, PLAIN_STATUS_OFFLINE, NULL);

		iter = iter->next;
	}
	g_slist_free(list);

	/* Call the on_login script - if it is set */
	const char *on_login = purple_account_get_string(account, "on_login", NULL);
	exec_process(on_login, NULL, NULL, gc, NULL);
}
コード例 #11
0
ファイル: plainprpl.c プロジェクト: mwarning/plain-prpl
/* Ping buddies a ping every 5 minutes if there is no traffic */
void ping_buddies(PurpleConnection *gc, time_t now)
{
	PurpleBuddy *buddy;
	PurpleAccount *account;
	plain_buddy_state *bstate;
	plain_plugin_state *pstate;
	time_t time_next;
	GSList *iter;

	account = purple_connection_get_account(gc);
	pstate = purple_connection_get_protocol_data(gc);

	if(pstate->time_next > now) {
		return;
	}

	time_next = now + (60*5); //max time we wait for another round
	const char *on_lookup = purple_account_get_string(account, "on_lookup", NULL);

	iter = pstate->all_buddies;
	while (iter) {
		buddy = iter->data;
		bstate = purple_buddy_get_protocol_data(buddy);

		//uninitialized buddy
		if(bstate == NULL) {
			purple_debug_info("plainprpl", "Buddy %s has no state set.\n", buddy->name);
			goto next;
		}

		//printf("Do ping_buddies for %s\n", buddy->name);

		int state = bstate->state;
		int state_step = bstate->state_step;
		time_t state_next = bstate->state_next;

		if(state == BUDDY_STATE_RESOLVE) {
			const char *addr_str = purple_blist_node_get_string(PURPLE_BLIST_NODE(buddy), "addr_str");
			if(exec_process(on_lookup, addr_str, on_lookup_handle, gc, buddy) == 0) {
				/* Script was called - wait for answer some other time */
				purple_debug_info("plainprpl", "Lookup by SCRIPT succeded. Start to ping %s\n", str_addr(&bstate->addr));
				state = BUDDY_STATE_PING;
				state_step = 1;
				state_next = now + 1;
			} else if(addr_parse_full(&bstate->addr, addr_str, PLAIN_DEFAULT_PORT_STR, pstate->sockaf) == 0) {
				purple_debug_info("plainprpl", "Lookup by DNS succeded (%s). Start to ping %s\n", addr_str, str_addr(&bstate->addr));
				//switch to ping state
				state = BUDDY_STATE_PING;
				state_step = 1;
				state_next = now + 1;
			} else {
				if(state_step == 0) {
					state_step = 4;
				} else if(state_step < (5*60)) {
					state_step *= 2;
				}

				purple_debug_info("plainprpl", "Resolve failed. Try again in %d seconds.\n", state_step);
				state_next = now + state_step;
			}
		} else if(state == BUDDY_STATE_PING) {
			//send ping
			if(bstate->time_recv < (now - (5*60))) {
				if(state_step < (5*60)) {
					state_step *= 2;
					state_next = now + state_step;

					send_msg(pstate, bstate, "/ping");

					/* Set buddy status to online */
					purple_prpl_got_user_status(account, bstate->name, PLAIN_STATUS_OFFLINE, NULL);
				} else {
					state = BUDDY_STATE_RESOLVE;
					state_step = 1;
					state_next = now + 1;
				}
			} else {
				state_step = 1;
				state_next = now + (5*60);
			}
		} else {
			purple_debug_info("plainprpl", "Invalid state: %d\n", state);
		}

		bstate->state = state;
		bstate->state_step = state_step;
		bstate->state_next = state_next;

		/* Get next time we need to do something here */
		if (state_next < time_next) {
			time_next = state_next;
		}

next:
		iter = iter->next;
	}

	pstate->time_next = time_next;
	purple_debug_info("plainprpl", "Next iteration in %d seconds.\n", (int)(time_next - now));
}
コード例 #12
0
int
exec_process_cnclient (char *buf, char *rwl_client_path, int rwl_wifi_flag)
{
    unsigned int  position;
    char gCmdStr[WFA_CMD_STR_SZ];
    int timeout_count = 30;
    FILE *tmpfd;
    /* Create Process related variables */
    PROCESS_INFORMATION ProcessInfo;
    char Args[WFA_BUFF_512];
    TCHAR pDefaultCMD[WFA_BUFF_512];
    STARTUPINFO StartupInfo;

    if (rwl_wifi_flag) {
        /*The server can be in different channel after association
         *Hence we issue a findserver and then find out if it has
         *been associated to return the right status
         */

        memset(Args, 0, WFA_BUFF_512);
        sprintf(Args, "%s", (const char *)buf);
        memset(&ProcessInfo, 0, sizeof(ProcessInfo));
        memset(&StartupInfo, 0, sizeof(StartupInfo));
        StartupInfo.cb = sizeof(StartupInfo);
        /*  "/C" option - Do the command and EXIT the command processor */
        _tcscpy(pDefaultCMD, _T("cmd.exe /C "));
        _tcscat(pDefaultCMD, Args);
        if(!CreateProcess(NULL,(LPTSTR)pDefaultCMD, NULL,NULL,FALSE,FALSE,NULL,NULL,
                          &StartupInfo,&ProcessInfo)) {
            processHandle = ProcessInfo.hProcess;
            processThread = ProcessInfo.hThread;
            return FALSE;
        }
        asd_sleep(3);
        sprintf(gCmdStr, "%s findserver", rwl_client_path);
        exec_process(gCmdStr);
    }
    else {
        exec_process(buf);
    }

    /* while cnClient associates in the child, parent looks
     * for association if it has happened
     * If it has not associated within a loop of 30, it comes out
     * as not associated
     */
    while(timeout_count > 0) {
        strcpy(gCmdStr, rwl_client_path);
        strcat(gCmdStr, " assoc >");
        if((tmpfd = asd_Config(gCmdStr,TEMP_FILE_PATH)) == NULL) {
            DPRINT_ERR(WFA_ERR, "\nassoc failed\n");
            return FALSE;
        }
        if((FileSearch(tmpfd, L"Not associated", &position))== -1) {
            Cleanup_File(tmpfd);
            break;
        }
        Cleanup_File(tmpfd);
        asd_sleep(1);
        timeout_count--;
    }
    if(timeout_count)
        return TRUE;
    else
        return FALSE;
}
コード例 #13
0
ファイル: pmsh.c プロジェクト: pdsouza/pmsh
int main(int argc, char** argv) {
    ssize_t cmd_size;
    int i;
    int pipefd[2], fin, fout;
    char buf[BUFFER_SIZE];
    char *cmd;
    char **args;
    job *j;
    job_list = init_list();
    msg_q = init_list();
    pid_t pgid;

    /* initial setup */
    shell_pgid = getpgid(0);
    sync_pwd();

    /* disable (ignore) job control signals */
    signal(SIGTTOU, SIG_IGN);
    signal(SIGTTIN, SIG_IGN);
    signal(SIGTERM, SIG_IGN);
    signal(SIGTSTP, SIG_IGN);
    signal(SIGINT,  SIG_IGN);

    set_handler();

    /*** Shell loop ***/
    for(;;) {

        /* Print out queued messages */
        for(i=0;i<msg_q->size;i++) {
            message *m = (message *) get(msg_q, i);
            printf("%s: %s\n", m->status ? "Finished" : "Stopped", m->msg);
        }

        // clear the queue
        while(msg_q->size > 0)
            free(del(msg_q,0));

        /* TODO: shell print macro */
        printf("%s %s %s ", SHELL, pwd, PROMPT);
        fflush(stdout);

        do 
            cmd_size = read(STDIN_FILENO, buf, BUFFER_SIZE);
        while(cmd_size == -1 && errno == EINTR); // ignore system call interrupts

        if(cmd_size == -1) {
            perror("read");
            continue;
        } else if(cmd_size == 0) { // EOF (quit)
            write(STDOUT_FILENO, EXIT_MSG, STRING_SIZE(EXIT_MSG));
            cleanup();
            _exit(EXIT_SUCCESS);
        } else if(cmd_size == 1 && buf[0] == '\n') {
            continue;
        }

        if(buf[cmd_size-1] != '\n') { // overflow 
            write(STDOUT_FILENO, OFLOW_MSG, STRING_SIZE(OFLOW_MSG));
            pflush();
            continue;
        }

        buf[cmd_size-1] = '\0'; // strip the newline

        j = parse(buf);
        if(j == (job *) NULL) {
            printf("Invalid redirections you moron!\n");
            continue;
        } 

        args = j->cmds[0];
        if (!my_strcmp(args[0], "fg")) {
            do_fg(args);
            free_job(j);
            continue;
        } else if (!my_strcmp(args[0], "bg")) {
            do_bg(args);
            free_job(j);
            continue;
        } else if (!my_strcmp(args[0], "jobs")) {
            print_bg(job_list);
            free_job(j);
            continue;
        } else if (!my_strcmp(args[0], "cd")) {
            do_cd(args);
            free_job(j);
            continue;
        }

        j->job_id = gen_job_id(job_list);
        j->running = 1;
        j->complete = 0;
        push(job_list, JOB, (void *)j);
    
        pgid = 0; // set the job pgid to be the first child's pid

        fin = STDIN_FILENO;
        for(i=0;i<(j->numcmds);i++) {
            args = j->cmds[i];
            cmd = args[0];

            if(i + 1 < (j->numcmds)) { // not last process in job
                //printf("Creating a pipe!\n");
                if(pipe(pipefd) == -1) {
                    perror("pipe");
                    exit(EXIT_FAILURE);
                }
                fout = pipefd[1];
            }
            else
                fout = STDOUT_FILENO;

            /*printf("Forking %s\n", cmd);
            k = 0;
            while( args[k] != (char *) NULL ) {
                printf("\targv[%d] = %s\n", k, args[k]);
                ++k;
            }*/

            pid = fork();
            if(pid == -1) {
                perror("fork");
                continue;
            }

            /*** CHILD ***/
            if(!pid) {

                // <
                if(j->fin[i] != (char *) NULL) {
                    if( (fin = open(j->fin[i], O_RDONLY)) == -1 ) {
                        perror("open");
                    }
                }
                // >
                if(j->fout[i] != (char *) NULL) {
                    if( (fout = open(j->fout[i], O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1 ) {
                        perror("open");
                    }
                }

                exec_process(cmd, args, pgid, fin, fout, j->fg); 
            }
            
            /*** PARENT ***/
            else {
                if(!pgid) { // set to first child's pid (process group leader)
                    pgid = pid;
                    j->pgid = pgid;
                    //printf("Set job's pgid to %d\n", pgid);
                }

                process *proc = malloc(sizeof(process));
                proc->complete = 0;
                proc->pid = pid;
                proc->pgid = pgid;
                push(j->pid_list, PROCESS, (void *)proc);
                
                if( setpgid(pid, pgid) == -1 ) {
                    perror("setpgid");
                    _exit(EXIT_FAILURE);
                }

            }

            if(fin != STDIN_FILENO)
                close(fin);
            if(fout != STDOUT_FILENO)
                close(fout);

            fin = pipefd[0];
        }

        //print_jobs();

        if(j->fg) {  // foreground

            // give terminal control to job
            if( tcsetpgrp(STDIN_FILENO, pgid) == -1 ) {
                perror("tcsetpgrp");
                _exit(EXIT_FAILURE);
            }

            // wait for job to finish
            jwait(j);

            // give pmsh terminal control again
            if( tcsetpgrp(STDIN_FILENO, shell_pgid) == -1 ) {
                perror("tcsetpgrp");
                _exit(EXIT_FAILURE);
            }
        }
        else  {      // background
            printf("Running: %s\n", j->rawcmd);
        }
    }
}
コード例 #14
0
ファイル: execute.c プロジェクト: tomoasleep/nemuish
int exec_job_list(job* job_list)
{
    int index;
    job *jb;
    process *pr;

    for(index = 0, jb = job_list; jb != NULL; jb = jb->next, ++index) {
        int fileds[2][2] = {
            {-1, -1},
            {-1, -1}
        };
        int has_before = 0;

        for(pr = jb->process_list; pr != NULL; pr = pr->next) {
            // get before process'es pipeno (for input)
            fileds[0][0] = fileds[1][0];
            fileds[0][1] = fileds[1][1];

            if (pr->next) {
                if (pipe(fileds[1]) < 0) {
                    perror("pipe");
                    exit(3);
                }
            }

            if (exec_buildin(pr)) {
                pr->program_name = NULL;
            }

            pr->pid = fork();

            if (pr->pid < 0) {
                perror("fork");
                exit(3);
            } else if (pr->pid > 0) {
                // parents do not use before process'es pipe 
                if (fileds[0][0] != -1) close(fileds[0][0]);
                if (fileds[0][1] != -1) close(fileds[0][1]);

                if (pr->next) {
                    has_before = 1;
                } else has_before = 0;
                continue;
            }

            // redirection
            if (pr->input_redirection) {
                int inputds = open(pr->input_redirection, O_RDONLY);
                close(STDIN_FILENO); dup2(inputds, STDIN_FILENO);
                close(inputds);
            }

            if (pr->output_redirection) {
                int outputds = -1;
                switch (pr->output_option) {
                    case APPEND:
                        outputds = open(pr->output_redirection,
                                O_WRONLY | O_APPEND | O_CREAT, S_IREAD | S_IWRITE);
                        break;
                    case TRUNC:
                        outputds = open(pr->output_redirection,
                                O_WRONLY | O_TRUNC | O_CREAT, S_IREAD | S_IWRITE);
                }
                close(STDOUT_FILENO); dup2(outputds, STDOUT_FILENO);
                close(outputds);
            }

            // pipeline
            if (has_before) {
                // connect before process'es out to in
                close(STDIN_FILENO); dup2(fileds[0][0], STDIN_FILENO);
                close(fileds[0][0]);
                // close unuse pipe
                close(fileds[0][1]);
            }
            if (pr->next) {
                // close unuse pipe
                close(fileds[1][0]);
                // connect my process'es out to next process'es in
                close(STDOUT_FILENO); dup2(fileds[1][1], STDOUT_FILENO);
                close(fileds[1][1]);
            }

            if (!pr->program_name) exit(0);
            exec_process(pr);
        }
    }

    for(index = 0, jb = job_list; jb != NULL; jb = jb->next, index++) {
        wait_process_list(jb);
    }

    //    printf("id %d [ %s ]\n", index, 
    //            jb->mode == FOREGROUND ? "foreground" : "background" );

        // for(pr = jb->process_list; pr != NULL; pr = pr->next) {
        //     if(print_process( pr ) < 0) {
        //         exit(EXIT_FAILURE);
        //     }
        //     if(jb->next != NULL) {
        //         printf( "\n" );
        //     }
    return 0;
}