const char* disque::addjob(const char* name, const void* job, size_t job_len, int timeout, const disque_cond* cond) { if (cond == NULL) return addjob(name, job, job_len, timeout); std::map<string, int> args; int n = cond->get_replicate(); if (n > 0) args["REPLICATE"] = n; n = cond->get_delay(); if (n >= 0) args["DELAY"] = n; n = cond->get_retry(); if (n > 0) args["RETRY"] = n; n = cond->get_ttl(); if (n > 0) args["TTL"] = n; n = cond->get_maxlen(); if (n > 0) args["MAXLEN"] = n; if (cond->is_async()) args["ASYNC"] = 1; return addjob(name, job, job_len, timeout, &args); }
/* * * 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 h * * ave 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 *argv[MAXARGS]; int bg = parseline(cmdline, argv); pid_t pid; struct job_t *jb; sigset_t mask; if (argv[0] == NULL) return; //Ignoring the empty lines if (!builtin_cmd(argv)) { sigprocmask(SIG_BLOCK,&mask, NULL); if((pid = fork()) == 0) { sigprocmask(SIG_UNBLOCK,&mask,NULL); setpgid(0,0); if(execv(argv[0],argv)<0){ printf("%s : Command not found!! \n" , argv[0]); exit(0); } } if(!bg) { addjob(jobs,pid,FG,cmdline); sigprocmask(SIG_UNBLOCK,&mask,NULL); waitfg(pid); } else{ addjob(jobs,pid,BG,cmdline); sigprocmask(SIG_UNBLOCK,&mask,NULL); jb = getjobpid(jobs,pid); printf("[%d] (%d) %s", jb->jid, jb->pid,jb->cmdline); } } return; }
/* * 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 *argv[MAXARGS]; int isBG = parseline(cmdline, argv); if (argv[0] == NULL) return; if (builtin_cmd(argv)) return; sigset_t allset; sigfillset(&allset); sigprocmask(SIG_BLOCK, &allset, NULL); pid_t childpid = fork(); if (childpid == -1) unix_error("fork failed"); if (childpid == 0) { sigprocmask(SIG_UNBLOCK, &allset, NULL); if (setpgid(0, 0) == -1) unix_error("setpgrp failed"); if (execv(argv[0], argv) == -1) unix_error("execv failed"); } if (isBG) { addjob(jobs, childpid, BG, cmdline); printjob(jobs, childpid); sigprocmask(SIG_UNBLOCK, &allset, NULL); } else { addjob(jobs, childpid, FG, cmdline); sigprocmask(SIG_UNBLOCK, &allset, NULL); waitfg(childpid); } return; }
/* * 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) { // Kyung and Jung drove here /* Outline taken from Bryant & O'Hall page 735 */ /* variables*/ char *argv[MAXARGS]; char buf[MAXLINE]; int bg; pid_t pid; struct job_t *addedjob; sigset_t mask; /* for signals */ sigemptyset(&mask); sigaddset(&mask, SIGCHLD); strcpy(buf,cmdline); /* parse command line */ bg = parseline(buf,argv); /************************** * evaluates command line **************************/ if(argv[0] == NULL) return; if(!builtin_cmd(argv)) { /* built-in command */ sigprocmask(SIG_BLOCK, &mask, NULL); pid = fork(); if(pid < 0) { /* fork error handling */ unix_error("Fork error"); } else if(pid==0) { /* child */ setpgid(0, 0); sigprocmask(SIG_UNBLOCK, &mask, NULL); if(execve(argv[0], argv,environ) < 0) { printf("%s: Command not found\n", argv[0]); exit(1); } } else { /* parent - not a build-in command */ if(bg) { /* run in background */ sigprocmask(SIG_UNBLOCK, &mask, NULL); addjob(jobs, pid, BG, cmdline); addedjob = getjobpid(jobs,pid); printf("[%d] (%d) %s", addedjob->jid, addedjob->pid, addedjob->cmdline); } else { /* run in foreground */ sigprocmask(SIG_UNBLOCK, &mask, NULL); addjob(jobs, pid, FG, cmdline); waitfg(pid); } } } return; /* done with code excerpt/outline */ // end of Kyung and Jung driving }
/* * 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. * * Requires: * "cmdline" is a NUL ('\0') terminated string with a trailing * '\n' character. "cmdline" must contain less than MAXARGS * arguments. * * Effects: * A built-in command is executed immediately. Otherwise, it attempts * to fork a child process and execute the job. If necessary, the * executable program is searched through the directories of the * search path. If not found, an error is thrown. If the job is * running as a foreground job, it waits until completion. */ static void eval(const char *cmdline) { char *argv[MAXARGS]; int bg = parseline(cmdline, argv); pid_t pid; sigset_t mask; // Checks command line is not empty. if (!argv[0]) { return; } // Checks that the command is not a built-in command. if(!builtin_cmd(argv)){ sigemptyset(&mask); sigaddset(&mask, SIGCHLD); sigprocmask(SIG_BLOCK, &mask, NULL); // A child is forked. pid = fork(); if (pid == 0) { // Put child in new group whose ID is identical to child’s PID. setpgid(0, 0); sigprocmask(SIG_UNBLOCK, &mask, NULL); if (execve(argv[0], argv, environ) == -1) { int index = 0; // Run through directories in search path to execute program. while (argv[0][0] != '.' && index < directoryCount) { if (execve(strcat(directories[index],argv[0]), argv, environ) != -1) { break; } index++; } // Command not found. char *print; asprintf(&print, "%s: Command not found\n", argv[0]); sio_error(print); } } if (bg == 0) { addjob(jobs,pid,FG,cmdline); sigprocmask(SIG_UNBLOCK, &mask, NULL); // Wait for foreground jobs to complete. waitfg(pid); } else { addjob(jobs,pid,BG,cmdline); sigprocmask(SIG_UNBLOCK, &mask, NULL); printf("[%d] (%d) %s", pid2jid(pid), pid, cmdline); } } return; }
/* * 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 *argv[MAXARGS]; char buf[MAXLINE]; int bg; sigset_t mask; pid_t pid; strcpy(buf, cmdline); bg = parseline(buf, argv); if(argv[0] == NULL) return; if(!builtin_cmd(argv)){ //block signal if(sigemptyset(&mask) < 0) unix_error("sigemptyset error"); if(sigaddset(&mask, SIGCHLD) < 0) unix_error("sigaddset error"); if(sigprocmask(SIG_BLOCK, &mask, NULL) < 0) unix_error("sigprocmask error"); if((pid = fork()) == 0){ //set pid group to be the same as the current pid if(setpgid(0,0) < 0) unix_error("eval: set pid group error"); //unblock siganl if(sigprocmask(SIG_UNBLOCK, &mask, NULL) < 0) unix_error("sigprocmask error"); //execute program if(execve(argv[0], argv, environ)<0){ printf("%s: Command not found.\n", argv[0]); exit(1); } } if(!bg){ addjob(jobs, pid, FG, cmdline); //unblock siganl if(sigprocmask(SIG_UNBLOCK, &mask, NULL) < 0) unix_error("sigprocmask error"); waitfg(pid); }else{ addjob(jobs, pid, BG, cmdline); //unblock siganl if(sigprocmask(SIG_UNBLOCK, &mask, NULL) < 0) unix_error("sigprocmask error"); printf("[%d] (%d) %s", pid2jid(pid), pid, cmdline); } } return; }
/* * 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; }
/* * 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 * argv[MAXARGS]; int bg = parseline(cmdline, argv); int rbic = builtin_cmd(argv); if (!rbic) { pid_t child = fork(); //printf("forked\n"); if (child) { //PARENT if (bg) { int ret = addjob(jobs, child, BG, cmdline); //returns an int if (ret) { int jid = pid2jid(child); printf("[%d] (%d) %s", jobs[jid-1].jid, jobs[jid-1].pid, jobs[jid-1].cmdline); } else { printf("addjobfailed\n"); } } else { int ret = addjob(jobs, child, FG, cmdline); //returns an int if (!ret) { printf("addjobfailed\n"); } waitfg(child); } } else if( child < 0 ) { //ERROR exit(1); } else { //CHILDS setpgid( 0, 0 ); int rc = execv( argv[0], argv ); if (rc == -1) { printf( "execv error %d\n", errno); exit(1); } } } return; }
/* * Exec * * arguments: * commandT *cmd: the command to be run * bool forceFork: whether to fork * * returns: none * * Executes a command. */ static void Exec(char *abspath, commandT* cmd, bool forceFork) { if (!forceFork) { if (execv(abspath, cmd->argv) < 0) printf("%s not found", cmd->argv[0]); return; } sigset_t mask; pid_t pid; bool bg; struct job_t *curr; char buf[MAXLINE]; int i = 1; int status; if (sigemptyset(&mask) != 0) { perror("sigemptyset error"); } if (sigaddset(&mask, SIGCHLD) != 0) { perror("sigaddset error"); } if (sigprocmask(SIG_BLOCK, &mask, NULL) != 0) { perror("sigprocmask error"); } strncpy(buf, cmd->argv[0], MAXLINE); if (*cmd->argv[cmd->argc - 1] == '&') { cmd->argv[--cmd->argc] = NULL; bg = 1; } else bg = 0; jobListToString(cmd->argv, 0, cmd->argc, buf); if ((pid = fork()) < 0) { perror("fork error"); } else if (pid == 0) { if (sigprocmask(SIG_UNBLOCK, &mask, NULL) != 0) { perror("sigprocmask error"); } if (setpgid(0, 0) < 0) { perror("setpgid error"); } if (execv(abspath, cmd->argv) < 0) printf("%s not found", cmd->argv[0]); } else { if (sigprocmask(SIG_UNBLOCK, &mask, NULL) != 0) { perror("sigprocmask error"); } if (bg) addjob(jobs, pid, BG, buf); else { addjob(jobs, pid, FG, buf); waitpid(pid, &status, WUNTRACED); if (!WIFSTOPPED(status)) deletejob(jobs, pid); } } } /* Exec */
/* * 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) { // Get memory for our parsed input char temp[MAXLINE]; char** argv = (char**)temp; // Return if only newline if (strcmp(cmdline, "\n") == 0) { return; } // Parse the input int background = parseline(cmdline, argv); // Check if built in command if (builtin_cmd(argv) == 0) { // Not a built in command char* programName = argv[0]; // Block sigchild signal sigset_t mask; Sigemptyset(&mask); Sigaddset(&mask, SIGCHLD); Sigprocmask(SIG_BLOCK, &mask, NULL); // Create a child process pid_t pid = Fork(); // Unblock sichild signal Sigprocmask(SIG_UNBLOCK, &mask, NULL); if (pid == 0) { // Child // Assign it a new process group id setpgid(0,0); // Run the external program Execve(programName, argv, environ); } else { // Parent if (background == 0) { // Add it to the list addjob(jobs, pid, FG, cmdline); // Make the shell wait for the process in the fg waitfg(pid); } else { // Add it to the list addjob(jobs, pid, BG, cmdline); // Get the job id int jid = pid2jid(pid); // Print info on background job printf("[%d] (%d) %s", jid, pid, cmdline); } } } return; }
/* * 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 *argv[MAXARGS]; //args for execvp pid_t pid; sigset_t sSet; int stat; if (*cmdline == 10) return; else{ stat= parseline(cmdline, argv); if (argv[0] == NULL) return; /* ignore empty lines */ if(!builtin_cmd(argv)){ //If it is not a user command sigemptyset(&sSet); sigaddset(&sSet,SIGCHLD); sigprocmask(SIG_BLOCK, &sSet,NULL); if((pid = fork()) == 0) { /*Child runs user job*/ setpgrp(); sigprocmask(SIG_UNBLOCK, &sSet,NULL); /*Unblocked after setpgrp() because childpid should be set as group pid first without any interruption */ int stat1=execvp(argv[0], argv); //prints a message if execvp fails. if(stat1 < 0) { //If the command doesnot exists stat1=0; printf("%s: Command not found.\n",argv[0]);//prints a message if execvp fails. exit(0); /*In case execvp fails then exit will get called.*/ } } if(stat) { addjob(jobs, pid, BG, cmdline); /* request for background job then job is added with BG state*/ sigprocmask(SIG_UNBLOCK,&sSet,NULL); /*unblocks signal after adding all jobs without any type of signal*/ printf("[%d] (%d) %s",pid2jid(pid),pid,cmdline); } else { addjob(jobs, pid, FG, cmdline) ; sigprocmask(SIG_UNBLOCK,&sSet,NULL);/*unblocks signal after adding all jobs without any type of signal*/ waitfg(pid);/*parent waits*/ } } } return; }
/* * 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 *argv[MAXARGS]; //int to record for bg int bg; pid_t pid; sigset_t mask; // parse the line bg = parseline(cmdline, argv); //check if valid builtin_cmd if(!builtin_cmd(argv)) { // blocking first sigemptyset(&mask); sigaddset(&mask, SIGCHLD); sigprocmask(SIG_BLOCK, &mask, NULL); // forking if((pid = fork()) < 0){ unix_error("forking error"); } // child else if(pid == 0) { sigprocmask(SIG_UNBLOCK, &mask, NULL); setpgid(0, 0); //check if command is there if(execvp(argv[0], argv) < 0) { printf("%s: Command not found\n", argv[0]); exit(1); } } // parent add job first else { if(!bg){ addjob(jobs, pid, FG, cmdline); } else { addjob(jobs, pid, BG, cmdline); } sigprocmask(SIG_UNBLOCK, &mask, NULL); //if bg/fg if (!bg){ //wait for fg waitfg(pid); } else { //print for bg printf("[%d] (%d) %s", pid2jid(pid), pid, cmdline); } } } }
/* * 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 *argv[MAXARGS]; int bg; pid_t pid; sigset_t mask; sigemptyset(&mask); sigaddset(&mask, SIGCHLD); bg=parseline(cmdline, argv); if(!builtin_cmd(argv)){ sigprocmask(SIG_BLOCK, &mask, 0); /* Fork */ if((pid=fork())<0){ unix_error("fork error"); return; } /* Child process */ else if(pid==0){ if(setpgid(0,0)<0) unix_error("setpgid error"); if (execvp(argv[0], argv) < 0) { printf("%s: Command not found. \n", argv[0]); exit(0); } } /* Parent process */ else{ if(bg==1){ addjob(jobs, pid, BG, cmdline); sigprocmask(SIG_UNBLOCK, &mask, 0); printf("[&d] (%d) %s", pid2jid(pid), pid, cmdline); } else{ addjob(jobs, pid, FG, cmdline); sigprocmask(SIG_UNBLOCK, &mask, 0); waitfg(pid); } } } return; }
/* * 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 *argv[MAXARGS]; char buf[MAXLINE]; int bg; pid_t pid; sigset_t mask; strcpy(buf,cmdline); bg = parseline(buf,argv); if (argv[0] == NULL) return; if (!builtin_cmd(argv)) { sigemptyset(&mask); sigaddset(&mask,SIGCHLD); sigprocmask(SIG_BLOCK,&mask,NULL); if ((pid = fork()) < 0) { perror("fork"); exit(0); } else if (pid == 0) { sigprocmask(SIG_UNBLOCK,&mask,NULL); if (execvp(argv[0], argv) < 0) { printf("%s : Command not found.\n", argv[0]); exit(0); } } if (bg) addjob(jobs,pid,BG,buf); else addjob(jobs,pid,FG,buf); sigprocmask(SIG_UNBLOCK,&mask,NULL); if (!bg) { waitfg(pid); } else { printf("%d %s",(int)pid, cmdline); } } return; }
/* * 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) { /* the following code demonstrates how to use parseline --- you'll * want to replace most of it (at least the print statements). */ int i, bg, job_loc; char *argv[MAXARGS]; bg = parseline(cmdline, argv); if (bg) { // printf("background job requested\n"); } for (i=0; argv[i] != NULL; i++) { // printf("argv[%d]=%s%s", i, argv[i], (argv[i+1]==NULL)?"\n":", "); } if (builtin_cmd(&argv[0]) == 0){ return; }else{ int pid; sigset_t mask; sigemptyset(&mask); sigaddset(&mask, SIGCHLD); sigprocmask(SIG_BLOCK, &mask, NULL); if((pid=fork())==0){ setpgid(0, 0); if(execvp(argv[0], argv)< 0){ printf("Command not found\n"); deletejob(jobs, pid); exit(0); } } if (!bg){ job_loc=addjob(jobs,pid,FG,cmdline); sigprocmask(SIG_UNBLOCK, &mask, NULL); waitfg(pid); } else{ job_loc=addjob(jobs,pid,BG,cmdline); printf("[%d] (%d) %s",job_loc, pid, cmdline); sigprocmask(SIG_UNBLOCK, &mask, NULL); } return; } }
void eval(char *cmdline) { char *argv[MAXARGS]; int argc = 0; int bg = parseline(cmdline, argv, &argc); pid_t pid = -1; sigprocmask(SIG_BLOCK,&maskchld,NULL); if(builtin_cmd(argv,argc)) return; if(bg) { pid = Fork(); if(pid==0) { setpgid(0,0); sigprocmask(SIG_UNBLOCK,&maskchld,NULL); Signal(SIGINT, SIG_DFL); Signal(SIGTSTP, SIG_DFL); if(execv(argv[0], argv) < 0) { printf("%s: Command not found\n",argv[0]); exit(0); } return; } addjob(jobs,pid,BG,cmdline); struct job_t* job = getjobpid(jobs,pid); printf("[%d] (%d) ", job->jid, job->pid); printf("%s", job->cmdline); sigprocmask(SIG_UNBLOCK,&maskchld,NULL); } else { pid=Fork(); if(pid==0){ setpgid(0,0); sigprocmask(SIG_UNBLOCK,&maskchld,NULL); Signal(SIGTSTP,SIG_DFL); Signal(SIGINT,SIG_DFL); if(execv(argv[0],argv) < 0){ printf("%s: Command not found\n",argv[0]); exit(0); } } addjob(jobs,pid,FG,cmdline); sigprocmask(SIG_UNBLOCK,&maskchld,NULL); waitfg(pid); return; } return; }
/* * 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) { int bg; /* should the job run in bg or fg? */ struct cmdline_tokens tok; struct job_t *jobinfo; pid_t pid; sigset_t wait; /* Parse command line */ bg = parseline(cmdline, &tok); if (bg == -1) /* parsing error */ return; if (tok.argv[0] == NULL) /* ignore empty lines */ return; if(!buildinCmd(&tok)){ blockAllSignal(); if((pid = fork()) == 0){ //child if(setpgid(0, 0) < 0){ unix_error("process set prcess group error\n"); } IORedirect(&tok); unblockAllSignal(); if(execve(tok.argv[0], tok.argv, environ) == -1){ printf("%s, command not found\n", tok.argv[0]); exit(0); } }else{ //parent if(!bg){ addjob(job_list, pid, FG, cmdline); sigemptyset(&wait); sigsuspend(&wait); unblockAllSignal(); while(fgpid(job_list) != 0) { sigsuspend(&wait); } }else{ addjob(job_list, pid, BG, cmdline); jobinfo = getjobpid(job_list, pid); printf("[%d] (%d) %s\n", jobinfo->jid, jobinfo->pid, jobinfo->cmdline); unblockAllSignal(); } } } return; }
/* * 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 *argv[MAXARGS]; int bg=parseline(cmdline,argv); int p=builtin_cmd(&argv[0]); int childpid; bg++; //because the background process is defined as 2 and foreground as 1 sigset_t set; sigemptyset(&set); sigaddset(&set,SIGCHLD); sigaddset(&set,SIGINT); sigaddset(&set,SIGTSTP); if(!p) { if((childpid=fork())==0) { setpgid(0,0); //Changing group id execve(argv[0], argv, NULL); printf("Command not found\n");//If incase there is no command exit(0); } else { sigprocmask(SIG_BLOCK,&set,NULL); //masking if incase child executes first addjob(jobs,childpid,bg,cmdline); sigprocmask(SIG_UNBLOCK,&set,NULL);//remove mask if(bg==1) waitfg(childpid); else printf("[%d] (%d) %s",pid2jid(childpid),childpid,cmdline); } } return; }
/* * 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 *argv[MAXARGS]; /* argv for execve() */ int bg; pid_t pid; bg = parseline(cmdline, argv); if(argv[0] == NULL) return; /* ignore empty lines */ if(!builtin_cmd(argv)) { if((pid = fork()) < 0) unix_error("eval(): fork() error"); if(pid == 0) /* child runs user job */ { if(setpgid(0,0) < 0) unix_error("eval(): setpgid() error"); if(execve(argv[0], argv, environ) < 0) { printf("%s: Command not found.\n", argv[0]); exit(0); } } addjob(jobs,pid,(bg == 1 ? BG : FG),cmdline); sigprocmask(SIG_UNBLOCK,&mask,NULL); if(!bg) waitfg(pid); else printf("[%d] (%d) %s",pid2jid(pid),pid,cmdline); } return; }
/*function used to run user command using execvp*/ void run(char *input,char *usrcmdargs[],int is_background){ int pid1; pid1=fork(); struct job_t *tempjob_list; if(pid1 == 0){ close(fdin); close(fdout); //execvp return -1 if command do not exist, if it is successful, it do not return any value err=execvp(usrcmdargs[0],usrcmdargs); printf("errno is %d\n", errno); if(err == -1){ printf("command do not exist\n"); exit(EXIT_FAILURE); } exit(0); } else if(is_background != 0){ addjob(job_list,pid1,BKG,input); tempjob_list=getjob(job_list,pid1); printf("[%d] %d running in background\n",tempjob_list->jid,pid1); } else{ //addjob(job_list,pid1,FRG,input); waitpid(pid1,&status, 0); } }
/* * handle the parent process */ void handle_parent_process(struct cmdline_tokens* toks, int bg, pid_t pid, sigset_t* oldset, char* cmdline) { sigset_t emptyset; if(!addjob(job_list, pid, bg?BG:FG, cmdline)){ unix_error("error in addjob"); } struct job_t* job = getjobpid(job_list, pid); if(!bg){ if(sigprocmask(SIG_SETMASK, oldset, NULL)){ unix_error("error in parent process's sigprocmask"); } if(sigemptyset(&emptyset)){ unix_error("set is not empty"); } while(fgpid(job_list) && job -> state == FG) sigsuspend(&emptyset); } else { printf("[%d] (%d) %s\n", job->jid, job->pid, job->cmdline); if(sigprocmask(SIG_SETMASK, oldset, NULL)){ unix_error("error in parent process's sigprocmask"); } } }
/* * 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 *argv[MAXARGS]; /* int ground = parseline(cmdline, (char **)&argv); */ char buf[MAXLINE]; // Holds modified command line strcpy(buf, cmdline); int ground = parseline(buf, argv); if (argv[0] == NULL) return; if (!builtin_cmd((char **)&argv)) { sigset_t mask; sigemptyset(&mask); sigaddset(&mask, SIGCHLD); sigprocmask(SIG_BLOCK, &mask, NULL); pid_t pid = __fork(); if (pid != 0) { addjob(jobs, pid, ground ? BG : FG, cmdline); sigprocmask(SIG_UNBLOCK, &mask, NULL); if (!ground) waitfg(pid); else printf("[%d] (%d) %s", pid2jid(pid), pid, cmdline); } else { __setpgid(0, 0); sigprocmask(SIG_UNBLOCK, &mask, NULL); if (execve(argv[0], argv, environ) < 0) { printf("%s: Command not found\n", argv[0]); exit(0); } } } return; }
int main(int argc, char **argv) { int pid; sigset_t mask; Signal(SIGCHLD, handler); initjobs(); /* Initialize the job list */ while (1) { Sigemptyset(&mask); Sigaddset(&mask, SIGCHLD); Sigprocmask(SIG_BLOCK, &mask, NULL); /* Block SIGCHLD */ /* Child process */ if ((pid = Fork()) == 0) { Sigprocmask(SIG_UNBLOCK, &mask, NULL); /* Unblock SIGCHLD */ Execve("/bin/ls", argv, NULL); } /* Parent process */ addjob(pid); /* Add the child to the job list */ Sigprocmask(SIG_UNBLOCK, &mask, NULL); /* Unblock SIGCHLD */ } exit(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 *argv[MAXARGS]; char buf[MAXLINE]; int bg = 0; pid_t pid; int status = 0; strcpy(buf, cmdline); bg = parseline(buf, argv); if(argv[0] == NULL){ return ; } #ifdef DEBUG_MSG_EVAL printf("cmdline is %s\n",cmdline); fflush(stdout); #endif if(!builtin_cmd(argv)){ sigset_t mask; sigemptyset(&mask); sigaddset(&mask, SIGCHLD); sigprocmask(SIG_BLOCK, &mask, NULL); if((pid = fork()) == 0){ sigprocmask(SIG_UNBLOCK, &mask, NULL); setpgid(0,0); if(execve(argv[0], argv, environ) < 0){ printf("%s: Command not found\n", argv[0]); exit(0); } } if(!bg){ status = FG; addjob(jobs,pid,status, cmdline); sigprocmask(SIG_UNBLOCK, &mask, NULL); waitfg(pid); }else{ status = BG; addjob(jobs,pid,status, cmdline); printf("[%d] (%d) %s", getjobpid(jobs, pid)->jid, pid, cmdline); sigprocmask(SIG_UNBLOCK, &mask, NULL); } } return; }
/* * 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 *argv[MAXARGS]; // Parse command line. int isbg = parseline(cmdline, argv); pid_t pid; struct job_t *tmpjob; // Set sigset_t. sigset_t sig; sigemptyset(&sig); sigaddset(&sig, SIGCHLD); if( argv[0] == NULL ) // If input has no string, then return. return; if(!builtin_cmd(argv)) { // When cmdline is not builtin command. sigprocmask(SIG_BLOCK, &sig, NULL); // block SIGCHLD if( (pid = fork()) < 0) // When fork error occurs. return; else if( pid == 0 ) { //Child setpgid(0, 0); sigprocmask(SIG_UNBLOCK, &sig, NULL); // unblock SIGCHLD if(execve(argv[0], argv, environ) < 0) { // If command not found. printf("%s: Command not found\n", argv[0]); exit(0); } } else { // Parent if(isbg) { // When background addjob(jobs, pid, BG, cmdline); // Add to joblist(with state: BG) tmpjob = getjobpid(jobs, pid); printf("[%d] (%d) %s", tmpjob->jid, tmpjob->pid, tmpjob->cmdline); sigprocmask(SIG_UNBLOCK, &sig, NULL); // unblock SIGCHLD. } else { // foreground addjob(jobs, pid, FG, cmdline); // Add to joblist with state is FG. sigprocmask(SIG_UNBLOCK, &sig, NULL); // unblock SIGCHLD waitfg(pid); // wait foreground job. } } } return; }
/* * 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. * 70 lines */ void eval(char *cmdline) { char * argv[MAXARGS]; char buf[MAXLINE]; int bg = 0; sigset_t mask; pid_t pid = 0; strcpy(buf, cmdline); bg = parseline(buf,argv); if(argv[0] == NULL) return; // ignore empty line if(!builtin_cmd(argv)) { if(sigemptyset(&mask) <0) unix_error("sigemptyset error"); if(sigaddset(&mask, SIGCHLD) <0) unix_error("sigaddset error"); if(sigprocmask(SIG_BLOCK, &mask, NULL) < 0) unix_error("sigprocmask error block"); pid = fork(); if (pid < 0) unix_error("fork error"); else if((pid == 0))//child process { if(setpgid(0,0) < 0) unix_error("setpgid error"); if(sigprocmask(SIG_UNBLOCK, &mask, NULL) < 0) unix_error("sigprocmask error unblock"); if(execve(argv[0],argv,environ) < 0)//run task { printf("%s: Command not found\n", argv[0]); exit(0); } } if(bg) { printf("[%d] (%d) %s",nextjid, pid, cmdline); addjob(jobs,pid,BG,cmdline); } else addjob(jobs,pid,FG,cmdline); if(sigprocmask(SIG_UNBLOCK, &mask, NULL)<0) unix_error("sigprocmask error unblock"); if(!bg) { waitfg(pid); } } return; }
/* * 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 *argv[MAXARGS]; memset(argv, 0, sizeof(void*) * MAXARGS); int bg = parseline(cmdline, argv); if(!argv[0]) return; if(builtin_cmd(argv)) return; //printf("%s\n", argv[0]); sigset_t mask,mask_all,prev_mask; sigemptyset(&mask); sigfillset(&mask_all); sigaddset(&mask,SIGCHLD); sigprocmask(SIG_BLOCK, &mask, &prev_mask); pid_t pid = fork(); //Run the job in child process if(pid == 0) { setpgid(pid,pid); sigprocmask(SIG_SETMASK, &prev_mask, NULL); int result = execve(argv[0],argv,environ); if(result) { fprintf(stderr,"%s: Command not found\n", argv[0]); exit(0); } } //Parent process else { sigprocmask(SIG_BLOCK, &mask_all, NULL); if(bg) { addjob(jobs,pid,BG,cmdline); printf("[%d] (%d) %s", jobs->jid, pid, cmdline); sigprocmask(SIG_SETMASK, &prev_mask,NULL); } else{ addjob(jobs,pid,FG,cmdline); sigprocmask(SIG_SETMASK, &prev_mask, NULL); waitfg(pid); } } return; }
/* * 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 *argv[MAXARGS];//argv will hold all of the parsed args pid_t pid; sigset_t mask; int background_job = parseline(cmdline, argv); //returns 1 if bg if(argv[0] == NULL){//no input return; } int builtin_job = builtin_cmd(argv); //returns 0 if not built in if(!builtin_job){ sigemptyset(&mask); sigaddset(&mask, SIGCHLD); sigprocmask(SIG_BLOCK,&mask,NULL); pid = fork(); if(pid == 0){ //child setpgid(0,0); sigprocmask(SIG_UNBLOCK,&mask,NULL); if(execvp(argv[0], argv) < 0){ printf("%s: Command not found.\n", argv[0]); exit(0); } } else{//parent if(background_job){ addjob(jobs, pid, BG, cmdline); printf("[%d] (%d) %s", pid2jid(pid), pid, cmdline); } else{ addjob(jobs, pid, FG, cmdline); } sigprocmask(SIG_UNBLOCK,&mask,NULL); if(!background_job){//wait until job is done waitfg(pid); //stuck } } } return; }
/* * 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 *argv[MAXARGS]; char buf[MAXLINE]; int bg; pid_t pid; strcpy(buf,cmdline); bg=parseline(buf,argv); if(argv[0]==NULL) return; if(!builtin_cmd(argv)) { sigset_t mask; sigemptyset(&mask); sigprocmask(SIG_BLOCK,&mask,NULL); if((pid=fork())==0) { sigprocmask(SIG_UNBLOCK,&mask,NULL); if(execve(argv[0],argv,NULL)<0){ printf("%s: Command not found\n",argv[0]); exit(0); } } if(!bg) { if(setpgid(pid,pid)<0) unix_error("setpgid: setpgid error"); if(!addjob(jobs,pid,FG,buf)) app_error("addjob: addjob error"); sigprocmask(SIG_UNBLOCK,&mask,NULL); waitfg(pid); } else { if(setpgid(pid,pid)<0) unix_error("setpgid: setpgid error"); if(!addjob(jobs,pid,BG,buf)) app_error("addjob: addjob error"); sigprocmask(SIG_UNBLOCK,&mask,NULL); printf("[%d] (%d) %s",getjobpid(jobs,pid)->jid,pid,cmdline); } } return; }
/* * 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 *argv[MAXARGS]; int bg; pid_t pid; sigset_t signals; bg = parseline(cmdline, argv); if (argv[0] == NULL) return; if (bg != -1 && !builtin_cmd(argv)) { sigemptyset(&signals); sigaddset(&signals, SIGCHLD); sigprocmask(SIG_BLOCK, &signals, NULL); if ((pid = fork()) == 0) { if (setpgid(0, 0) < 0) unix_error("setpgid failed"); if (execve(argv[0], argv, environ) < 0) { printf("%s: Command not found\n", argv[0]); exit(0); } } if (!bg) addjob(jobs, pid, FG, cmdline); else addjob(jobs, pid, BG, cmdline); sigprocmask(SIG_UNBLOCK, &signals, NULL); if (!bg) waitfg(pid); else printf("[%d] (%d) %s", pid2jid(pid), pid, cmdline); } return; }