void daemon_init(const char *pname, int facility, int nochdir, int noclose) { pid_t pid; if ( (pid = Fork()) != 0) exit(0); /* parent terminates */ /* 41st child continues */ setsid(); /* become session leader */ Signal(SIGHUP, SIG_IGN); if ( (pid = Fork()) != 0) exit(0); /* 1st child terminates */ /* 42nd child continues */ if (nochdir == 0) chdir("/"); /* change working directory */ umask(0); /* clear our file mode creation mask */ if (noclose == 0) { int fd = Open("/dev/null", O_RDWR); Dup2(fd, 0); Dup2(fd, 1); Dup2(fd, 2); if (fd > 2) Close(fd); } daemon_proc = 1; /* for our err_XXX() functions */ openlog(pname, LOG_PID, facility); }
void IO_redirection(struct cmdline_tokens tok) { int fd; if(tok.outfile != NULL) { fd = Open(tok.outfile, O_WRONLY|O_CREAT,0); Dup2(fd,STDOUT_FILENO); } if(tok.infile != NULL) { fd = Open(tok.infile,O_RDONLY|O_CREAT,0); Dup2(fd,STDIN_FILENO); } }
void requestServeDynamic(int fd, char *filename, char *cgiargs, request* req) { char buf[MAXLINE], *emptylist[] = {NULL}; /* The server does only a little bit of the header. */ /* The CGI script has to finish writing out the header. */ sprintf(buf, "HTTP/1.0 200 OK\r\n"); sprintf(buf, "%s Server: Tiny Web Server\r\n", buf); /* CS537: Your statistics go here -- fill in the 0's with something * useful! */ sprintf(buf, "%s Stat-req-arrival: %f\r\n", buf, toMS(req->req_arrival)); sprintf(buf, "%s Stat-req-dispatch: %f\r\n", buf, toMS(req->req_dispatch)); sprintf(buf, "%s Stat-thread-id: %d\r\n", buf, req->t_stats.thread_id); sprintf(buf, "%s Stat-thread-count: %d\r\n", buf, req->t_stats.thread_count); sprintf(buf, "%s Stat-thread-static: %d\r\n", buf, req->t_stats.thread_static); sprintf(buf, "%s Stat-thread-dynamic: %d\r\n", buf, req->t_stats.thread_dynamic); Rio_writen(fd, buf, strlen(buf)); if(Fork() == 0) { /* Child process */ Setenv("QUERY_STRING", cgiargs, 1); /* When the CGI process writes to stdout, it will instead go to * the socket */ Dup2(fd, STDOUT_FILENO); Execve(filename, emptylist, environ); } Wait(NULL); }
void executeScripts(char *phpScript, int numProcesses) { pid_t child_pid; char *argv[] = {"/usr/bin/php", phpScript, 0}; char *envp[] = {0}; int i = 0; for (; i < numProcesses; i++) { child_pid = Fork(); if (child_pid == 0) { // change stdout to log file char logFile[25]; sprintf(logFile, "logs/%s%d.log", phpScript, i); int fd = Open(logFile, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); Dup2(fd, 1); // make stdout go to file Close(fd); // execute script execve("/usr/bin/php", argv, envp); exit(0); } else { printf("Executing php script '%s' in process %d.\n", phpScript, i); } } }
void interaction::traceIpHost(const char* ipHost) { //----------------------- // check if we over limit //----------------------- if(rLimitor->isOverLimit()) { // notify user dprintf(connfd, "*********************************************\n"); dprintf(connfd, "Making too many requests than you can\n"); dprintf(connfd, "%s\n",rLimitor->currentLimit()); dprintf(connfd, "*********************************************\n"); // log it extern eventsLog servLog; servLog.logIt("User from IP: %s (with pid %d)" " making too many requests\n", userIp(*clientAddr), getpid()); return; } //--------------------------------------------- // check if ip hinted by ipHost is valid or not //--------------------------------------------- if(strict) { if(!isValidIp(ipHost)) { return; } } pid_t child_pid; if((child_pid=fork())<0) { sys_err("call to fork() failed"); } else if(child_pid==0) { // in child // Close stuff from parents // redirect stderr and stdout to connfd Dup2(connfd, STDOUT_FILENO); Dup2(connfd, STDERR_FILENO); cout<<"------------------------------------------" <<"----------------------------------"<<endl; // call execlp 'NULL' must be provided execlp("traceroute","traceroute",ipHost, NULL); } else {// in parent if(VOMIT) { cout<<"client interaction process: "<<getpid() <<" forked a child with pid: "<<child_pid<<endl; } // block until child finish waitpid(child_pid, NULL, 0); } }
/* $begin get_dynamic */ void get_dynamic(int fd, char *filename, char *cgiargs) { char buf[MAXLINE], *emptylist[] = { NULL },httpsbuf[MAXLINE]; int p[2]; /* Return first part of HTTP response */ sprintf(buf, "HTTP/1.0 200 OK\r\n"); sprintf(buf, "%sServer: Tiny Web Server\r\n",buf); if(ishttps) SSL_write(ssl,buf,strlen(buf)); else Rio_writen(fd, buf, strlen(buf)); if(ishttps) { if(pipe(p)==-1) syslog(LOG_ERR,"cannot create pipe"); if (Fork() == 0) { /* child */ close(p[0]); setenv("QUERY_STRING", cgiargs, 1); Dup2(p[1], STDOUT_FILENO); /* Redirect stdout to p[1] */ Execve(filename, emptylist, environ); /* Run CGI program */ } close(p[1]); Read(p[0],httpsbuf,MAXLINE); /* parent read from p[0] */ SSL_write(ssl,httpsbuf,strlen(httpsbuf)); Wait(NULL); /* Parent waits for and reaps child */ } else { if (Fork() == 0) { /* child */ /* Real server would set all CGI vars here */ setenv("QUERY_STRING", cgiargs, 1); Dup2(fd, STDOUT_FILENO); /* Redirect stdout to client */ Execve(filename, emptylist, environ); /* Run CGI program */ } Wait(NULL); /* Parent waits for and reaps child */ } }
/* $begin post_dynamic */ void post_dynamic(int fd, char *filename, int contentLength,rio_t *rp) { char buf[MAXLINE],length[32], *emptylist[] = { NULL },data[MAXLINE]; int p[2]; sprintf(length,"%d",contentLength); if(pipe(p)==-1) syslog(LOG_ERR,"cannot create pipe"); /* The post data is sended by client,we need to redirct the data to cgi stdin. * so, child read contentLength bytes data from fp,and write to p[1]; * parent should redirct p[0] to stdin. As a result, the cgi script can * read the post data from the stdin. */ if(!ishttps) /* https already read all data ,include post data by SSL_read() */ { if (Fork() == 0) { /* child */ close(p[0]); Rio_readnb(rp,data,contentLength); Rio_writen(p[1],data,contentLength); exit(0) ; } } else { } /* Send response headers to client */ sprintf(buf, "HTTP/1.0 200 OK\r\n"); Rio_writen(fd, buf, strlen(buf)); sprintf(buf, "Server: Tiny Web Server\r\n"); Rio_writen(fd, buf, strlen(buf)); Dup2(p[0],STDIN_FILENO); /* Redirct p[0] to stdin */ close(p[0]); close(p[1]); setenv("CONTENT-LENGTH",length , 1); Dup2(fd,STDOUT_FILENO); /* Redirct stdout to client */ Execve(filename, emptylist, environ); }
/* open_dup2_in - redirect stdin to input file descripter */ void open_dup2_in(char *infile) { int fd; if (infile != NULL) { if ((fd = Open(infile, O_RDONLY, 0)) > 0) { if (Dup2(fd, STDIN_FILENO) > 0) { Close(fd); } } } }
char fork_process(char *argv[], int fd_in, int fd_out, int fd_errout, int sockfd) { pid_t child_pid = Fork(); if (child_pid > 0) { // parent printf("Child spawn with pid: %d\n", child_pid); int status = 0; while( (wait( &status ) == -1) && (errno == EINTR) ); if (WIFEXITED(status)) { char exit_code = WEXITSTATUS(status); printf("Child pid (%d) exit code: %d\n", child_pid, exit_code); return exit_code; } else { printf("Child pid (%d) crash status: %x\n", child_pid, status); return 0; } } else if (child_pid == 0) { // child if (fd_in != -1) { Dup2(fd_in, STDIN_FILENO); Close(fd_in); } Dup2(fd_out, STDOUT_FILENO); Dup2(fd_errout, STDERR_FILENO); Close(fd_out); if (fd_out != fd_errout) Close(fd_errout); execvp(argv[0], argv); exit(ERR_CMD_NOT_FOUND); } else { err_sys("fork failed"); } return 0; }
/* open_dup2_out - redirect stdout to output file descripter */ void open_dup2_out(char *outfile) { int fd; if (outfile != NULL) { /* If not exist, then create */ if ((fd = Open(outfile, O_CREAT | O_WRONLY, DEF_MODE)) > 0) { if (Dup2(fd, STDOUT_FILENO) > 0) { Close(fd); } } } }
int main() { int fd1, fd2; char c; fd1 = Open("foobar.txt", O_RDONLY, 0); fd2 = Open("foobar.txt", O_RDONLY, 0); Read(fd2, &c, 1); Dup2(fd2, fd1); Read(fd1, &c, 1); printf("c = %c\n", c); exit(0); }
/* create ring of n processes */ int main(int argc, char *argv[]) { int nproc; int fd[2]; pid_t pid; int i, status; status = nproc = pid = 0; fd[0] = fd[1] = 0; if (argc != 2 || ((nproc = atoi(argv[1])) <= 0)) err_quit("Uasge: %s processes", argv[0]); fprintf(stderr, "Creating ring of %d processes\n", nproc+1); Pipe(fd); Dup2(fd[0], STDIN_FILENO); Dup2(fd[1], STDOUT_FILENO); Close(fd[0]); Close(fd[1]); for (i = 0; i < nproc; i++) { Pipe(fd); if ((pid = Fork()) > 0) Dup2(fd[1], STDOUT_FILENO); else Dup2(fd[0], STDIN_FILENO); Close(fd[0]); Close(fd[1]); if (pid > 0) break; } if (pid > 0) if (wait(&status) == -1) err_sys("wait error"); fprintf(stderr, "This is process: %d, ID: %ld parent: %ld\n", i , (long)getpid(), (long)getppid()); return 0; }
/* * serve_dynamic- run a CGI program on behalf of the client */ void serve_dynamic(int fd, char *filename, char *cgiargs) { char buf[MAXLINE], *emptylist[] = {NULL}; sprintf(buf, "HTTP/1.0 200 OK\r\n"); Rio_writen(fd, buf, strlen(buf)); sprintf(buf, "Server: Tiny Web Server\r\n"); Rio_writen(fd, buf, strlen(buf)); if (Fork() == 0) { setenv("QUERY_STRING", cgiargs, 1); Dup2(fd, STDOUT_FILENO); Execve(filename, emptylist, environ); } Wait(NULL); }
/* $begin serve_dynamic */ void serve_dynamic(int fd, char *filename, char *cgiargs) { char buf[MAXLINE]; /* Return first part of HTTP response */ sprintf(buf, "HTTP/1.0 200 OK\r\n"); Rio_writen(fd, buf, strlen(buf)); sprintf(buf, "Server: Tiny Web Server\r\n"); Rio_writen(fd, buf, strlen(buf)); Dup2(fd, STDOUT_FILENO); /* Redirect stdout to client */ //line:netp:servedynamic:dup2 int result = functionstub(cgiargs); printf("%d", result); }
int main(int argc, char *argv[]) { int fd1, fd2, fd3; char c1, c2, c3; char *fname = argv[1]; fd1 = Open(fname, O_RDONLY, 0); fd2 = Open(fname, O_RDONLY, 0); fd3 = Open(fname, O_RDONLY, 0); Dup2(fd2, fd3); Read(fd1, &c1, 1); Read(fd2, &c2, 1); Read(fd3, &c3, 1); printf("c1 = %c, c2 = %c, c3 = %c\n", c1, c2, c3); return 0; }
static int xioopen_system(int argc, const char *argv[], struct opt *opts, int xioflags, /* XIO_RDONLY etc. */ xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3 ) { int status; char *path = NULL; int duptostderr; int result; const char *string = argv[1]; status = _xioopen_foxec(xioflags, &fd->stream, groups, &opts, &duptostderr); if (status < 0) return status; if (status == 0) { /* child */ int numleft; /* do not shutdown connections that belong our parent */ sock[0] = NULL; sock[1] = NULL; if (setopt_path(opts, &path) < 0) { /* this could be dangerous, so let us abort this child... */ Exit(1); } if ((numleft = leftopts(opts)) > 0) { Error1("%d option(s) could not be used", numleft); showleft(opts); return STAT_NORETRY; } /* only now redirect stderr */ if (duptostderr >= 0) { diag_dup(); Dup2(duptostderr, 2); } Info1("executing shell command \"%s\"", string); errno=0; result = System(string); if (result != 0) { Warn2("system(\"%s\") returned with status %d", string, result); if (errno != 0) Warn1("system(): %s", strerror(errno)); } Exit(result>>8); /* this child process */ }
/* * serve_dynamic - serve dynamic content */ void serve_dynamic(int connfd, char* filename, char* cgiargs) { char body[MAXBUF], *emptylist[] = {NULL}; /* send response headers to client */ sprintf(body, "HTTP/1.0 200 OK\r\n"); sprintf(body, "%sServer: Tiny Web Server\r\n", body); Rio_writen(connfd, body, strlen(body)); if (Fork() == 0) { /* fork a new child */ setenv("QUERY_STRING", cgiargs, 1); Dup2(connfd, STDOUT_FILENO); /* redirect stdout to connfd */ Execve(filename, emptylist, environ); } Wait(NULL); /* parent wait */ }
void serve_dynamic(int fd, char* filename, char* cgiargs) { char buf[MAXLINE], *emptylist[] = {NULL}; //return first part of HTTP response sprintf(buf, "HTTP/1.0 200 0k\r\n"); Rio_writen(fd, buf, strlen(buf)); sprintf(buf, "Server: Tiny Web Server\r\n"); Rio_writen(fd, buf, strlen(buf)); if (Fork() == 0) { //child //real server would set all cgi vars here setenv("QUERY_STRING", cgiargs, 1); Dup2(fd, STDOUT_FILENO); // redirect stdout to client Execve(filename, emptylist, environ); //Run cgi program } Wait(NULL); //parent waits for and reaps child }
/* $begin serve_dynamic */ void serve_dynamic(int fd, char *filename, char *cgiargs) { char buf[MAXLINE], *emptylist[] = { NULL }; /* Return first part of HTTP response */ sprintf(buf, "HTTP/1.0 200 OK\r\n"); Rio_writen(fd, buf, strlen(buf)); sprintf(buf, "Server: Tiny Web Server\r\n"); Rio_writen(fd, buf, strlen(buf)); if (Fork() == 0) { /* child */ //line:netp:servedynamic:fork /* Real server would set all CGI vars here */ setenv("QUERY_STRING", cgiargs, 1); //line:netp:servedynamic:setenv Dup2(fd, STDOUT_FILENO); /* Redirect stdout to client */ //line:netp:servedynamic:dup2 Execve(filename, emptylist, environ); /* Run CGI program */ //line:netp:servedynamic:execve } Wait(NULL); /* Parent waits for and reaps child */ //line:netp:servedynamic:wait }
void serve_dynamic(int fd, char *filename, char *cgiargs) { char buf[MAXLINE], *emptylist[] = { NULL }; /* Return first part of HTTP response */ sprintf(buf, "HTTP/1.0 200 OK\r\n"); Rio_writen(fd, buf, strlen(buf)); sprintf(buf, "Server: Tiny Web Server\r\n"); Rio_writen(fd, buf, strlen(buf)); if (Fork() == 0) { /* Child */ /* Real server would set all CGI vars here */ setenv("QUERY_STRING", cgiargs, 1); Dup2(fd, STDOUT_FILENO); /* 重定向标准输出 */ Execve(filename, emptylist, environ); /* Run CGI program */ } Wait(NULL); /* 等待子进程终止 */ }
void requestServeDynamic(int fd, char *filename, char *cgiargs) { char buf[MAXLINE], *emptylist[] = {NULL}; // The server does only a little bit of the header. // The CGI script has to finish writing out the header. sprintf(buf, "HTTP/1.0 200 OK\r\n"); sprintf(buf, "%sServer: CS537 Web Server\r\n", buf); Rio_writen(fd, buf, strlen(buf)); if (Fork() == 0) { /* Child process */ Setenv("QUERY_STRING", cgiargs, 1); /* When the CGI process writes to stdout, it will instead go to the socket */ Dup2(fd, STDOUT_FILENO); Execve(filename, emptylist, environ); } Wait(NULL); }
/* $begin serve_dynamic */ void serve_dynamic(int fd, char *filename, char *cgiargs, rio_t *rp) { char buf[MAXLINE], *emptylist[] = { NULL }; /* Return first part of HTTP response */ sprintf(buf, "HTTP/1.0 200 OK\r\n"); Rio_writen(fd, buf, strlen(buf)); sprintf(buf, "Server: Tiny Web Server\r\n"); Rio_writen(fd, buf, strlen(buf)); if (Fork() == 0) { /* child */ /* Real server would set all CGI vars here */ read_request(rp, cgiargs); setenv("QUERY_STRING", cgiargs, 1); fprintf(stderr, "%s: %s\r\n", "QUERY_STRING", cgiargs); Dup2(fd, STDOUT_FILENO); /* Redirect stdout to client */ Execve(filename, emptylist, environ); /* Run CGI program */ } Wait(NULL); /* Parent waits for and reaps child */ }
pid_t child_make(int i, int listenfd, int addrlen) { int sockfd[2]; pid_t pid; void child_main(int, int, int); Socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd); if ( (pid = Fork()) > 0) { Close(sockfd[1]); cptr[i].child_pid = pid; cptr[i].child_pipefd = sockfd[0]; cptr[i].child_status = 0; return(pid); /* parent */ } Dup2(sockfd[1], STDERR_FILENO); /* child's stream pipe to parent */ Close(sockfd[0]); Close(sockfd[1]); Close(listenfd); /* child does not need this open */ child_main(i, listenfd, addrlen); /* never returns */ }
/* ring_dup_in: duplicate write file descriptor */ static void ring_dup_out(struct ring *r) { Dup2(r->fd[OUT], r->out); }
static int xioopen_exec(int argc, const char *argv[], struct opt *opts, int xioflags, /* XIO_RDONLY, XIO_MAYCHILD etc. */ xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3 ) { int status; bool dash = false; int duptostderr; if (argc != 2) { Error3("\"%s:%s\": wrong number of parameters (%d instead of 1)", argv[0], argv[1], argc-1); } retropt_bool(opts, OPT_DASH, &dash); status = _xioopen_foxec(xioflags, &fd->stream, groups, &opts, &duptostderr); if (status < 0) return status; if (status == 0) { /* child */ const char *ends[] = { " ", NULL }; const char *hquotes[] = { "'", NULL }; const char *squotes[] = { "\"", NULL }; const char *nests[] = { "'", "'", "(", ")", "[", "]", "{", "}", NULL } ; char **pargv = NULL; int pargc; size_t len; const char *strp; char *token; /*! */ char *tokp; char *path = NULL; char *tmp; int numleft; /*! Close(something) */ /* parse command line */ Debug1("child: args = \"%s\"", argv[1]); pargv = Malloc(8*sizeof(char *)); if (pargv == NULL) return STAT_RETRYLATER; len = strlen(argv[1])+1; strp = argv[1]; token = Malloc(len); /*! */ tokp = token; if (nestlex(&strp, &tokp, &len, ends, hquotes, squotes, nests, true, true, false) < 0) { Error("internal: miscalculated string lengths"); } *tokp++ = '\0'; pargv[0] = strrchr(tokp-1, '/'); if (pargv[0] == NULL) pargv[0] = token; else ++pargv[0]; pargc = 1; while (*strp == ' ') { while (*++strp == ' ') ; if ((pargc & 0x07) == 0) { pargv = Realloc(pargv, (pargc+8)*sizeof(char *)); if (pargv == NULL) return STAT_RETRYLATER; } pargv[pargc++] = tokp; if (nestlex(&strp, &tokp, &len, ends, hquotes, squotes, nests, true, true, false) < 0) { Error("internal: miscalculated string lengths"); } *tokp++ = '\0'; } pargv[pargc] = NULL; if ((tmp = Malloc(strlen(pargv[0])+2)) == NULL) { return STAT_RETRYLATER; } if (dash) { tmp[0] = '-'; strcpy(tmp+1, pargv[0]); } else { strcpy(tmp, pargv[0]); } pargv[0] = tmp; if (setopt_path(opts, &path) < 0) { /* this could be dangerous, so let us abort this child... */ Exit(1); } if ((numleft = leftopts(opts)) > 0) { Error1("%d option(s) could not be used", numleft); showleft(opts); return STAT_NORETRY; } /* only now redirect stderr */ if (duptostderr >= 0) { diag_dup(); Dup2(duptostderr, 2); } Notice1("execvp'ing \"%s\"", token); Execvp(token, pargv); /* here we come only if execvp() failed */ switch (pargc) { case 1: Error3("execvp(\"%s\", \"%s\"): %s", token, pargv[0], strerror(errno)); break; case 2: Error4("execvp(\"%s\", \"%s\", \"%s\"): %s", token, pargv[0], pargv[1], strerror(errno)); break; case 3: default: Error5("execvp(\"%s\", \"%s\", \"%s\", \"%s\", ...): %s", token, pargv[0], pargv[1], pargv[2], strerror(errno)); break; } Exit(1); /* this child process */ } /* parent */ return 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) { int bg; /* should the job run in bg or fg? */ struct cmdline_tokens tok; pid_t cpid ; //child's pid sigset_t mask; sigset_t prev; int parseId; //prepare for the jid or pid in the future int state; struct job_t* job; //use for the fg or bg int infg = 0; //default STDIN int outfg = 1; //default STDOUT /* Create block signal */ Sigemptyset(&mask); /* block int stp child signal with the block signal*/ Sigaddset(&mask, SIGINT); Sigaddset(&mask, SIGTSTP); Sigaddset(&mask, SIGCHLD); /* Parse command line */ bg = parseline(cmdline, &tok); if (bg == -1) /* parsing error */ return; if (tok.argv[0] == NULL) /* ignore empty lines */ return; /* When there is a redirect input or output , change the value infg and out fg to the file */ if (tok.infile != NULL) { infg = Open(tok.infile, O_RDONLY, 0); } if (tok.outfile!=NULL) { outfg = Open(tok.outfile, O_WRONLY,0); } /* There are 5 situations: 1. Not a builtin command 2. Quit 3. list jobs 4. builtin foreground jobs 5. builtin background jobs */ switch (tok.builtins) { case BUILTIN_NONE: //we need to fork and create a child process Sigprocmask(SIG_BLOCK, &mask, &prev); if ((cpid=Fork())==0) { //in the child process //we should unblock all signals Sigprocmask(SIG_UNBLOCK, &mask, NULL); cpid = getpid(); //set child process group to avoid race condition setpgid(cpid,cpid); Sigprocmask(SIG_SETMASK, &prev, NULL); //set the in and out direction if(infg != 0){ Dup2(infg, 0); Close(infg); } if (outfg != 1) { Dup2(outfg, 1); Close(outfg); } //process the outside command Execve(tok.argv[0], tok.argv, environ); }else{ //in the parent process //determin whether it is a bg or fg if (bg==1) { state = BG; } else{ state = FG; } //add the job to job list addjob(job_list, cpid, state, cmdline); //get the job from job list by pid job = getjobpid(job_list, cpid); //unblock all signal Sigprocmask(SIG_UNBLOCK, &mask, NULL); //use while to //set the shell wait until the job is stp or killed if(state == FG){ while (fgpid(job_list)!=0) { Sigsuspend(&prev); } } else{ //if bg, print the background job printf("[%d] (%d) %s\n",job->jid, job->pid,cmdline); } } break; case BUILTIN_QUIT: //use the exit function exit(0); break; case BUILTIN_JOBS: //use the listjobs function listjobs(job_list, outfg); break; case BUILTIN_BG: //get the jid if (tok.argv[1][0]=='%') { parseId = atoi(&tok.argv[1][1]); job = getjobjid(job_list, parseId); } //or get the pid else if ((tok.argv[1][0] >= '0')&&(tok.argv[1][0]<='9')) { parseId = atoi(&tok.argv[1][0]); job = getjobpid(job_list, (pid_t)parseId); } printf("[%d] (%d) %s\n",job->jid, job->pid,job->cmdline); //set the job state to BG job->state = BG; //send SIGCONT Kill(-(job->pid), SIGCONT); break; case BUILTIN_FG: //get jid if (tok.argv[1][0]=='%') { parseId = atoi(&tok.argv[1][1]); job = getjobjid(job_list, parseId); } //get pid else if ((tok.argv[1][0] >= '0')&&(tok.argv[1][0]<='9')) { parseId = atoi(&tok.argv[1][0]); job = getjobpid(job_list, (pid_t)parseId); } //set the job state to FG job->state = FG; //send SIGCONT Kill(-(job->pid), SIGCONT); break; default: break; } return; }
TVerdict CTestSyscalls::doTestStepL() { int err; if(TestStepName() == KCreat) { INFO_PRINTF1(_L("Creat():")); err = Creat(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == Kopen1) { INFO_PRINTF1(_L("open1():")); err = open1(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == Kopen2) { INFO_PRINTF1(_L("open2():")); err = open2(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == Kopen3) { INFO_PRINTF1(_L("open3():")); err = open3(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == Kopen4) { INFO_PRINTF1(_L("open4():")); err = open4(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == Kopen5) { INFO_PRINTF1(_L("open5():")); err = open5(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == Kopen6) { INFO_PRINTF1(_L("open6():")); err = open6(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KOpenTruncate1) { INFO_PRINTF1(_L("OpenTruncate1:")); err = OpenTruncate1(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KOpenTruncate2) { INFO_PRINTF1(_L("OpenTruncate2:")); err = OpenTruncate2(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == Kopen7) { INFO_PRINTF1(_L("open7():")); err = open7(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KOpenInAppendMode) { INFO_PRINTF1(_L("OpenInAppendMode():")); err = OpenInAppendMode(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == Kwrite1) { INFO_PRINTF1(_L("write1():")); err = write1(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == Kwrite2) { INFO_PRINTF1(_L("write2():")); err = write2(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == Kwrite3) { INFO_PRINTF1(_L("write3():")); err = write3(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == Kwrite5) { INFO_PRINTF1(_L("write5():")); err = write5(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == Kread1) { INFO_PRINTF1(_L("read1():")); err = read1(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == Kread2) { INFO_PRINTF1(_L("read2():")); err = read2(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == Kread3) { INFO_PRINTF1(_L("read3():")); err = read3(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == Kread4) { INFO_PRINTF1(_L("read4():")); err = read4(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KOpendir) { INFO_PRINTF1(_L("Opendir():")); err = Opendir(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KClosedir) { INFO_PRINTF1(_L("Closedir():")); err = Closedir(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KReaddir) { INFO_PRINTF1(_L("Readdir():")); err = Readdir(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KLseek) { INFO_PRINTF1(_L("Lseek():")); err = Lseek(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KLseek1) { INFO_PRINTF1(_L("Lseek1():")); err = Lseek1(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KAccess) { INFO_PRINTF1(_L("Access():")); err = Access(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KAccess1) { INFO_PRINTF1(_L("Access1():")); err = Access1(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KDup) { INFO_PRINTF1(_L("Dup():")); err = Dup(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KDup2) { INFO_PRINTF1(_L("Dup2():")); err = Dup2(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KRename) { INFO_PRINTF1(_L("Rename():")); err = Rename(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KRename1) { INFO_PRINTF1(_L("Rename1():")); err = Rename1(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KChmod) { INFO_PRINTF1(_L("Chmod():")); err = Chmod(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KChmod1) { INFO_PRINTF1(_L("Chmod1():")); err = Chmod1(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KChmod_dir) { INFO_PRINTF1(_L("Chmod_dir():")); err = Chmod_dir(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KFChmod) { INFO_PRINTF1(_L("FChmod():")); err = FChmod(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KFChmod_dir) { INFO_PRINTF1(_L("FChmod_dir():")); err = FChmod_dir(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KExit) { INFO_PRINTF1(_L("Exit():")); err = Exit(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KClose) { INFO_PRINTF1(_L("Close():")); err = Close(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KMkdir) { INFO_PRINTF1(_L("Mkdir():")); err = Mkdir(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KMk_dir) { INFO_PRINTF1(_L("Mk_dir():")); err = Mk_dir(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KRmdir) { INFO_PRINTF1(_L("Rmdir():")); err = Rmdir(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KRm_dir) { INFO_PRINTF1(_L("Rm_dir():")); err = Rm_dir(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KRmdir1) { INFO_PRINTF1(_L("Rmdir1():")); err = Rmdir1(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KRmdir_Chdir) { INFO_PRINTF1(_L("Rmdir_Chdir():")); err = Rmdir_Chdir(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KFsync) { INFO_PRINTF1(_L("Fsync():")); err = Fsync(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KUtimes) { INFO_PRINTF1(_L("Utimes():")); err = Utimes(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KUtime) { INFO_PRINTF1(_L("Utime():")); err = Utime(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KChdir) { INFO_PRINTF1(_L("Chdir():")); err = Chdir(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KFcntl) { INFO_PRINTF1(_L("Fcntl():")); err = Fcntl(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KIoctl) { INFO_PRINTF1(_L("Ioctl():")); err = Ioctl(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KFstat) { INFO_PRINTF1(_L("Fstat():")); err = Fstat(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KStat) { INFO_PRINTF1(_L("Stat():")); err = Stat(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KStat1) { INFO_PRINTF1(_L("Stat1():")); err = Stat1(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KStat2) { INFO_PRINTF1(_L("Stat2():")); err = Stat2(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KStat3) { INFO_PRINTF1(_L("Stat3():")); err = Stat3(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KGetpid) { INFO_PRINTF1(_L("Getpid():")); err = Getpid(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KClock) { INFO_PRINTF1(_L("Clock():")); err = Clock(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KTime) { INFO_PRINTF1(_L("Time():")); err = Time(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KWaitPid) { INFO_PRINTF1(_L("WaitPid():")); err = WaitPid(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KReadV) { INFO_PRINTF1(_L("ReadV():")); err = ReadV(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KWriteV) { INFO_PRINTF1(_L("WriteV():")); err = WriteV(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KSleep) { INFO_PRINTF1(_L("Sleep():")); err = Sleep(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KSeekDir) { INFO_PRINTF1(_L("SeekDir():")); err = SeekDir(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KRewindDir) { INFO_PRINTF1(_L("RewindDir():")); err = RewindDir(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KTelldir) { INFO_PRINTF1(_L("Telldir():")); err = Telldir(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KTestClock) { INFO_PRINTF1(_L("TestClock():")); err = TestClock(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KCreat2) { INFO_PRINTF1(_L("Creat2():")); err = Creat2(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == Kopen8) { INFO_PRINTF1(_L("open8():")); err = open8(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KTestStat) { INFO_PRINTF1(_L("KTestStat():")); err = TestStat(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KLseekttytest1) { INFO_PRINTF1(_L("Lseekttytest1():")); err = Lseekttytest1(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KLseekttytest2) { INFO_PRINTF1(_L("Lseekttytest2():")); err = Lseekttytest2(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KWaitPidtest) { INFO_PRINTF1(_L("WaitPidtest():")); err = WaitPidtest(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KWaittest) { INFO_PRINTF1(_L("Waittest():")); err = Waittest(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KOpen_FileDes_Test) { INFO_PRINTF1(_L("Open_FileDes_Test():")); err = Open_FileDes_Test(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == Kopenuid) { INFO_PRINTF1(_L("openuid():")); err = openuid(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KMkdir1) { INFO_PRINTF1(_L("Mkdir1():")); err = Mkdir1(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KMkdir2) { INFO_PRINTF1(_L("Mkdir2():")); err = Mkdir2(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KRename2) { INFO_PRINTF1(_L("Rename2():")); err = Rename2(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == Ktestfsync) { INFO_PRINTF1(_L("testfsync():")); err = testfsync(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == Ktestrename) { INFO_PRINTF1(_L("testrename():")); err = testrename(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == Ktestopenvalidate) { INFO_PRINTF1(_L("testopenvalidate():")); err = testopenvalidate(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == Ksync_safe) { INFO_PRINTF1(_L("sync_safe():")); err = sync_safe(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KFstat1) { INFO_PRINTF1(_L("Fstat1():")); err = Fstat1(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KUtimes1) { INFO_PRINTF1(_L("Utimes1():")); err = Utimes1(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KMkdir_test1) { INFO_PRINTF1(_L("Mkdir_test1():")); err = Mkdir_test1(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KChmod_test) { INFO_PRINTF1(_L("Chmod_test():")); err = Chmod_test(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KChdir1) { INFO_PRINTF1(_L("Chdir1():")); err = Chdir1(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KRmdir2) { INFO_PRINTF1(_L("Rmdir2():")); err = Rmdir2(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KRename_test) { INFO_PRINTF1(_L("Rename_test():")); err = Rename_test(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KRename3) { INFO_PRINTF1(_L("Rename3():")); err = Rename3(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KCreat1) { INFO_PRINTF1(_L("Creat1():")); err = Creat1(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KReadV1) { INFO_PRINTF1(_L("ReadV1():")); err = ReadV1(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KUtimes2) { INFO_PRINTF1(_L("Utimes2():")); err = Utimes2(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KStat_test) { INFO_PRINTF1(_L("Stat_test():")); err = Stat_test(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KMkdir_test2) { INFO_PRINTF1(_L("Mkdir_test2():")); err = Mkdir_test2(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KChmod2) { INFO_PRINTF1(_L("Chmod2():")); err = Chmod2(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KChdir2) { INFO_PRINTF1(_L("Chdir2():")); err = Chdir2(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KRename4) { INFO_PRINTF1(_L("Rename4():")); err = Rename4(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KRename5) { INFO_PRINTF1(_L("Rename5():")); err = Rename5(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == KRmdir3) { INFO_PRINTF1(_L("Rmdir3():")); err = Rmdir3(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } else if(TestStepName() == Kread5) { INFO_PRINTF1(_L("read5():")); err = read5(); SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass); } return TestStepResult(); }
/* Run the given command line as if with exec. What we actually do is fork the command line as a subprocess, then loop, relaying data between the socket and the subprocess. This allows Ncat to handle SSL from the socket and give plain text to the subprocess, and also allows things like logging and line delays. Never returns. */ void netexec(struct fdinfo *info, char *cmdexec) { int child_stdin[2]; int child_stdout[2]; int pid; int crlf_state; char buf[DEFAULT_TCP_BUF_LEN]; int maxfd; if (o.debug) { switch (o.execmode) { case EXEC_SHELL: logdebug("Executing with shell: %s\n", cmdexec); break; #ifdef HAVE_LUA case EXEC_LUA: logdebug("Executing as lua script: %s\n", cmdexec); break; #endif default: logdebug("Executing: %s\n", cmdexec); break; } } if (pipe(child_stdin) == -1 || pipe(child_stdout) == -1) bye("Can't create child pipes: %s", strerror(errno)); pid = fork(); if (pid == -1) bye("Error in fork: %s", strerror(errno)); if (pid == 0) { /* This is the child process. Exec the command. */ close(child_stdin[1]); close(child_stdout[0]); /* We might have turned off SIGPIPE handling in ncat_listen.c. Since the child process SIGPIPE might mean that the connection got broken, ignoring it could result in an infinite loop if the code here ignores the error codes of read()/write() calls. So, just in case, let's restore SIGPIPE so that writing to a broken pipe results in killing the child process. */ Signal(SIGPIPE, SIG_DFL); /* rearrange stdin and stdout */ Dup2(child_stdin[0], STDIN_FILENO); Dup2(child_stdout[1], STDOUT_FILENO); switch (o.execmode) { char **cmdargs; case EXEC_SHELL: execl("/bin/sh", "sh", "-c", cmdexec, (void *) NULL); break; #ifdef HAVE_LUA case EXEC_LUA: lua_run(); break; #endif default: cmdargs = cmdline_split(cmdexec); execv(cmdargs[0], cmdargs); break; } /* exec failed. */ die("exec"); } close(child_stdin[0]); close(child_stdout[1]); maxfd = child_stdout[0]; if (info->fd > maxfd) maxfd = info->fd; /* This is the parent process. Enter a "caretaker" loop that reads from the socket and writes to the suprocess, and reads from the subprocess and writes to the socket. We exit the loop on any read error (or EOF). On a write error we just close the opposite side of the conversation. */ crlf_state = 0; for (;;) { fd_set fds; int r, n_r; FD_ZERO(&fds); FD_SET(info->fd, &fds); FD_SET(child_stdout[0], &fds); r = fselect(maxfd + 1, &fds, NULL, NULL, NULL); if (r == -1) { if (errno == EINTR) continue; else break; } if (FD_ISSET(info->fd, &fds)) { int pending; do { n_r = ncat_recv(info, buf, sizeof(buf), &pending); if (n_r <= 0) goto loop_end; write_loop(child_stdin[1], buf, n_r); } while (pending); } if (FD_ISSET(child_stdout[0], &fds)) { char *crlf = NULL, *wbuf; n_r = read(child_stdout[0], buf, sizeof(buf)); if (n_r <= 0) break; wbuf = buf; if (o.crlf) { if (fix_line_endings((char *) buf, &n_r, &crlf, &crlf_state)) wbuf = crlf; } ncat_send(info, wbuf, n_r); if (crlf != NULL) free(crlf); } } loop_end: #ifdef HAVE_OPENSSL if (info->ssl != NULL) { SSL_shutdown(info->ssl); SSL_free(info->ssl); } #endif close(info->fd); exit(0); }
/* * main - The shell's main routine */ int main(int argc, char **argv) { char c; char cmdline[MAXLINE]; /* cmdline for fgets */ int emit_prompt = 1; /* emit prompt (default) */ /* Redirect stderr to stdout (so that driver will get all output * on the pipe connected to stdout) */ Dup2(1, 2); /* Parse the command line */ while ((c = getopt(argc, argv, "hvp")) != EOF) { switch (c) { case 'h': /* print help message */ usage(); break; case 'v': /* emit additional diagnostic info */ verbose = 1; break; case 'p': /* don't print a prompt */ emit_prompt = 0; /* handy for automatic testing */ break; default: usage(); } } /* Install the signal handlers */ /* These are the ones you will need to implement */ Signal(SIGINT, sigint_handler); /* ctrl-c */ Signal(SIGTSTP, sigtstp_handler); /* ctrl-z */ Signal(SIGCHLD, sigchld_handler); /* Terminated or stopped child */ Signal(SIGTTIN, SIG_IGN); Signal(SIGTTOU, SIG_IGN); /* This one provides a clean way to kill the shell */ Signal(SIGQUIT, sigquit_handler); /* Initialize the job list */ initjobs(job_list); /* Execute the shell's read/eval loop */ while (1) { if (emit_prompt) { printf("%s", prompt); fflush(stdout); } if ((fgets(cmdline, MAXLINE, stdin) == NULL) && ferror(stdin)) app_error("fgets error"); if (feof(stdin)) { /* End of file (ctrl-d) */ printf ("\n"); fflush(stdout); fflush(stderr); exit(0); } /* Remove the trailing newline */ cmdline[strlen(cmdline)-1] = '\0'; /* Evaluate the command line */ eval(cmdline); fflush(stdout); fflush(stdout); } exit(0); /* control never reaches here */ }
/* ring_dup_in: duplicate read file descriptor */ static void ring_dup_in(struct ring *r) { Dup2(r->fd[IN], r->in); }