pid_t exec_command(char *comm_name,char **args,int flags,pid_t group_id,int infile,int outfile){ pid_t cpid = fork(); int hist_ret; if(cpid==0){ //child: //Reset Signals signal (SIGINT ,SIG_DFL); signal (SIGQUIT,SIG_DFL); signal (SIGTSTP,SIG_DFL); signal (SIGTTIN,SIG_DFL); signal (SIGTTOU,SIG_DFL); signal (SIGCHLD,SIG_DFL); cpid=getpid(); if(group_id==0)group_id=cpid; setpgid(cpid,group_id); if(infile!=STDIN_FILENO){ dup2(infile,STDIN_FILENO); close(infile); } if(outfile!=STDOUT_FILENO){ dup2(outfile,STDOUT_FILENO); close(outfile); } if(flags&EXEC_FLAG_BACKGROUND){ } else{ tcsetpgrp(shell_in,group_id); } if(!strcmp(comm_name,"pid")){ exec_pid(args); exit(0); } else if((hist_ret=check_hist_str(comm_name))!=-1){ //Check for hist command and process hist #TODz exec_hist(hist_ret); exit(0); } else{ int execret=execvp(comm_name,args); if(execret==-1){ error(0,0,"%s : %s\n",comm_name,strerror(errno)); exit(2); } } } else{ //parent: if(infile!=STDIN_FILENO) close(infile); if(outfile!=STDOUT_FILENO) close(outfile); process_list[plist_end].pid=cpid; process_list[plist_end].process_name=strdup(args[0]); plist_end=(plist_end+1)%PLIST_LENGTH_MAX; if(plist_end==plist_start)plist_start=(plist_start+1)%PLIST_LENGTH_MAX; if(group_id==0)group_id=cpid; setpgid(cpid,group_id); if(flags&(EXEC_FLAG_BACKGROUND)){ //add process to ActiveProcess list and continue active_process_list[actv_plist_cnt].pid=cpid; active_process_list[actv_plist_cnt].process_name=strdup(args[0]); actv_plist_cnt++; if(actv_plist_cnt>=PLIST_LENGTH_MAX){ error(0,0,"Cannot manage more than %d Active Processes. Process Killed\n",PLIST_LENGTH_MAX); kill(cpid,SIGKILL); actv_plist_cnt--; } } else if(flags&(EXEC_MORE_PIPES)){ tcsetpgrp(shell_in,group_id); } else{ //wait patiently till process exits tcsetpgrp(shell_in,group_id); waitpid(cpid,NULL,0); tcsetpgrp(shell_in,mypid); } } return cpid; }
// Invokes a command, assuming it has no pipes. int invoke(char *input, int will_fork) { int stdin_copy = dup(0); int stdout_copy = dup(1); // First, we want to determine whether we need any redirects. char **files = tokenize_redirects(input); unsigned int i; char *infile = NULL; char *outfile = NULL; int status; // Clean up the array contents. char **tokens = tokenize(files[0]); char **infiles; if (files[1]) { infiles = tokenize(files[1]); infile = infiles[0]; } char **outfiles; if (files[2]) { outfiles = tokenize(files[2]); outfile = outfiles[0]; } if (infile) { int in_fd = open(infile, O_RDONLY); if (in_fd == -1) { fprintf(stderr, "open failed: %s\n", strerror(errno)); exit(EXIT_FAILURE); } dup2(in_fd, STDIN_FILENO); status = close(in_fd); if (status == -1) { fprintf(stderr, "close failed: %s\n", strerror(errno)); exit(EXIT_FAILURE); } } if (outfile) { int out_fd = open(outfile, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR); if (out_fd == -1) { fprintf(stderr, "open failed: %s\n", strerror(errno)); exit(EXIT_FAILURE); } dup2(out_fd, STDOUT_FILENO); status = close(out_fd); if (status == -1) { fprintf(stderr, "close failed: %s\n", strerror(errno)); exit(EXIT_FAILURE); } } // Handle built in commands. if (!tokens[0]) return 0; if (strcmp(tokens[0], "cd") == 0 || strcmp(tokens[0], "chdir") == 0) { exec_cd(tokens); } else if (strcmp(tokens[0], "history") == 0) { exec_hist(tokens); } else if (strcmp(tokens[0], "exit") == 0) { exit(EXIT_SUCCESS); } else { if (will_fork) { // Based on how invoke is called, fork. pid_t pid = fork(); if (pid == -1) { fprintf(stderr, "fork failed: %s\n", strerror(errno)); exit(EXIT_FAILURE); } else if (pid == 0) { if (execvp(tokens[0], tokens) == -1) { fprintf(stderr, "execvp failed: %s\n", strerror(errno)); } } else { wait(&status); } } else { if (execvp(tokens[0], tokens) == -1) { fprintf(stderr, "execvp failed: %s\n", strerror(errno)); } } } dup2(stdin_copy, STDIN_FILENO); dup2(stdout_copy, STDOUT_FILENO); // Memory management. for (i = 0; tokens[i] != NULL; i++) { free(tokens[i]); } free(tokens); if (files[1]) { for (i = 0; infiles[i] != NULL; i++) { free(infiles[i]); } free(infiles); } if (files[2]) { for (i = 0; outfiles[i] != NULL; i++) { free(outfiles[i]); } free(outfiles); } for (i = 0; i < 3; i++) { if (files[i]) { free(files[i]); } } free(files); return 0; }