Esempio n. 1
0
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);
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
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();
    }
};
Esempio n. 7
0
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;
}
Esempio n. 8
0
/* 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;
}
Esempio n. 9
0
/*
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));


}
Esempio n. 10
0
File: jobs.c Progetto: adtools/abcsh
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;
}
Esempio n. 11
0
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
}