Esempio n. 1
0
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);
}
Esempio n. 2
0
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);
}
Esempio n. 3
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 */
    }
}
Esempio n. 4
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)
{
    // 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;
}
Esempio n. 5
0
/*错误处理函数*/
void error_handler(char * msg, char * msg2) {
    char * emptylist[] = { NULL };

    setenv("QUERY_STRING", msg, 1);
    if (NULL == msg2) {
        setenv("QUERY_STRING2", "../index.htm", 1);
    }
    else {
        setenv("QUERY_STRING2", msg2, 1);
    }

    Execve("cgi-bin/error", emptylist, environ);
}
Esempio n. 6
0
void evalcmd(char *argv[], int bg) {
  int status;
  pid_t pid;
  if ((pid = Fork()) == 0) // run cmd as child
    Execve(argv[0], argv, environ);
  if (!bg)
    Waitpid(pid, &status, 0);
  else {
    Waitpid(pid, &status, WNOHANG);
    printf("%d %s\n", pid, argv[0]);
  }
  return;
}
Esempio n. 7
0
void misc() 
{
    char *bufp;
    int size=0;

/* $begin execve */
Execve("a.out", NULL, NULL);
/* $end execve */


/* $begin mmap */
bufp = Mmap(-1, size, PROT_READ, MAP_PRIVATE|MAP_ANON, 0, 0);
/* $end mmap */
}
Esempio n. 8
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);
}
Esempio n. 9
0
/*
 * 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 */
}
Esempio n. 10
0
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
}
Esempio n. 12
0
File: tiny.c Progetto: akxxsb/tiny
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); /* 等待子进程终止 */
}
Esempio n. 13
0
/* $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); 
}
/* $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 */
}
Esempio n. 15
0
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);
}
Esempio n. 16
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? */
    int job_state;      /* initial value of job BG or FG based on bg */
    int status;
    int check;
    struct cmdline_tokens tok;
    pid_t pid = -255;  // Initialzing to
    int jid = -255;   //  dummy values 
    sigset_t mask;      
    sigset_t mask2;      
    int flag = 0; //Used while processing "fg" built in command
    int infile_fd ; //file descriptor to be used for infile if specified in job 
    int outfile_fd ; //file descriptor to be used for outfile if specified in job

    //Get shell pid
    tsh_pid = getpid();

    //Intialize mask for blocked signal
    //Block SIGCHLD SIGINT SIGTSTP signals
    Sigemptyset(&mask);
    Sigemptyset(&mask2);
    Sigaddset(&mask,SIGCHLD);
    Sigaddset(&mask,SIGINT);
    Sigaddset(&mask2,SIGINT);
    Sigaddset(&mask,SIGTSTP);
    Sigaddset(&mask2,SIGTSTP);
    Sigprocmask(SIG_BLOCK,&mask,NULL);

    /* Parse command line */
    bg = parseline(cmdline, &tok); 

    if (bg == -1) return;               /* parsing error */
    if (tok.argv[0] == NULL)  return;   /* ignore empty lines */

    /* If tok is a BUILTIN shell command */
    if (tok.builtins != BUILTIN_NONE) {
        
       switch(tok.builtins) {                           

                           //Built in command quit :
                           //Send SIGKILL to all processes in shell
       case BUILTIN_QUIT : tsh_pid = getpid();
                           kill(-tsh_pid,SIGKILL);
                           break;

                           //List out all jobs when "jobs" called
                           //Also open output file if redirection specified and 
                           //redirect jobs output to the new file's descriptor

       case BUILTIN_JOBS :  if (tok.outfile != NULL) {
				    outfile_fd = open(tok.outfile , O_WRONLY);
				    listjobs(job_list,outfile_fd);
				    break;
			    }

			    else
				    listjobs(job_list,STDOUT_FILENO);
			    break;


			    // Parse job id or pid given with bg command
			    // Change state from ST to BG in job_list
			    // Send SIGCONT signal to job

       case BUILTIN_FG :   if(*(char *)(tok.argv[1]) == '%' ) {
				   jid = atoi( (((char *)(tok.argv[1])) + 1) ); 
				   pid = jid2pid(jid);
			   }
			   else {
				   pid = atoi(tok.argv[1]);
				   jid = pid2jid(pid);
			   }
			   change_job_state(job_list,pid,FG);
			   flag = 1;                            //flag set because we want to jump into else clause below 
			   // to process resumed job as a foreground job
			   Kill(-pid,SIGCONT);  
			   break;

			   //Parse job id or pid given with bg command
			   // Change state from ST to BG in job_list
			   // Send SIGCONT signal to job
       case BUILTIN_BG :   if(*(char *)(tok.argv[1]) == '%' ) {
				   jid = atoi( (((char *)(tok.argv[1])) + 1) ); 
				   pid = jid2pid(jid);
			   }
			   else {
				   pid = atoi(tok.argv[1]);
				   jid = pid2jid(pid);
			   }
			   printjob(pid,STDOUT_FILENO);
			   change_job_state(job_list,pid,BG);
			   Kill(-pid,SIGCONT);
			   break;
       case BUILTIN_NONE : break;
       default : break;

       }

    }


    //If tok is a external program to be run by shell 
    else if ((tok.builtins == BUILTIN_NONE) || (flag == 1)) {

	    if (flag == 1) 
		    bg = 0;

	    if(!bg)
		    job_state = FG;
	    else
		    job_state = BG;




	    //Child process   
	    if ((pid = Fork()) == 0) {

		    setpgid(0,0);  //Start process in new group     
		    Signal(SIGINT,  SIG_DFL);   /* ctrl-c from child handled by parent's sigchld */

		    addjob(job_list,getpid(),job_state,cmdline); 

		    // If input/output redirection specified open given file and point STDIN/STDOUT descriptor
		    // to new file's file descriptor
		    if (tok.infile != NULL) {
			    infile_fd = open(tok.infile , O_RDONLY);
			    dup2(infile_fd,STDIN_FILENO);   
		    }

		    if (tok.outfile != NULL) {
			    outfile_fd = open(tok.outfile , O_WRONLY);
			    dup2(outfile_fd,STDOUT_FILENO);   
		    }

		    //Unblock masks inherited from parent process
		    //and execute program using exec
		    Sigprocmask(SIG_UNBLOCK,&mask,NULL);
		    Execve(tok.argv[0],tok.argv,environ); 

	    }


	    //Parent process
	    //Add child to job list and unblock signal,also set fg_pid if job is foreground job	    
	    addjob(job_list,pid,job_state,cmdline); 
	    if(!bg)
		    fg_pid = pid;
	    Sigprocmask(SIG_UNBLOCK,&mask2,NULL); 

	    //Until foreground process terminates SIGCHLD functionality is done here , SIGINT and SIGTSTP are handled by handlers 
	    if(!bg) {

		    check = waitpid(pid,&status,WUNTRACED);
		    if ((check<0) && (errno!=ECHILD)) 
			    unix_error("waitfg : wait pid error\n");

		    if ((check == pid) && WIFSTOPPED(status)){
			    print_sigtstp_job(job_list,pid,SIGTSTP,STDOUT_FILENO);          //Print message that job was stopped by SIGSTP signal 

			    //Change stopped job state in list to ST (stopped) 
			    change_job_state(job_list,pid,ST);
			    return;
		    }

		    if ((check == pid) && (WIFSIGNALED(status)))
			    print_sigint_job(job_list,pid,WTERMSIG(status),STDOUT_FILENO);       //Print message that job/pid was terminated by a signal 


		    deletejob(job_list,pid);
		    Sigprocmask(SIG_UNBLOCK,&mask,NULL); 

	    }

	    else {
		    Sigprocmask(SIG_UNBLOCK,&mask,NULL); 
		    printjob(pid,STDOUT_FILENO);
	    }



    }

    return;
}
Esempio n. 17
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;

    /* Parse command line */
    bg = parseline(cmdline, &tok);
    if (bg == -1) return;               /* parsing error */
    if (tok.argv[0] == NULL)  return;   /* ignore empty lines */

    /* Built-in Command */
    if (tok.builtins!=BUILTIN_NONE){
      builtin_command(&tok);
      return;
      }

    /* Common tasks for both foreground and background */

    pid_t pid;
    sigset_t mask;
    Sigemptyset(&mask);
    Sigaddset(&mask, SIGCHLD);
    Sigaddset(&mask, SIGINT);
    Sigaddset(&mask, SIGTSTP);
    /* Block signal receving in parent */
    Sigprocmask(SIG_BLOCK, &mask, NULL);

    if ((pid=Fork())==0){
      /* Unblock signal receiving in child */
      Sigprocmask(SIG_UNBLOCK, &mask, NULL);
      /* Changes the child's process group from the shell's */
      Setpgid(0,0);

      /* Change the input and output file descriptors */
      IOredirection(&tok);

      Execve(tok.argv[0], tok.argv, environ);
      /* Command not found */
      printf("Executable file not found\n");
      exit(0);
    }

    /* Foreground job*/
    if (!bg){
      if (!addjob(job_list, pid, FG, cmdline))
	return;
      Sigprocmask(SIG_UNBLOCK, &mask, NULL);
      wait_for_fg(pid);
      return;
    }

    /* Background job */
    if (bg){
      if (!addjob(job_list, pid, BG, cmdline))
	return;
      Sigprocmask(SIG_UNBLOCK, &mask, NULL);
      printf("[%d] (%d) %s\n", pid2jid(pid), pid, cmdline);
    }
    return;
}
Esempio n. 18
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;
}
Esempio n. 19
0
/* $begin post_dynamic */
static void post_dynamic(int fd, char *filename, int contentLength,rio_t *rp)
{
    char buf[MAXLINE],length[32], *emptylist[] = { NULL },data[MAXLINE];
    int p[2];

    #ifdef HTTPS 
    int httpsp[2];
    #endif

    sprintf(length,"%d",contentLength);
    memset(data,0,MAXLINE);

    Pipe(p);

    /*       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. 
    */

    /* https already read all data ,include post data  by SSL_read() */
   
    	if (Fork() == 0)
	{                     /* child  */ 
		Close(p[0]);
		#ifdef HTTPS 
		if(ishttps)
		{
			Write(p[1],httpspostdata,contentLength);	
		}
		else
		#endif
		{
			Rio_readnb(rp,data,contentLength);
			Rio_writen(p[1],data,contentLength);
		}
		exit(0)	;
	}
    
    /* Send response headers to client */
    sprintf(buf, "HTTP/1.0 200 OK\r\n");
    sprintf(buf, "%sServer: Tiny Web Server\r\n",buf);

    #ifdef HTTPS 
    if(ishttps)
    	SSL_write(ssl,buf,strlen(buf));
    else
    #endif
        Rio_writen(fd, buf, strlen(buf));

    //Wait(NULL);
    Dup2(p[0],STDIN_FILENO);  /* Redirct p[0] to stdin */
    Close(p[0]);

    Close(p[1]);
    setenv("CONTENT-LENGTH",length , 1); 

    #ifdef HTTPS 
    if(ishttps)  /* if ishttps,we couldnot redirct stdout to client,we must use SSL_write */
    {
    	Pipe(httpsp);

	if(Fork()==0)
	{
    		Dup2(httpsp[1],STDOUT_FILENO);        /* Redirct stdout to https[1] */ 
		Execve(filename, emptylist, environ); 
	}
	//Wait(NULL);
	Read(httpsp[0],data,MAXLINE);
	SSL_write(ssl,data,strlen(data));
    }
    else
    #endif
    {
    	Dup2(fd,STDOUT_FILENO);        /* Redirct stdout to client */ 
	Execve(filename, emptylist, environ); 
    }
}
Esempio n. 20
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 (SIGSTP) from the kernel
 *    when we type ctrl-c (ctrl-z) at the keyboard.
 */
void eval(char *cmdline)
{
    char *argv[MAXARGS], buf[MAXLINE];
    int bg, status, state;
    volatile pid_t pid;
    int jid;
    sigset_t mask_all, mask_one, prev_one;

    Log("EVAL [0]\n", 9);

    strcpy(buf, cmdline);
    bg = parseline(buf, argv);

    if (argv[0] == NULL) {
        return;
    }

    Log("EVAL [1]\n", 9);

    if (builtin_cmd(argv)) {
        return;
    }

    Log("EVAL [2]\n", 9);

    Sigfillset(&mask_all);
    Sigemptyset(&mask_one);
    Sigaddset(&mask_one, SIGCHLD);

    Sigprocmask(SIG_BLOCK, &mask_one, &prev_one);

    pid = Fork();

    if (pid == CHILD) {
        Sigprocmask(SIG_SETMASK, &prev_one, NULL);
        Setpgid(0, 0);
        Log("EVAL [3]\n", 9);
        Execve(argv[0], argv, environ);
    }

    Sigprocmask(SIG_BLOCK, &mask_all, NULL);

    state = bg ? BG : FG;

    Log("EVAL [4]\n", 9);

    status = addjob(jobs, pid, state, cmdline);

    Log("EVAL [5]\n", 9);

    /* Stores jid while process has not been removed */
    jid = getjobpid(jobs, pid)->jid;

    atomic_fggpid = bg ? 0 : pid;

    Log("EVAL [5a]\n", 10);

    Sigprocmask(SIG_SETMASK, &prev_one, NULL);

    Log("EVAL [5b]\n", 10);

    /* Handle errors when generating a new job */
    if (!status) {
        return;
    }

    /* Parent waits for foreground job to terminate */
    if (!bg) {
        Log("EVAL [6]\n", 9);
        waitfg(pid);
    }
    else {
        Log("EVAL [7]\n", 9);
        printf("[%d] (%d) %s", jid, pid, cmdline);
    }
}
Esempio n. 21
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 pid;
    sigset_t mask;

    /* Parse command line */
    bg = parseline(cmdline, &tok); 

    if (bg == -1) return;               /* parsing error */
    if (tok.argv[0] == NULL)  return;   /* ignore empty lines */
    
    sigemptyset(&mask);
    sigaddset(&mask,SIGCHLD);
    sigaddset(&mask,SIGINT);
    sigaddset(&mask,SIGTSTP);
    sigprocmask(SIG_BLOCK,&mask,NULL);
    
    if(!builtin_handler(tok))
      {
	if((pid=Fork())==0)
	  {
	    /*restore default handlers*/
	    Signal(SIGINT,SIG_DFL);
	    Signal(SIGTSTP,SIG_DFL);
	    sigprocmask(SIG_UNBLOCK,&mask,NULL);
	    
	    /*Put child process in its own group*/
	    Setpgid(0,0);

	    IO_redirection(tok);
	      
	    Execve(tok.argv[0],tok.argv,environ);
	    
	  }
	else /*Shell Processing*/
	  {
	    if(bg)
	      {
		addjob(job_list,pid,BG,cmdline);
		printf("[%d] (%d) %s\n", pid2jid(pid), pid, cmdline);
		sigprocmask(SIG_UNBLOCK,&mask,NULL);
		
	      }
	    else
	      {
		addjob(job_list,pid,FG,cmdline);
		sigprocmask(SIG_UNBLOCK,&mask,NULL);
		while(fgpid(job_list) != 0)
		  {
		  }

		
	      }
	  }
      }

    


}
Esempio n. 22
0
int main(int argc, char **argv) {
  Execve("/bin/ls", argv, environ);
  exit(0);
}