c - Is there a more efficient way to do this? -


first of all, yes laboratory activity in class, have submitted , defended exercise. know if there way, more efficient way write code.

what tasked write code creates process, creates child, in turn creates child , creates child.

*edit: separated , numbered requirements better readability :)

  1. the last child show current processes running in system.

  2. its parent ask word create file using input user.

  3. its parent ask word or phrase, find within libraries in machine (let's typed hi, should find , list files containing hi & directory. position of word hi should not matter)

  4. lastly, main parent print parent id.

here complete code matter:

int main(void){      char filename[30];     char phrase[30];     int pid = fork();     int fd[2];     pipe(fd);     if(pid==0){         printf ("child1: 1st child\n");         printf ("child1: id %d \n", getpid());         printf ("child1: parent id %d \n", getppid());         int pid2 = fork();         if(pid2==0){             printf ("\t child2: 2nd child\n");             printf ("\t child2: id %d \n", getpid());             printf ("\t child2: parent id %d \n", getppid());             int pid3 = fork();                       if(pid3==0){                     printf ("\t\t child3: 3rd child\n");                     printf ("\t\t child3: id %d \n", getpid());                     printf ("\t\t child3: parent id %d \n", getppid());                     execlp ("/usr/bin/top", "top", null);                 }else if(pid3==-1){                     printf ("id %d", getpid());                     printf ("error");                     exit(1);                 }else{                     wait(null);                     printf ("\t child2: enter filename: ");                     scanf ("%s", filename);                     printf ("\t child2: %s succcessfully created!\n", filename);                     execlp ("/bin/touch", "touch", filename, null);                  }         }else if(pid2==-1){             printf ("id %d", getpid());             printf ("error");             exit(1);         }else{             wait(null);             int pid4 = fork();                 if(pid4 > 0) {                     printf ("child1: enter pharse: ");                     scanf ("%s", phrase);                     close(fd[1]);                     close(stdin_fileno);                     dup2(fd[0],stdin_fileno);                     execlp ("/bin/grep", "grep", phrase, null);                 }else if (pid4 == 0) {                     close(fd[0]);                     close(stdout_fileno);                     dup2(fd[1],stdout_fileno);                     execlp ("/usr/bin/find", "find", null);                 }else {                     printf ("error");                 }         }            }else if(pid==-1){         printf ("id %d", getpid());         printf ("error");         exit(1);     }else{         wait(null);         printf ("parent: parent\n");         printf ("parent: id %d \n", getpid());     } } 

your code seems reasonably efficient in terms of run-time , number of lines, single main function, nested, few favors humans try read , understand you've done.

consider idiom: 1 that's more modular, ancestry of processes (imho) easier follow reviewer. (i invoke ps instead of top there's no need keyboard interaction in step.)

is approach more "efficient"? arguably no, although prefer more direct coding of child-per-function approach. chaining of parent , child process artificial, of course assignment.

#include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h>  /*  * run passed function in child process, , return  * function if child process runs ,  * exits status of 0.  */ static void run_func_in_child(void (*f)()) {     int status;     pid_t pid = fork();      switch (pid) {     case -1:         perror("fork");         exit(1);     case 0: /* child */         (*f)();         break;     default: /* parent */         if (waitpid(pid, &status, 0) == -1) {              perror("waitpid");              exit(1);         }         if (wifexited(status) && wexitstatus(status) == 0) {              return;         }         fprintf(stderr, "child did not exit cleanly\n");         exit(1);     } }  /*  * scanf simpler, let's protect against buffer overruns  */ static void get_rsp(const char *prompt, char *buf, size_t blen) {     int bl;      printf("%s: ", prompt);     fflush(stdout);      if (fgets(buf, blen, stdin) == null) {         if (ferror(stdin)) {             perror("read");         }         exit(1);     }     bl = strlen(buf);     if (bl > 0 && buf[bl - 1] == '\n') {         buf[bl - 1] = '\0';     } }  static void child_4() {     execlp("/usr/bin/ps", "ps", "-www", "-e", "f", null);      perror("exec /usr/bin/ps");     exit(1); }  static void child_3() {     char buf[256];     int fd;      run_func_in_child(child_4);      get_rsp("file name", buf, sizeof buf);      if (access(buf, f_ok) == 0) {         fprintf(stderr, "%s exists\n", buf);         exit(1);     }      if ((fd = creat(buf, 0644)) == -1) {         perror("creat");         exit(1);     }     close(fd);      printf("created empty file %s\n", buf);      exit(0); }  static void child_2() {     char buf[80];     int fd[2];     pid_t pid;      run_func_in_child(child_3);      get_rsp("phrase", buf, sizeof buf);      if (pipe(fd) == -1) {         perror("pipe");         exit(1);     }      pid = fork();      switch (pid) {     case -1:         perror("fork");         exit(1);     case 0:         /* no explicit wait child-of-child          * process, when parent (the grep) exits,          * init becomes parent, , wait          */         dup2(fd[1], 1);         close(fd[0]);         close(fd[1]);         execlp("/usr/bin/find", "find", null);         perror("exec of find");         exit(1);     default:         dup2(fd[0], 0);         close(fd[0]);         close(fd[1]);         execlp("/usr/bin/grep", "grep", buf, null);         perror("exec of grep");         exit(1);     } }  static void child_1() {     run_func_in_child(child_2);      printf("child 1: pid %d; ppid %d\n", getpid(), getppid());      exit(0); }  int main(int ac, char *av[]) {     run_func_in_child(child_1);      return 0; } 

Comments

Popular posts from this blog

Android layout hidden on keyboard show -

google app engine - 403 Forbidden POST - Flask WTForms -

c - Why would PK11_GenerateRandom() return an error -8023? -