static void pipe_exec(char **command, t_env *e, int fork) { static char *builtins[] = { BUILTINS }; static void (*function[])(char **, t_env *) = { FUNCTION }; char *path; int i; i = 0; while (builtins[i]) { if (ft_strcmp(*command, builtins[i]) == 0) { function[i](command, e); return ; } i++; } if (!fork) pipe_fork(command, e); else { path = fork_function(command, e); if (path) free(path); } }
/** * @param tr_out Handler function for data read from stdin. Its parameters are: byte buffer, size of byte buffer, pid of child process. */ int playbatch(int *ret_code, FILE *fp_in, int (*tr_in)(), FILE *fp_out, int (*tr_out)(), FILE *fp_err, int (*tr_err)(), long vtimer, char *prog, char *argv[]) { int pid; int pipe_out[2], pipe_err[2], pipe_in[2]; pid = pipe_fork(pipe_in, pipe_out, pipe_err); if (pid < 0) { return ERRO; } if (pid == 0) { /* child */ struct rlimit resource_limit; struct itimerval interval_time; // Disable core dump resource_limit.rlim_cur = 0; resource_limit.rlim_max = 0; setrlimit(RLIMIT_CORE, &resource_limit); // Set max time a process can run before signaling with SIGVTALRM if (vtimer != 0) { interval_time.it_interval.tv_sec = vtimer; interval_time.it_interval.tv_usec = vtimer * 1000000L; interval_time.it_value.tv_sec = vtimer; interval_time.it_value.tv_usec = vtimer * 1000000L; signal(SIGVTALRM, SIG_DFL); // SIG_DFL is the default action for this signal, which is to terminate the process setitimer(ITIMER_VIRTUAL, &interval_time, NULL); } execv(prog, argv); exit(ERRO); } else { /* parent */ int child_retcode, bytes, result; int fim_le = FALSE; while (waitpid(pid, &child_retcode, WNOHANG) != pid) { // Read data from child's output pipe bytes = -1; if (ioctl(pipe_out[0], FIONREAD, &bytes) != -1) { if (bytes > 0) { bytes = read(pipe_out[0], buff, BUFFSIZE); } } if (bytes == -1) { result = ERRO; goto fim; } // Handle data if (tr_out != NULL) { result = tr_out(fp_out, buff, bytes, pid); if (result == ERRO || result != bytes) { result = ERRO; goto fim; } } // Read data from child's err pipe bytes = -1; if (ioctl(pipe_err[0], FIONREAD, &bytes) != -1) { if (bytes > 0) { bytes = read(pipe_err[0], buff, BUFFSIZE); } } if (bytes == -1) { result = ERRO; goto fim; } // Handle data if (tr_err != NULL) { result = tr_err(fp_err, buff, bytes, pid); if (result == ERRO || result != bytes) { result == ERRO; goto fim; } } if ( ! fim_le) { bytes = tr_in(fp_in, buff, BUFFSIZE); if (bytes < 0) { result = ERRO; goto fim; } else if (bytes == 0) { fim_le = TRUE; close(pipe_in[1]); } else { bytes = writepipe(pipe_in[1], buff, bytes); if (bytes < 0) { msg("Error writing to the pipe"); result = ERRO; goto fim; } else { if (bytes == 0) { continue; /* broken pipe! */ } } } } } // Handle any remaining output data do { bytes = -1; if (ioctl(pipe_out[0], FIONREAD, &bytes) != -1) { if (bytes > 0) { bytes = read(pipe_out[0], buff, BUFFSIZE); } } if (bytes == -1) { result = ERRO; goto fim; } // Handle data if (tr_out != NULL) { result = tr_out(fp_out, buff, bytes, pid); if (result == ERRO || result != bytes) { result = ERRO; goto fim; } } } while (bytes > 0); // Handle any remaining err data do { // Read data from child's err pipe bytes = -1; if (ioctl(pipe_err[0], FIONREAD, &bytes) != -1) { if (bytes > 0) { bytes = read(pipe_err[0], buff, BUFFSIZE); } } if (bytes == -1) { result = ERRO; goto fim; } // Handle data if (tr_err != NULL) { result = tr_err(fp_err, buff, bytes, pid); if (result == ERRO || result != bytes) { result == ERRO; goto fim; } } } while (bytes > 0); fim: waitpid(pid, &child_retcode, 0); close(pipe_in[1]); close(pipe_out[0]); close(pipe_err[0]); if (ret_code != NULL) { *ret_code = child_retcode; } return result; } }
int playinput(int *ret_code, FILE *fp_in, int (*tr_in)(), FILE *fp_out, int (*tr_out)(), FILE *fp_err, int (*tr_err)(), long vtimer, char *prog, char *argv[]) { int i, c, bytes, ret1, k, j; struct itimerval t1; long tt2, tt1; struct rlimit resource_limit; int fim_le; int pipe_out[2], pipe_err[2], fdm; pid_t pid, pipe_fork(); pid = pty_fork(&fdm, pipe_out, pipe_err); if (pid < 0) return ERRO; if ( pid == 0 ) /* child */ { resource_limit.rlim_cur = resource_limit.rlim_max = 0; setrlimit(RLIMIT_CORE, &resource_limit); /* tamanho maximo para arquivo CORE = 0 bytes */ if (vtimer != 0) { tick2timeval(vtimer, &t1.it_value); t1.it_interval.tv_sec = t1.it_value.tv_sec ; t1.it_interval.tv_usec = t1.it_value.tv_usec; signal(SIGVTALRM, SIG_DFL); setitimer(ITIMER_VIRTUAL, &t1, NULL); } execv(prog,argv ); return ERRO; } else { tt1 = gettimedad(); fim_le = FALSE; c = 0; while ( waitpid(pid, &c, WNOHANG) != pid ) { bytes = 0; if (ioctl(pipe_out[0],FIONREAD,&bytes) != -1 && bytes > 0) bytes = read(pipe_out[0],buff,BUFFSIZE); else bytes = 0; if (tr_out != NULL && (k = tr_out(fp_out, buff, bytes,pid)) != bytes) { if (k != ERRO) k = OK; goto fim; } bytes = 0; if (ioctl(pipe_err[0],FIONREAD,&bytes) != -1 && bytes > 0) bytes = read(pipe_err[0],buff,BUFFSIZE); else bytes = 0; if (tr_err != NULL && (k = tr_err(fp_err, buff, bytes, pid)) != bytes) { if (k != ERRO) k = OK; goto fim; } if ( ! fim_le) { bytes = tr_in(buff, BUFFSIZE); if (bytes < 0) { k = ERRO; goto fim; } else if (bytes == 0) { fim_le = TRUE; /* / close(fdm); */ } else { int t; t = bytes; bytes = writen(fdm, buff, bytes); if (bytes < 0) { msg("Error writing to master"); k = ERRO; goto fim; } } } } do { if (ioctl(pipe_out[0],FIONREAD,&bytes) != -1 && bytes > 0) bytes = read(pipe_out[0],buff,BUFFSIZE); else bytes = 0; if (tr_out != NULL && (k =tr_out(fp_out, buff, bytes, pid)) != bytes) { if (k != ERRO) k = OK; goto fim; } } while (bytes > 0); do { if (ioctl(pipe_err[0],FIONREAD,&bytes) != -1 && bytes > 0) bytes = read(pipe_err[0],buff,BUFFSIZE); else bytes = 0; if (tr_err != NULL && (k = tr_err(fp_err, buff, bytes, pid))!=bytes) { if (k != ERRO) k = OK; goto fim; } } while (bytes > 0); } k = OK; fim: wait(NULL); close(pipe_out[0]); close(pipe_err[0]); close(fdm); if (ret_code != NULL) *ret_code = c; return k; }