⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shell.c~

📁 The main purpose of this project is to add a new scheduling algorithm to GeekOS and to implement a s
💻 C~
字号:
/* * A really, really simple shell program * Copyright (c) 2003, Jeffrey K. Hollingsworth <hollings@cs.umd.edu> * Copyright (c) 2003,2004 David H. Hovemeyer <daveho@cs.umd.edu> * $Revision: 1.18 $ *  * This is free software.  You are permitted to use, * redistribute, and modify it as specified in the file "COPYING". */#include <geekos/errno.h>#include <conio.h>#include <process.h>#include <string.h>#define BUFSIZE 79#define DEFAULT_PATH "/c:/a"#define INFILE	0x1#define OUTFILE	0x2#define PIPE	0x4#define ISSPACE(c) ((c) == ' ' || (c) == '\t')struct Process {    int flags;    char program[BUFSIZE+1];    char infile[BUFSIZE+1];    char outfile[BUFSIZE+1];    char *command;    int pid;    int readfd, writefd;    int pipefd;};char *Strip_Leading_Whitespace(char *s);void Trim_Newline(char *s);char *Copy_Token(char *token, char *s);int Build_Pipeline(char *command, struct Process procList[]);void Spawn_Single_Command(struct Process procList[], int nproc, const char *path);/* Maximum number of processes allowed in a pipeline. */#define MAXPROC 5int exitCodes = 0;int main(int argc, char **argv){    int nproc;    char commandBuf[BUFSIZE+1];    struct Process procList[MAXPROC];    char path[BUFSIZE+1] = DEFAULT_PATH;    char *command;    /* 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);	/*	 * 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;	}	/*	 * Parse the command string and build array of	 * Process structs representing a pipeline of commands.	 */	nproc = Build_Pipeline(command, procList);	if (nproc <= 0)	    continue;	Spawn_Single_Command(procList, nproc, path);            }    Print_String("DONE!\n");    return 0;}/* * Skip leading whitespace characters in given string. * Returns pointer to first non-whitespace character in the string, * which may be the end of the string. */char *Strip_Leading_Whitespace(char *s){    while (ISSPACE(*s))	++s;    return s;}/* * Destructively trim newline from string * by changing it to a nul character. */void Trim_Newline(char *s){    char *c = strchr(s, '\n');    if (c != 0)	*c = '\0';}/* * Copy a single token from given string. * If a token is found, returns pointer to the * position in the string immediately past the token: * i.e., where parsing for the next token can begin. * If no token is found, returns null. */char *Copy_Token(char *token, char *s){    char *t = token;    while (ISSPACE(*s))	++s;    while (*s != '\0' && !ISSPACE(*s))	*t++ = *s++;    *t = '\0';    return *token != '\0' ? s : 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;}/* * Spawn a single command. */void Spawn_Single_Command(struct Process procList[], int nproc, const char *path){    int pid;    if (nproc > 1) {	Print("Error: pipes not supported yet\n");	return;    }    if (procList[0].flags & (INFILE|OUTFILE)) {	Print("Error: I/O redirection not supported yet\n");	return;    }    pid = Spawn_With_Path(procList[0].program, procList[0].command,	path);    if (pid < 0)	Print("Could not spawn process: %s\n", Get_Error_String(pid));    else {	int exitCode = Wait(pid);	if (exitCodes)	    Print("Exit code was %d\n", exitCode);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -