Ejemplo n.º 1
0
/*
 * eval - Evaluate the command line that the user has just typed in
 *
 * If the user has requested a built-in command (quit, jobs, bg or fg)
 * then execute it immediately. Otherwise, fork a child process and
 * run the job in the context of the child. If the job is running in
 * the foreground, wait for it to terminate and then return. Note:
 * each child process must have a unique process group ID so that our
 * background children don't receive SIGINT (SIGTSTP) from the kernel
 * when we type ctrl-c (ctrl-z) at the keyboard.
*/
void eval(char *cmdline)
{
        char* argvTask[MAXARGS]; // holds arguments for other calls
        pid_t npid; // new pid temp var
        sigset_t mask;
        parseline(cmdline, argvTask);
        if(builtin_cmd(argvTask)){}                 // check for a built in and runs immediately
        else // reaches for non-built in
        {
                sigemptyset(&mask);
                sigaddset(&mask, SIGCHLD);
                sigprocmask(SIG_BLOCK, &mask, NULL); // enable mask for parent
                if(parseline(cmdline, argvTask)) //checking if BG
                {
                        if(( npid = fork()) == 0) // child run in bg
                        {
                                sigprocmask(SIG_UNBLOCK, &mask, NULL); // unblock mask for child
                                setpgid(0,0);
                                if(execve(argvTask[0], argvTask, environ) < 0)
                                {
                                        //unix_error( argvTask[0]);
                                        printf("%s: Command not found \n",argvTask[0]);

                                        exit(0);
                                }
                        }
                        else // parent
                        {
                                addjob(jobs, npid,BG, cmdline); // add bg job to list and parent does not wait
                                printf( "[%d] (%d) %s", maxjid(jobs) , npid , cmdline);

                                sigprocmask(SIG_UNBLOCK, &mask, NULL); // unblock the parent
                        }
                }
                else // runs if FG
                {
                        if(( npid = fork()) == 0) // child run in fg
                        {
                                sigprocmask(SIG_UNBLOCK, &mask, NULL); // unblock child
                                setpgid(0,0);
                                if(execve(argvTask[0], argvTask, environ) < 0) // use exec call and check for error
                                {
                                        printf("%s: Command not found \n",argvTask[0]);
                                        exit(0);
                                }
                        }
                        else                 // parent
                        {
                                addjob(jobs, npid,FG,cmdline);        // adding the fg job to jobs list
                                sigprocmask(SIG_UNBLOCK, &mask, NULL); // unblock the parent

                                waitfg(npid);        //waiting for fg process to finish
                        }
                }
        }
  return;
}
// function used to delete job from job list
void deletejob(struct job_t *job_list,pid_t pid){
int i;
for(i=0;i<20;i++){
		if(job_list[i].pid==pid){
			clearjob(&job_list[i]);
			nextjid=maxjid(job_list)+1;
			break;
			}
		}
}
Ejemplo n.º 3
0
Archivo: tsh.c Proyecto: protos37/splab
/* 
 * sigchld_handler - The kernel sends a SIGCHLD to the shell whenever
 *	 a child job terminates (becomes a zombie), or stops because it
 *	 received a SIGSTOP or SIGTSTP signal. The handler reaps all
 *	 available zombie children, but doesn't wait for any other
 *	 currently running children to terminate.  
 */
void sigchld_handler(int sig) 
{
	int child_status;	// child process status for waitpid
	pid_t wpid;
	struct job_t *job;

	// wait for child process while there is any child left
	while(maxjid(jobs))
	{
		// -1			: wait for any child
		// WNOHANG		: don't block procedure
		// WUNTRACED	: trace stopped child
		wpid = waitpid(-1, &child_status, WNOHANG | WUNTRACED);

		if(wpid == -1)
		{
			// handle waitpid error
			perror("waitpid");
			return;
		}
		else if(wpid == 0)
		{
			// no child was terminated or stopped
			break;
		}

		// find job object with pid
		// getjobpid never fails
		job = getjobpid(jobs, wpid);

		// check child status
		if(WIFSIGNALED(child_status))
		{
			// child terminated by a signal
			printf("Job [%d] (%d) terminated by signal %d\n", job->jid, job->pid, WTERMSIG(child_status));
			// delete job from job list
			deletejob(jobs, wpid);
		}
		else if(WIFSTOPPED(child_status))
		{
			// child stopped
			printf("Job [%d] (%d) stopped by signal %d\n", job->jid, job->pid, WSTOPSIG(child_status));
			// set state
			job->state = ST;
		}
		else if(WIFEXITED(child_status))
		{
			// child exited properly
			// delete job from job list
			deletejob(jobs, wpid);
		}
	}
}
Ejemplo n.º 4
0
/* deletejob - Delete a job whose PID=pid from the job list */
int deletejob(struct job_t *jobs, pid_t pid) {
    int i;

    if (pid < 1)
        return 0;

    for (i = 0; i < MAXJOBS; i++) {
        if (jobs[i].pid == pid) {
            clearjob(&jobs[i]);
            nextjid = maxjid(jobs)+1;
            return 1;
        }
    }
    return 0;
}
Ejemplo n.º 5
0
/*
 * Requires:
 *   "jobs" points to an array of MAXJOBS job structures.
 *
 * Effects:
 *   Deletes a job from the jobs list whose PID equals "pid".
 */
static int
deletejob(JobP jobs, pid_t pid) 
{
	int i;

	if (pid < 1)
		return (0);
	for (i = 0; i < MAXJOBS; i++) {
		if (jobs[i].pid == pid) {
			clearjob(&jobs[i]);
			nextjid = maxjid(jobs) + 1;
			return (1);
		}
	}
	return (0);
}
Ejemplo n.º 6
0
/* deletejob - Delete a job whose PID=pid from the job list */
int deletejob(struct job_t *job_list, pid_t pid) 
{
    int i;
	//fprintf(stderr, "try to delete job:%d\n", pid);
    if (pid < 1)
        return 0;

    for (i = 0; i < MAXJOBS; i++) {
        if (job_list[i].pid == pid) {
            clearjob(&job_list[i]);
            nextjid = maxjid(job_list)+1;
            return 1;
        }
    }
    return 0;
}
Ejemplo n.º 7
0
		/* deletejob - Delete a job whose PID=pid from the job list */
		int deletejob(struct job_t *jobs, pid_t pid)
		{
		    int i;
	//printf("here in delete job \n" );
		    if (pid < 1)
			return 0;

		    for (i = 0; i < MAXJOBS; i++) {

			if (jobs[i].pid == pid) {
			    clearjob(&jobs[i]);
			    nextjid = maxjid(jobs)+1;
				//	printf("job found\n");
			    return 1;
			}
		    }
		    return 0;
		}