int main(int argc, char **argv) { char commandBuf[BUFSIZE + 1]; struct Process proc; char path[BUFSIZE + 1] = DEFAULT_PATH; char *command; int detached; /* Set attribute to gray on black. */ Print("\x1B[37m"); while (true) { /* Print shell prompt (bright cyan on black background) */ Print("\x1B[1;36m$\x1B[37m "); /* Read a line of input */ Read_Line(commandBuf, sizeof(commandBuf)); command = Strip_Leading_Whitespace(commandBuf); Trim_Newline(command); detached = isDetached(command); /* * Handle some special commands */ if (strcmp(command, "exit") == 0) { /* Exit the shell */ break; } else if (strcmp(command, "pid") == 0) { /* Print the pid of this process */ Print("%d\n", Get_PID()); continue; } else if (strcmp(command, "exitCodes") == 0) { /* Print exit codes of spawned processes. */ exitCodes = 1; continue; } else if (strncmp(command, "path=", 5) == 0) { /* Set the executable search path */ strcpy(path, command + 5); continue; } else if (strcmp(command, "") == 0) { /* Blank line. */ continue; } proc.command = Strip_Leading_Whitespace(command); if (!Copy_Token(proc.program, proc.command)) { Print("Error: invalid command\n"); continue; } Spawn_Single_Command(&proc, path, detached); if (detached && proc.pid > 0) Print("[%d]\n", proc.pid); } Print_String("DONE!\n"); return 0; }
/* * Build process pipeline. */ int Build_Pipeline(char *command, struct Process procList[]) { int nproc = 0, i; while (nproc < MAXPROC) { struct Process *proc = &procList[nproc]; char *p, *s; proc->flags = 0; command = Strip_Leading_Whitespace(command); p = command; if (strcmp(p, "") == 0) break; ++nproc; s = strpbrk(p, "<>|"); /* Input redirection from file? */ if (s != 0 && *s == '<') { proc->flags |= INFILE; *s = '\0'; p = s+1; s = Copy_Token(proc->infile, p); if (s == 0) { Print("Error: invalid input redirection\n"); return -1; } p = s; /* Output redirection still allowed for this command. */ p = Strip_Leading_Whitespace(p); s = (*p == '>' || *p == '|') ? p : 0; } /* Output redirection to file or pipe? */ if (s != 0 && (*s == '>' || *s == '|')) { bool outfile = (*s == '>'); proc->flags |= (outfile ? OUTFILE : PIPE); *s = '\0'; p = s+1; if (outfile) { s = Copy_Token(proc->outfile, p); if (s == 0) { Print("Error: invalid output redirection\n"); return -1; } p = s; } } proc->command = command; /*Print("command=%s\n", command);*/ if (!Copy_Token(proc->program, command)) { Print("Error: invalid command\n"); return -1; } if (p == command) command = ""; else command = p; } if (strcmp(command,"") != 0) { Print("Error: too many commands in pipeline\n"); return -1; } #if 0 for (i = 0; i < nproc; ++i) { struct Process *proc = &procList[i]; Print("program=%s, command=\"%s\"\n", proc->program, proc->command); if (proc->flags & INFILE) Print("\tinfile=%s\n", proc->infile); if (proc->flags & OUTFILE) Print("\toutfile=%s\n", proc->outfile); if (proc->flags & PIPE) Print("\tpipe\n"); } #endif /* * Check commands for validity */ for (i = 0; i < nproc; ++i) { struct Process *proc = &procList[i]; if (i > 0 && (proc->flags & INFILE)) { Print("Error: input redirection only allowed for first command\n"); return -1; } if (i < nproc-1 && (proc->flags & OUTFILE)) { Print("Error: output redirection only allowed for last command\n"); return -1; } if (i == nproc-1 && (proc->flags & PIPE)) { Print("Error: unterminated pipeline\n"); return -1; } } return nproc; }