void execute_file_commands (struct file *file) { const char *p; /* Don't go through all the preparations if the commands are nothing but whitespace. */ for (p = file->cmds->commands; *p != '\0'; ++p) if (!isspace ((unsigned char)*p) && *p != '-' && *p != '@') break; if (*p == '\0') { /* If there are no commands, assume everything worked. */ set_command_state (file, cs_running); file->update_status = us_success; notice_finished_file (file); return; } /* First set the automatic variables according to this file. */ initialize_file_variables (file, 0); set_file_variables (file); /* If this is a loaded dynamic object, unload it before remaking. Some systems don't support overwriting a loaded object. */ if (file->loaded) unload_file (file->name); /* Start the commands running. */ new_job (file); }
void execute_file_commands (struct file *file) { const char *p; /* Don't go through all the preparations if the commands are nothing but whitespace. */ for (p = file->cmds->commands; *p != '\0'; ++p) if (!isspace ((unsigned char)*p) && *p != '-' && *p != '@') break; if (*p == '\0') { /* If there are no commands, assume everything worked. */ set_command_state (file, cs_running); file->update_status = 0; notice_finished_file (file); return; } /* First set the automatic variables according to this file. */ initialize_file_variables (file, 0); set_file_variables (file); /* Start the commands running. */ new_job (file); }
void MiniLoop::AddToDelayedWorkQueue(PendingJob job) { assert(job.delay_run_ticks > 0); PendingJob new_job(job); job.seq_num = next_seq_num ++; delayed_job_.push(job); }
static flexsched_problem_t new_flexsched_problem(FILE *input, FILE *estimates) { flexsched_problem_t flex_prob; int i, j; // initialize flex_problem if (!(flex_prob = malloc(sizeof(struct flexsched_problem_s)))) { fprintf(stderr, "Insufficient memory to allocate flexsched problem structure!\n"); exit(1); } /* Parse instance file */ fscanf(input,"%d", &flex_prob->num_resources); fscanf(input,"%d", &flex_prob->num_nodes); fscanf(input,"%d", &flex_prob->num_jobs); flex_prob->nodes = calloc(flex_prob->num_nodes, sizeof(node_t)); for (i = 0; i < flex_prob->num_nodes; i++) { flex_prob->nodes[i] = new_node(flex_prob->num_resources); for (j = 0; j < flex_prob->num_resources; j++) fscanf(input,"%lf", &(flex_prob->nodes[i]->unit_capacities[j])); for (j = 0; j < flex_prob->num_resources; j++) fscanf(input,"%lf", &(flex_prob->nodes[i]->total_capacities[j])); } flex_prob->jobs = calloc(flex_prob->num_jobs, sizeof(job_t)); for (i = 0; i < flex_prob->num_jobs; i++) { flex_prob->jobs[i] = new_job(flex_prob->num_resources); for (j = 0; j < flex_prob->num_resources; j++) fscanf(input, "%lf", &(flex_prob->jobs[i]->unit_rigid_requirements[j])); for (j = 0; j < flex_prob->num_resources; j++) fscanf(input, "%lf", &(flex_prob->jobs[i]->actual_unit_fluid_needs[j])); for (j = 0; j < flex_prob->num_resources; j++) fscanf(input, "%lf", &(flex_prob->jobs[i]->total_rigid_requirements[j])); for (j = 0; j < flex_prob->num_resources; j++) fscanf(input, "%lf", &(flex_prob->jobs[i]->actual_total_fluid_needs[j])); if (estimates) { for (j = 0; j < flex_prob->num_resources; j++) fscanf(estimates, "%lf", &(flex_prob->jobs[i]->unit_fluid_needs[j])); for (j = 0; j < flex_prob->num_resources; j++) fscanf(estimates, "%lf", &(flex_prob->jobs[i]->total_fluid_needs[j])); } else { for (j = 0; j < flex_prob->num_resources; j++) { flex_prob->jobs[i]->unit_fluid_needs[j] = flex_prob->jobs[i]->actual_unit_fluid_needs[j]; flex_prob->jobs[i]->total_fluid_needs[j] = flex_prob->jobs[i]->actual_total_fluid_needs[j]; } } } return flex_prob; }
void enqueue_job (command *ptr, unsigned int stopped) { job *tmp = new_job (ptr); tmp->content->job = generate_job_number (); tmp->content->stopped = stopped; list_append ((sdlist **)&list, (sddata *)tmp); if (stopped) { fprintf (stdout, "[%d] %d (%s) suspended\n", tmp->content->job, ptr->pid, ptr->cmd); } else fprintf (stdout, "[%d] %d (%s)\n", tmp->content->job, ptr->pid, ptr->cmd); }
static void dag_compile_par(struct dag * slf){ int use_semaphore = 0; int size_semaphore = 0; size_semaphore = atoi(global_get_str("-jobs")); if( size_semaphore > 0 ){ use_semaphore = 1; pkg_sem_init(size_semaphore); } if(slf->sorted){ int i, max = 0; for(i = 0; slf->sorted[i]; i++){ max++; } struct job ** jobs = calloc(max+1, sizeof(struct job *)); for(i = 0; i < max; i++){ jobs[i] = new_job(); if( use_semaphore ){ jobs[i]->fn = &pkg_compile_par_sem; }else{ jobs[i]->fn = &pkg_compile_par; } jobs[i]->arg = (void *) slf->sorted[i]; } jobs[max] = NULL; int fail = spawn_jobs(i, jobs); if(fail){ panic("parallel compile failed", __FILE__, __LINE__); } for(i = 0; jobs[i]; i++){ free(jobs[i]); } free(jobs); } if(use_semaphore){ pkg_sem_destroy(); } };
int try_execute(String command, StringList arguments){ int c_pid; //handlers dos controladores struct sigaction sigchld; struct sigaction ctrlc; struct sigaction ctrlz; sigchld.sa_flags = SA_SIGINFO; sigchld.sa_sigaction = sigchld_hand; ctrlc.sa_flags = SA_SIGINFO; ctrlc.sa_sigaction = ctrlc_hand; ctrlz.sa_flags = SA_SIGINFO; ctrlz.sa_sigaction = ctrlz_hand; c_pid = fork(); if (c_pid == 0) { //processo filho setpgid(0, 0); execv(command, to_array(arguments)); } else { /*processo pai //tem controle sobre o sinal SIGCHLD, enviado pelo processo filho apos terminar sua execucao controle dos sinais: */ sigaction(SIGCHLD, &sigchld, 0); sigaction(SIGINT, &ctrlc, 0); sigaction(SIGTSTP, &ctrlz, 0); //adiciona na lista de jobs job_list_push(job_list, new_job(copy_string(int_to_string(c_pid)), parse_proc_name(command))); if(background == 1){ return 1; }else{ wait(NULL); } } return 1; }
/* execute tree in child subprocess */ int exchild(struct op *t, int flags, volatile int *xerrok, int close_fd) /* used if XPCLOSE or XCCLOSE */ { static Proc *last_proc; /* for pipelines */ int i; sigset_t omask; Proc *p; Job *j; int rv = 0; int forksleep; int ischild; if (flags & XEXEC) /* Clear XFORK|XPCLOSE|XCCLOSE|XCOPROC|XPIPEO|XPIPEI|XXCOM|XBGND * (also done in another execute() below) */ return execute(t, flags & (XEXEC | XERROK), xerrok); /* no SIGCHLD's while messing with job and process lists */ sigprocmask(SIG_BLOCK, &sm_sigchld, &omask); p = new_proc(); p->next = (Proc *) 0; p->state = PRUNNING; p->status = 0; p->pid = 0; /* link process into jobs list */ if (flags&XPIPEI) { /* continuing with a pipe */ if (!last_job) internal_errorf(1, "exchild: XPIPEI and no last_job - pid %d", (int) procpid); j = last_job; last_proc->next = p; last_proc = p; } else { j = new_job(); /* fills in j->job */ /* we don't consider XXCOM's foreground since they don't get * tty process group and we don't save or restore tty modes. */ j->flags = (flags & XXCOM) ? JF_XXCOM : ((flags & XBGND) ? 0 : (JF_FG|JF_USETTYMODE)); timerclear(&j->usrtime); timerclear(&j->systime); j->state = PRUNNING; j->pgrp = 0; j->ppid = procpid; j->age = ++njobs; j->proc_list = p; j->coproc_id = 0; last_job = j; last_proc = p; put_job(j, PJ_PAST_STOPPED); } snptreef(p->command, sizeof(p->command), "%T", t); /* create child process */ forksleep = 1; while ((i = fork()) < 0 && errno == EAGAIN && forksleep < 32) { if (intrsig) /* allow user to ^C out... */ break; sleep(forksleep); forksleep <<= 1; } if (i < 0) { kill_job(j, SIGKILL); remove_job(j, "fork failed"); sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0); errorf("cannot fork - try again"); } ischild = i == 0; if (ischild) p->pid = procpid = getpid(); else p->pid = i; #ifdef JOBS /* job control set up */ if (Flag(FMONITOR) && !(flags&XXCOM)) { int dotty = 0; if (j->pgrp == 0) { /* First process */ j->pgrp = p->pid; dotty = 1; } /* set pgrp in both parent and child to deal with race * condition */ setpgid(p->pid, j->pgrp); /* YYY: should this be if (ttypgrp_ok && ischild && !(flags&XBGND)) tcsetpgrp(tty_fd, j->pgrp); instead? (see also YYY below) */ if (ttypgrp_ok && dotty && !(flags & XBGND)) tcsetpgrp(tty_fd, j->pgrp); } #endif /* JOBS */ /* used to close pipe input fd */ if (close_fd >= 0 && (((flags & XPCLOSE) && !ischild) || ((flags & XCCLOSE) && ischild))) close(close_fd); if (ischild) { /* child */ /* Do this before restoring signal */ if (flags & XCOPROC) coproc_cleanup(false); sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0); cleanup_parents_env(); #ifdef JOBS /* If FMONITOR or FTALKING is set, these signals are ignored, * if neither FMONITOR nor FTALKING are set, the signals have * their inherited values. */ if (Flag(FMONITOR) && !(flags & XXCOM)) { for (i = NELEM(tt_sigs); --i >= 0; ) setsig(&sigtraps[tt_sigs[i]], SIG_DFL, SS_RESTORE_DFL|SS_FORCE); } #endif /* JOBS */ if (Flag(FBGNICE) && (flags & XBGND)) nice(4); if ((flags & XBGND) && !Flag(FMONITOR)) { setsig(&sigtraps[SIGINT], SIG_IGN, SS_RESTORE_IGN|SS_FORCE); setsig(&sigtraps[SIGQUIT], SIG_IGN, SS_RESTORE_IGN|SS_FORCE); if (!(flags & (XPIPEI | XCOPROC))) { int fd = open("/dev/null", 0); if (fd != 0) { (void) ksh_dup2(fd, 0, true); close(fd); } } } remove_job(j, "child"); /* in case of `jobs` command */ nzombie = 0; #ifdef JOBS ttypgrp_ok = 0; Flag(FMONITOR) = 0; #endif /* JOBS */ Flag(FTALKING) = 0; tty_close(); cleartraps(); execute(t, (flags & XERROK) | XEXEC, NULL); /* no return */ internal_errorf(0, "exchild: execute() returned"); unwind(LLEAVE); /* NOTREACHED */ } /* shell (parent) stuff */ /* Ensure next child gets a (slightly) different $RANDOM sequence */ change_random(); if (!(flags & XPIPEO)) { /* last process in a job */ #ifdef JOBS /* YYY: Is this needed? (see also YYY above) if (Flag(FMONITOR) && !(flags&(XXCOM|XBGND))) tcsetpgrp(tty_fd, j->pgrp); */ #endif /* JOBS */ j_startjob(j); if (flags & XCOPROC) { j->coproc_id = coproc.id; coproc.njobs++; /* n jobs using co-process output */ coproc.job = (void *) j; /* j using co-process input */ } if (flags & XBGND) { j_set_async(j); if (Flag(FTALKING)) { shf_fprintf(shl_out, "[%d]", j->job); for (p = j->proc_list; p; p = p->next) shf_fprintf(shl_out, " %d", p->pid); shf_putchar('\n', shl_out); shf_flush(shl_out); } } else rv = j_waitj(j, JW_NONE, "jw:last proc"); } sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0); return rv; }
/* int read_command_line(sh_string *command_line){ if(command_line == NULL) return -1; else if(command_line->buffer == NULL) return -1; else{ fgets(command_line->buffer, STRING_SIZE, stdin); return 0; } } */ job* to_parse(char* in) { int isBackground = 0; int flagIn = 0; int flagOut = 0; int i; char* hasIn; char* hasOut; char* nameIn = NULL; char* nameOut = NULL; char** com; char deli = '|'; char aux[2]; if(in[strlen(in) - 2] == '&') { isBackground = 1; in[strlen(in) - 2] = '\0'; } hasIn = strchr(in, '<'); hasOut = strchr(in, '>'); if(hasIn != NULL) { flagIn = 1; } if(hasOut != NULL) { flagOut = 1; } if(flagIn == 1) { nameIn = (char*) malloc (32 * sizeof(char)); if(flagOut == 1) { nameOut = (char*) malloc (32 * sizeof(char)); if(hasIn-in+1 > hasOut-in+1) { for(i = hasOut-in+2; i < hasIn-in; ++i) { if(in[i] != ' ') { aux[0] = in[i]; aux[1] = '\0'; strcat(nameOut, aux); } } for(i = hasIn-in+2; i < strlen(in)-1; ++i) { if(in[i] != ' ') { aux[0] = in[i]; aux[1] = '\0'; strcat(nameIn, aux); } } hasOut = strchr(in, '>'); in[hasOut-in-1] = '\0'; } else { for(i = hasIn-in+2; i < hasOut-in; ++i) { if(in[i] != ' ') { aux[0] = in[i]; aux[1] = '\0'; strcat(nameIn, aux); } } for(i = hasOut-in+2; i < strlen(in)-1; ++i) { if(in[i] != ' ') { aux[0] = in[i]; aux[1] = '\0'; strcat(nameOut, aux); } } hasIn = strchr(in, '<'); in[hasIn-in-1] = '\0'; } } else { for(i = hasIn-in+2; i < strlen(in)-1; ++i) { if(in[i] != ' ') { aux[0] = in[i]; aux[1] = '\0'; strcat(nameIn, aux); } } hasIn = strchr(in, '<'); in[hasIn-in-1] = '\0'; } } else { if(flagOut == 1) { nameOut = (char*) malloc (32 * sizeof(char)); for(i = hasOut-in+2; i < strlen(in)-1; ++i) { if(in[i] != ' ') { aux[0] = in[i]; aux[1] = '\0'; strcat(nameOut, aux); } } hasOut = strchr(in, '>'); in[hasOut-in-1] = '\0'; } } com = VectorChar(in, &deli); return (new_job(com, isBackground, nameIn, nameOut)); }
int exchild(struct op *t, int flags, int close_fd) /* used if XPCLOSE or XCCLOSE */ { static Proc *last_proc; /* for pipelines */ int i; sigset_t omask; Proc *p; Job *j; int rv = 0; int forksleep; int ischild; if (flags & XEXEC) /* Clear XFORK|XPCLOSE|XCCLOSE|XCOPROC|XPIPEO|XPIPEI|XXCOM|XBGND * (also done in another execute() below) */ return execute(t, flags & (XEXEC | XERROK)); p = new_proc(); p->next = (Proc *) 0; p->state = PRUNNING; p->status = 0; p->pid = 0; /* link process into jobs list */ if (flags&XPIPEI) { /* continuing with a pipe */ if (!last_job) internal_errorf(1, "exchild: XPIPEI and no last_job - pid %d", (int) procpid); j = last_job; last_proc->next = p; last_proc = p; } else { j = new_job(); /* fills in j->job */ /* we don't consider XXCOM's foreground since they don't get * tty process group and we don't save or restore tty modes. */ j->flags = (flags & XXCOM) ? JF_XXCOM : ((flags & XBGND) ? 0 : (JF_FG|JF_USETTYMODE)); j->usrtime = j->systime = 0; j->state = PRUNNING; j->pgrp = 0; j->ppid = procpid; j->age = ++njobs; j->proc_list = p; j->coproc_id = 0; last_job = j; last_proc = p; put_job(j, PJ_PAST_STOPPED); } snptreef(p->command, sizeof(p->command), "%T", t); /* create child process */ forksleep = 1; while ((i = fork()) < 0 && errno == EAGAIN && forksleep < 32) { if (intrsig) /* allow user to ^C out... */ break; sleep(forksleep); forksleep <<= 1; } if (i < 0) { kill_job(j, SIGKILL); remove_job(j, "fork failed"); sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0); errorf("cannot fork - try again"); } ischild = i == 0; if (ischild) p->pid = procpid = getpid(); else p->pid = i; /* used to close pipe input fd */ if (close_fd >= 0 && (((flags & XPCLOSE) && !ischild) || ((flags & XCCLOSE) && ischild))) close(close_fd); if (ischild) { /* child */ /* Do this before restoring signal */ if (flags & XCOPROC) coproc_cleanup(false); sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0); cleanup_parents_env(); if ((flags & XBGND)) { setsig(&sigtraps[SIGINT], SIG_IGN, SS_RESTORE_IGN|SS_FORCE); setsig(&sigtraps[SIGQUIT], SIG_IGN, SS_RESTORE_IGN|SS_FORCE); if (!(flags & (XPIPEI | XCOPROC))) { int fd = open("/dev/null", 0); if (fd != 0) { (void) ksh_dup2(fd, 0, true); close(fd); } } } remove_job(j, "child"); /* in case of `jobs` command */ nzombie = 0; Flag(FTALKING) = 0; tty_close(); cleartraps(); execute(t, (flags & XERROK) | XEXEC); /* no return */ internal_errorf(0, "exchild: execute() returned"); unwind(LLEAVE); /* NOTREACHED */ } /* shell (parent) stuff */ /* Ensure next child gets a (slightly) different $RANDOM sequence */ change_random(); if (!(flags & XPIPEO)) { /* last process in a job */ j_startjob(j); if (flags & XCOPROC) { j->coproc_id = coproc.id; coproc.njobs++; /* n jobs using co-process output */ coproc.job = (void *) j; /* j using co-process input */ } if (flags & XBGND) { j_set_async(j); if (Flag(FTALKING)) { shf_fprintf(shl_out, "[%d]", j->job); for (p = j->proc_list; p; p = p->next) shf_fprintf(shl_out, " %d", p->pid); shf_putchar('\n', shl_out); shf_flush(shl_out); } } else rv = j_waitj(j, JW_NONE, "jw:last proc"); } sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0); return rv; }
int main(void) { char inputBuffer[MAX_LINE]; /** buffer to hold the command entered **/ int background; /** equals 1 if a command is followed by '&' **/ int respawnable; /** igual a 1 si al comando le sigue '#' **/ char *args[MAX_LINE / 2]; /** command line (of 256) has max of 128 arguments **/ // probably useful variables: int pid_fork, pid_wait; /** pid for created and waited process **/ int status; /** status returned by wait **/ enum status status_res; /** status processed by analyze_status() **/ int info; /** info processed by analyze_status() **/ ignore_terminal_signals(); /** Ignora las señales del terminal **/ /** Asociamos el manejador a la señal SIGCHLD y creamos la lista de trabajos **/ signal(SIGCHLD, manejador); lista_trabajos = new_list("Lista trabajos"); /** Program terminates normally inside get_command() after ^D is typed **/ while(1) { printf("\nCOMMAND->"); fflush(stdout); /** get next command **/ get_command(inputBuffer, MAX_LINE, args, &background, &respawnable); // if empty command if(args[0] == NULL) { continue; } /** Comando interno CD **/ if(strcmp(args[0], "cd") == 0 && args[1] != NULL) { chdir(args[1]); continue; } /** Comando interno historial **/ if(strcmp(args[0], "historial") == 0) { continue; } /** Comando interno JOBS (HECHO) **/ if(strcmp(args[0], "jobs") == 0) { if(empty_list(lista_trabajos)) { printf("La lista de tareas está vacía\n"); } else { print_job_list(lista_trabajos); } continue; } /** Comando interno BG (HECHO) **/ if(strcmp(args[0], "bg") == 0) { if(args[1] == NULL) { printf("No le has pasado ningún argumento al comando \n"); } else { int index = atoi(args[1]); // Convertimos el indice pasado a un entero bgCommand(index); // Invocamos al comando FG } continue; } /** Comando interno FG (HECHO) **/ if(strcmp(args[0], "fg") == 0) { int index = 1; // Por defecto a la primera tarea de la lista if(args[1] != NULL) { index = atoi(args[1]); // Si no es nulo, lo aplicaremos al correspondiente } fgCommand(index); // Invocamos al comando FG continue; } // the steps are: // (1) fork a child process using fork() pid_fork = fork(); if(pid_fork < 0) { // Caso de error printf("Error. The system wasn able to spawn a new process. Exiting...\n"); exit(-1); } else if(pid_fork == 0) { // Proceso hijo /** Nuevo identificador de grupo de procesos para el hijo, asociacion del terminal y señales a default **/ pid_t mypid = getpid(); new_process_group(mypid); // Metemos al hijo en un nuevo grupo if(!background && !respawnable) { // Le asignamos el terminal set_terminal(mypid); } // Restauramos las señales que reciben del terminal restore_terminal_signals(); // (2) the child process will invoke execvp() execvp(args[0], args); // Solo llegará aquí si no se ha producido el cambio de imagen printf("Error. Command not found: %s\n", args[0]); exit(-1); // Padre } else { /** Nuevo identificador de grupo de procesos para el hijo **/ new_process_group(pid_fork); // El padre se va a un nuevo grupo de trabajo /** Si el programa está en background o es respawnable **/ if(background || respawnable) { /** BLoqueamos la señal SIGCHLD, añadimos el trabajo a la lista(background) y desbloqueamos la señal **/ block_SIGCHLD(); job *aux; // Creamos un nuevo nodo para agregarlo a la lista if(background) { aux = new_job(pid_fork, args[0], args, BACKGROUND); } else if(respawnable) { aux = new_job(pid_fork, args[0], args, RESPAWNABLE); } // Añadimos ese nodo a la lista creada anteriormente add_job(lista_trabajos, aux); unblock_SIGCHLD(); printf("Background job running... pid: %d, command: %s. \n", pid_fork, args[0]); /** Si no, es por que está en foreground **/ } else { /** * Wait con detección de suspension y recuperación del terminal * Con el WUNTRACED se comprueba también si el hijo se suspende **/ set_terminal(pid_fork); // Redundante pid_t wait_pid = waitpid(pid_fork, &status, WUNTRACED); set_terminal(getpid()); /** * pid_fork = waitpid(pid_fork, &status, 0); * esta instruccion ya no es necesaria porque hacemos el wait_pid **/ int info; // Le pasamos la variable "status" que nos acaba de pasar el wait enum status st = analyze_status(status, &info); /** * Si sale del bloqueo debido a la suspensión del estado * lo metemos en la lista de tareas para poder llevar un * seguimiento de los procesos suspendidos **/ if(st == SUSPENDED) { /** BLoqueamos la señal SIGCHLD, añadimos el trabajo a la lista (suspendido) y desbloqueamos la señal **/ block_SIGCHLD(); // Creamos un nuevo nodo para agregarlo a la lista job *aux = new_job(pid_fork, args[0], args, STOPPED); // Añadimos ese nodo a la lista creada anteriormente add_job(lista_trabajos, aux); unblock_SIGCHLD(); } // (4) Shell shows a status message for processed command printf("Foreground pid: %d, command: %s, status: %s, info: %d. \n", wait_pid, args[0], status_strings[st], info); } } // (5) loop returns to get_commnad() function } // end while }