Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/wait.h>
- #include <string.h>
- #define MAX_ARGS 20
- #define MAX_WORD 10
- #define MAX_LINE 1024
- #define MAX_CMDS 1024
- // pids of each child process
- int maxProc = 1;
- int availProc = 1;
- int* procs;
- // actual cmds for each process
- int cmdId = 0;
- int* cmdc;
- char*** cmds;
- void err(char *msg) {
- fprintf(stderr, "%s", msg);
- }
- void waitChild() {
- int status;
- int pid = wait(&status);
- if (status > 0) {
- err("exec failure:");
- int cmd = 0;
- for(cmd=0; cmd<=cmdId; cmd++){
- if(procs[cmd] == pid) {
- break;
- }
- }
- int argc = cmdc[cmd];
- char** argv = cmds[cmd];
- for(int i=0; i<argc; i++){
- err(" ");
- err(argv[i]);
- }
- exit(1);
- }
- }
- void run(int argc, char **argv, int usePath) {
- int child, status;
- while (availProc == 0) {
- waitChild();
- availProc++;
- }
- if ((child=fork()) == 0){
- if (usePath) {
- execvp(argv[0], argv);
- } else {
- char* envp[] = { NULL };
- execve(argv[0], argv, envp);
- }
- exit(1); // execve failed
- } else if (child == -1) {
- err("fork failure"); exit(1);
- } else {
- availProc--;
- procs[cmdId] = child;
- }
- }
- // === STRING FUNCS === //
- // remove newline at the back of string
- void trim(char* str) {
- int idx = strlen(str)-1;
- if (str[idx] == '\n') {
- str[idx] = 0;
- }
- }
- // returns count of tkns
- int tokenize(char* str, char** argv) {
- int cnt = 0; trim(str);
- char* tkn = strtok(str, " ");
- while (tkn) {
- argv[cnt++] = tkn;
- tkn = strtok(NULL, " ");
- }
- return cnt;
- }
- // put everything tgt into total and return leng
- int combineCmd(int cmdc, char** cmd, int extc, char** ext, char** total) {
- int idx = 0;
- int changed = 0;
- for(int i=0; i<cmdc; i++) {
- if (strcmp(cmd[i], "%")==0) {
- if (changed < extc) {
- total[idx++] = ext[changed++];
- }
- } else {
- total[idx++] = cmd[i];
- }
- }
- total[idx] = NULL;
- return idx;
- }
- // copy array
- char** copy(char** orig, int cnt) {
- char **full = calloc(MAX_WORD+MAX_ARGS, sizeof(char*));
- for (int i=0; i<cnt; i++) {
- full[i] = calloc(MAX_WORD, sizeof(char));
- strcpy(full[i], orig[i]);
- }
- return full;
- }
- int main(int rargc, char **rargv) {
- procs = calloc(MAX_CMDS, sizeof(int));
- cmdc = calloc(MAX_CMDS, sizeof(int));
- cmds = calloc(MAX_CMDS, sizeof(char**));
- // ignore orig file
- rargc--; rargv++;
- int usePath = 0;
- // in case of flags in wrong order
- for (int i=0; i<2; i++) {
- if (strcmp(rargv[0], "-p") == 0) {
- char path[MAX_ARGS+5] = "PATH=";
- strcat(path, rargv[1]);
- usePath = 1;
- putenv(path);
- rargc -= 2; rargv += 2;
- }
- if (strcmp(rargv[0], "-j") == 0) {
- maxProc = atoi(rargv[1]);
- availProc = maxProc;
- rargc -= 2; rargv += 2;
- }
- }
- char line[MAX_LINE];
- char **argv = calloc(MAX_WORD, sizeof(char*));
- char **full = calloc(MAX_WORD+MAX_ARGS, sizeof(char*));
- int argc, fulc;
- while(fgets(line, sizeof(line), stdin) != NULL) {
- argc = tokenize(line, argv);
- fulc = combineCmd(rargc, rargv, argc, argv, full);
- cmds[cmdId] = copy(full, fulc);
- cmdc[cmdId] = fulc;
- run(fulc, full, usePath);
- cmdId++;
- }
- for(int i=0; i<maxProc-availProc; i++){
- waitChild();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement