/* file: matrix.c * author: Robert S. Laramee * class: cs720/820 * date started: 27 Jan 98 * date finished: 27 Jan 98 * project: assignment 1 * description: This program should read in the following command * line arguments: name of the data file, number of * rows and columns in matrixA, and the number of rows and columns in * matrixB, in this order. For example % matrix mat.dat 2 10 10 5 * * argv[0] = matrix -name of program * argv[1] = mat.dat -name of input file * argv[2] = x -number of rows in matrix A * argv[3] = x -number of columnss in matrix A * argv[4] = x -number of rows in matrix B * argv[5] = x -number of columns in matrix B */ #include/* for fork(), wait(), getpid(), */ #include /* for wait(), */ #include /* for fork(), exec(), read() */ #include /* for printf(), scanf() */ #include /* for */ #include /* for strcmp() */ #include /* for errno, EINTR */ #define YES 0 #define NO -1 void main(int argc,char *argv[]) { pid_t childpid; pid_t child1pid, child2pid, child3pid; /* the children's process ID */ int status, i; int addsubtract = YES; int multiply = YES; char row[50], row3[50]; int num_rows = atoi(argv[2]); if (argc != 6) { /* check command line */ printf("\n Error in usage. e.g. % matrix mat.dat 2 10 10 5 \n"); exit(1); } /* Check to see if matrices can be add and subracted by comparing */ /* the number of rows and columns of each. */ if ( strcmp(argv[2], argv[4]) || strcmp(argv[3], argv[5]) ) { fprintf(stderr, "\n These matrices cannot be added or subtracted. \n"); addsubtract = NO; } /* The product of two matrices is not defined when the number of * columns in the first matrix and the number of rows in the second * matrix are not the same */ if ( strcmp(argv[3], argv[4]) ) { fprintf(stderr, "\n These matrices cannot be multiplied. \n"); multiply = NO; } for (i = 0; i < num_rows; i++) { sprintf(row, "%d", i*2); /* times 2 for every other even row */ sprintf(row3, "%d", i); /* separate for 3rd child */ if (addsubtract == YES) { if ((childpid = fork()) == -1) { printf("\n Error in 1st fork() \n."); exit(1); } else if (childpid == 0) { if (execl("child1", "child1", argv[1], row, argv[3], NULL) < 0) { printf("\n Error in 1st exec1() \n"); exit(1); } } if ((childpid = fork()) == -1) { printf("\n Error in 2nd fork() \n."); exit(1); } else if (childpid == 0) { if (execl("child2", "child2", argv[1], row, argv[3], NULL) < 0) { printf("\n Error in 2nd exec1() \n"); exit(1); } } } /* end if addsubtract == YES */ if (multiply == YES) { if ((childpid = fork()) == -1) { printf("\n Error in 3rd fork() \n."); exit(1); } else if (childpid == 0) { if (execl("child3", "child3", argv[1], row3, argv[2], argv[3], argv[5], NULL) < 0) { printf("\n Error in 3rd exec1() \n"); exit(1); } } } /* end if multiply == YES */ /* Because none of the forked children are parents, their wait() * returns -1 and sets errno to ECHILD (indicates that there no * un-waited-for child processes). They are not blocked * by this second for loop. Their identification messages can come * out it any order. The message for the original process comes * out at the very end after it has waited for all its children. */ for ( ; ; ) { childpid = wait(&status); if ((childpid == -1) && (errno != EINTR)) /* signal interruption */ break; } /* printf("\n I am process %ld, my parent is %ld. \n", (long)getpid(), (long)getppid()); */ } /* end for() */ exit(0); }