Advertisement
Guest User

Untitled

a guest
Mar 23rd, 2019
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.77 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <sys/wait.h>
  5.  
  6. #include <string.h>
  7.  
  8. #define MAX_ARGS 20
  9. #define MAX_WORD 10
  10. #define MAX_LINE 1024
  11. #define MAX_CMDS 1024
  12.  
  13. // pids of each child process
  14. int maxProc = 1;
  15. int availProc = 1;
  16. int* procs;
  17.  
  18. // actual cmds for each process
  19. int cmdId = 0;
  20. int* cmdc;
  21. char*** cmds;
  22.  
  23. void err(char *msg) {
  24. fprintf(stderr, "%s", msg);
  25. }
  26.  
  27. void waitChild() {
  28. int status;
  29. int pid = wait(&status);
  30.  
  31. if (status > 0) {
  32. err("exec failure:");
  33.  
  34. int cmd = 0;
  35. for(cmd=0; cmd<=cmdId; cmd++){
  36. if(procs[cmd] == pid) {
  37. break;
  38. }
  39. }
  40.  
  41. int argc = cmdc[cmd];
  42. char** argv = cmds[cmd];
  43.  
  44. for(int i=0; i<argc; i++){
  45. err(" ");
  46. err(argv[i]);
  47. }
  48. exit(1);
  49. }
  50. }
  51.  
  52. void run(int argc, char **argv, int usePath) {
  53. int child, status;
  54.  
  55. while (availProc == 0) {
  56. waitChild();
  57. availProc++;
  58. }
  59.  
  60. if ((child=fork()) == 0){
  61. if (usePath) {
  62. execvp(argv[0], argv);
  63. } else {
  64. char* envp[] = { NULL };
  65. execve(argv[0], argv, envp);
  66. }
  67.  
  68. exit(1); // execve failed
  69. } else if (child == -1) {
  70. err("fork failure"); exit(1);
  71. } else {
  72. availProc--;
  73. procs[cmdId] = child;
  74. }
  75. }
  76.  
  77. // === STRING FUNCS === //
  78.  
  79. // remove newline at the back of string
  80. void trim(char* str) {
  81. int idx = strlen(str)-1;
  82. if (str[idx] == '\n') {
  83. str[idx] = 0;
  84. }
  85. }
  86.  
  87. // returns count of tkns
  88. int tokenize(char* str, char** argv) {
  89. int cnt = 0; trim(str);
  90.  
  91. char* tkn = strtok(str, " ");
  92. while (tkn) {
  93. argv[cnt++] = tkn;
  94. tkn = strtok(NULL, " ");
  95. }
  96.  
  97. return cnt;
  98. }
  99.  
  100. // put everything tgt into total and return leng
  101. int combineCmd(int cmdc, char** cmd, int extc, char** ext, char** total) {
  102. int idx = 0;
  103. int changed = 0;
  104.  
  105. for(int i=0; i<cmdc; i++) {
  106. if (strcmp(cmd[i], "%")==0) {
  107. if (changed < extc) {
  108. total[idx++] = ext[changed++];
  109. }
  110. } else {
  111. total[idx++] = cmd[i];
  112. }
  113. }
  114. total[idx] = NULL;
  115.  
  116. return idx;
  117. }
  118.  
  119. // copy array
  120. char** copy(char** orig, int cnt) {
  121. char **full = calloc(MAX_WORD+MAX_ARGS, sizeof(char*));
  122.  
  123. for (int i=0; i<cnt; i++) {
  124. full[i] = calloc(MAX_WORD, sizeof(char));
  125. strcpy(full[i], orig[i]);
  126. }
  127. return full;
  128. }
  129.  
  130. int main(int rargc, char **rargv) {
  131. procs = calloc(MAX_CMDS, sizeof(int));
  132. cmdc = calloc(MAX_CMDS, sizeof(int));
  133. cmds = calloc(MAX_CMDS, sizeof(char**));
  134.  
  135. // ignore orig file
  136. rargc--; rargv++;
  137.  
  138. int usePath = 0;
  139.  
  140. // in case of flags in wrong order
  141. for (int i=0; i<2; i++) {
  142. if (strcmp(rargv[0], "-p") == 0) {
  143. char path[MAX_ARGS+5] = "PATH=";
  144. strcat(path, rargv[1]);
  145.  
  146. usePath = 1;
  147. putenv(path);
  148.  
  149. rargc -= 2; rargv += 2;
  150. }
  151.  
  152. if (strcmp(rargv[0], "-j") == 0) {
  153. maxProc = atoi(rargv[1]);
  154. availProc = maxProc;
  155. rargc -= 2; rargv += 2;
  156. }
  157. }
  158.  
  159. char line[MAX_LINE];
  160. char **argv = calloc(MAX_WORD, sizeof(char*));
  161. char **full = calloc(MAX_WORD+MAX_ARGS, sizeof(char*));
  162.  
  163. int argc, fulc;
  164. while(fgets(line, sizeof(line), stdin) != NULL) {
  165. argc = tokenize(line, argv);
  166. fulc = combineCmd(rargc, rargv, argc, argv, full);
  167.  
  168. cmds[cmdId] = copy(full, fulc);
  169. cmdc[cmdId] = fulc;
  170.  
  171. run(fulc, full, usePath);
  172. cmdId++;
  173. }
  174.  
  175. for(int i=0; i<maxProc-availProc; i++){
  176. waitChild();
  177. }
  178. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement