Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**************************************************************************
- * Student name and No.: Ho Hilary 3035229306
- * Development platform: Ubuntu 14.04 VM
- * Last modified date:
- * Compilation: gcc myshell.c -o myshell
- */
- #include <errno.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- //signal handler declaration
- void sigint_handler(int signum) {
- if(signum ==SIGUSR1){
- printf("Received SIGUSR1!\n");
- }else {
- printf(" Program terminated\n");
- }
- }
- int main() {
- //variable declaration
- //for timeX print out statisticc
- char str[50];
- FILE * file;
- int z;
- //unsigned long long i, x;
- unsigned long h, ut, st;
- char input[1024]; //store user input
- char *split[1024]; //split the input into
- int a=0;
- int childtype=0; //to indicate if it is background(1) or foreground(2) child process
- int result; //store result of waitid() from parent process
- siginfo_t info; //signal type
- //start of program
- //prompt ##myshell $ and get the input from user and store in "input"
- printf("##myshell $");
- fgets(input, 1024,stdin);
- //loop until "exit" command appears
- while(strcmp(input,"exit\n")!=0){
- //remove the newline character at the end of the input
- if (input[strlen(input) - 1] == '\n') {
- input[strlen(input) - 1] = '\0';
- }
- //check if the input has the character '&'
- if(strstr(input,"&")!=NULL){
- if(input[strlen(input)-1]!='&'){ //the input has '&' but not at the end position
- printf("'&' should not appear in the middle of the command line\n");
- }else{ //the input has '&' at the end
- childtype =1; //define it as background child process
- }
- //get process statistics
- }else if(strcmp(input,"timeX")==0){ //the input is exactly "timeX"
- printf("myshell: \"timeX\" cannot be a standalone command\n");
- sprintf(str, "/proc/%d/stat", (int)getpid());
- file = fopen(str, "r");
- if (file == NULL) {
- printf("Error in open my proc file\n");
- exit(0);
- }
- fscanf(file, "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu", &z, str, &str[0], &z, &z, &z, &z, &z,
- (unsigned *)&z, &h, &h, &h, &h, &ut, &st);
- fclose(file);
- printf("PID \t CMD \t UTIME \t STIME\n");
- //remove the newline character of the input
- if (input[strlen(input) - 1] == '\n') {
- input[strlen(input) - 1] = '\0';
- }
- printf("%d\t %s\t %.2lfs\t %.2lfs\n",(int)getpid(),input, ut*2.0f/sysconf(_SC_CLK_TCK),st*1.0f/sysconf(_SC_CLK_TCK));
- }else if ((strstr(input,"timeX")!=NULL) & (input[strlen(input)-1]=='&')){ //"timeX" command ends with '&'
- printf("myshell: \"timeX\" cannot be run in background mode\n");
- }
- else {
- //create child process to execute command
- int pid = fork();
- if (pid < 0) {
- printf("Cannot create child process successfully!");
- } else if (pid == 0) { //run child process
- childtype =2; ////define it as foreground child process
- // printf("It is a foreground process with type %d\n", childtype);
- //printf("I am a child process, with pid: %d\n", (int) getpid());
- //split the input into small pieces with delimiter of a space " "
- split[a] = strtok(input," ");
- while(split[a]!=NULL)
- {
- split[++a] = strtok(NULL," ");
- }
- if ((strcmp(split[0],"exit")==0)&& split[1]!=NULL){ //there are other input after "exit" command
- printf("myshell: \"exit\" with other arguments!!!\n");
- }
- else{
- //locate and execute program with aboslute
- execvp(split[0],split);
- char *path[] = {"HOME=/home","LOGNAME=home",(char *)0};
- execve(split[0],split,path);
- //input path cannot be found
- if (execvp (split[0], split) == -1) {
- printf("myshell: \'%s \': No such file or directory\n", input);
- exit(-1);
- }
- printf("These lines should never be printed\n");
- exit(0);
- }
- } else {
- //run parent process
- pid_t child_pid;
- child_pid = waitpid(pid,NULL,0);
- if(child_pid>0){}
- //printf("I am a parent process, with pid: %d and my child's pid is %d\n",(int) getpid(), (int) pid);
- //printf("Parent: OK\n");
- if(childtype==1) { // if it is a background child process.
- signal(SIGCHLD,sigint_handler);// handle SIGCHLD signal
- }
- if(childtype ==2){ //if it is a foreground child process
- result = waitid(P_ALL,0,&info,WCONTINUED);
- if(result ==-1){ //error
- //printf("Program terminated.%d\n",status.si_signo);
- }
- }
- }
- }
- //prompt the user and get input from user
- printf("##myshell $");
- fgets(input, 1024,stdin);
- }//end of while loop
- //"exit" command is typed
- printf("myshell: Terminated\n");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement