All pastes #945390 Raw Edit

Something

public c v1 · immutable
·published 2008-03-16 22:03 UTC
rendered paste body
#include <stdio.h>#include <stdlib.h>#include <sys/stat.h>#include <string.h>#include <fcntl.h>#include <stddef.h>#include <sys/types.h>#include <unistd.h>#include <sys/wait.h>#define MAX_PATH 2048// Maximal full path length we support#define MAX_COMMANDS 8#define MAX_COMMAND_LENGTH 48int main (int argc, char **argv) {  int i = 0;  int j = 0;  int k = 0; //test only  int fork_num = 0;  int status;  char file_name[MAX_PATH];  char file_path[MAX_PATH + 1];  FILE* cmd_file;  struct stat file_stat;  char *cmd_hldr;//[MAX_COMMAND_LENGTH];  char *cmd_ary[MAX_COMMANDS];  //add another dimension here for each arg  char *delimiter = " ";  pid_t childpid;  char *cmd_to_fork[MAX_COMMAND_LENGTH];  int totalpipeid[16];//Stores the ids of the pipes  //check if there is enough arguements (a filename and nothing more)  if (argc != 2) {    fprintf(stderr, "invalid number of arguments, please supply a filename\n");    perror("Error");    exit(1);  }  strcpy(file_name, argv[1]);  strcpy(file_path, "./");  strcat(file_path, file_name);  // obtain file status  if (stat(file_path, &file_stat) == -1) {    // error getting stat    fprintf(stderr, "%s cannot be read properly (cannot get stat)\n",file_name);    perror ("Error");    exit(1);  }  //check if the filename names a regular file  if(S_ISREG(file_stat.st_mode)) {    //printf("'%s' is regular file at '%s'\n", file_name, file_path);    cmd_file = fopen(file_path, "r");    //make sure file opens ok    if (!cmd_file) {      fprintf(stderr, "Failed opening file %s for reading \n", file_path);      perror ("Error");      exit(1);    }    cmd_hldr = malloc(MAX_COMMAND_LENGTH);    //loop to read each command from the file, into cmd_ary    while((fgets(cmd_hldr, MAX_COMMAND_LENGTH, cmd_file)) != NULL) {      if(fork_num > 7) {         fprintf(stderr, "File contains too many commands, will only performthe first %d\n", MAX_COMMANDS);         perror ("Error:");         break;      }      //unessecary, don't need to remove newline from command strings      /*for(i = 0; i < MAX_COMMAND_LENGTH;i++) {       //printf("char %d of command %d is %c\n", i, fork_num, cmd_hldr[i]);         if (cmd_hldr[i] == "\n") {         cmd_hldr[i] = " ";           //cmd_hldr[i+1] = " ";            break;            }            }*/      cmd_ary[fork_num] = malloc(strlen(cmd_hldr) + 1);      strcpy(cmd_ary[fork_num], cmd_hldr);      //printf("command number %d is %s\n", fork_num, cmd_ary[fork_num]);      fork_num++;    }    if (fclose(cmd_file) == -1) {      fprintf(stderr, "unable to close [%s]\n", file_path);      perror("Error");      exit(1);    }  }  //file named by filename is not a regular file, quit  else {    fprintf(stderr, "%s is not a regular file\n", file_name);    perror("Error");    exit(1);  }  /*************************************   * file is open now, next read   * commands one by one, forking them   * to seperate processes   ************************************/  //In case there is only a single command  if (fork_num == 1) {    childpid = fork();    int j = 0;    if (childpid == 0) {      //Store the program name for execution      cmd_hldr = strtok(cmd_ary[i], delimiter);      char program_name[strlen(cmd_hldr)];      strcpy(program_name,cmd_hldr);      printf("program name is  %s\n",cmd_hldr);      //Store the arguments for the program      while (( cmd_hldr = strtok(NULL, delimiter)) != NULL) {         j++;         cmd_to_fork[j] = malloc(strlen(cmd_hldr) + 1);         strcpy(cmd_to_fork[j], cmd_hldr);         printf("Arg %d of command [%s] is [%s]\n", j, program_name,cmd_to_fork[j]);      }      execvp(program_name, cmd_to_fork);      perror("I could not call exec for some reason");      return 0;    }    wait(&status);    if (WIFEXITED(status) != 1) {      perror("Failure to Exit safely");    }    return 1;  }  //Build up an array of pipeids  typedef int* my_type;  my_type pipeids[fork_num];  int t;  for (t =0; t < 1; t++) {    int pipenum[2];    if (pipe(pipenum) == -1) {      perror("Failure of pipe");    }    pipeids[t] = pipenum;  }  //Iterate over all the commands  for(i = 0; i < fork_num; i++) {    //printf("executing command number %d which is %s\n", i, cmd_ary[i]);    int j = 0;    //Store the program name for execution    cmd_hldr = strtok(cmd_ary[i], delimiter);    char program_name[strlen(cmd_hldr)];    strcpy(program_name,cmd_hldr);    //printf("program name is  %s\n",cmd_hldr);    //Store the arguments for the program    while (( cmd_hldr = strtok(NULL, delimiter)) != NULL) {      j++;      cmd_to_fork[j] = malloc(strlen(cmd_hldr) + 1);      strcpy(cmd_to_fork[j], cmd_hldr);      //printf("Arg %d of command [%s] is [%s]\n", j, program_name,cmd_to_fork[j]);    }    //Initial Case    if (i == 0) {      perror("I am initial");      childpid = fork();      if (childpid ==0 ){         if (dup2(pipeids[i][1],1) == -1) {           perror("Failed at initial redirect");         }         else if (close(pipeids[i][1]) == -1) {           perror("Failed to close pipe");         }         else {           if (execvp(program_name,cmd_to_fork) == -1) {             perror("Failure calling initial executable");           }         }         return 0;      }      wait(&status);      if (WIFEXITED(status) != 1) {         perror("child exit error");      }      close(pipeids[i][1]);      continue;    }    childpid = fork();    //Middle Case    if (i != fork_num-1) {//i is NOT the last command      perror("Middle case");      childpid = fork();      if (childpid == 0 ) {         if ((dup2(pipeids[i-1][0], 0) == -1 ) || (dup2(pipeids[i][1],1)==-1))           perror("Failed to redirect stdin of sort");         else if ((close(pipeids[i-1][0]) == -1) || (close(pipeids[i][1]) ==-1) ) {           perror("failed at closing");         }         else {           if (execvp(program_name,cmd_to_fork) == -1) {             perror("Failure calling Middle executable");           }         }         return 1;      }      wait(&status);      if (WIFEXITED(status) != 1) {         perror("child exit error");      }      close(pipeids[i-1][0]);      close(pipeids[i][1]);      continue;    }    //End Case    childpid = fork();    perror("End case");    if (childpid==0) {      if (dup2(pipeids[i-1][0] , 0) == -1) {         perror("Failed to redirect stdout of  sort");      }      else if (close(pipeids[i-1][0]) == -1) {         perror("failed at closing");      }      else {         if (execvp(program_name,cmd_to_fork) == -1) {           perror("Failure calling Final executable");         }      }      return 1;    }    wait(&status);    if (WIFEXITED(status) != 1) {      perror("child exit error");    }    close(pipeids[i-1][0]);  }  return 1;}