コード例 #1
0
ファイル: sh61.c プロジェクト: cs61/cs61-psets
void eval_line(const char* s) {
    int type;
    char* token;
    // Your code here!

    // build the command
    command* c = command_alloc();
    while ((s = parse_shell_token(s, &type, &token)) != NULL)
        command_append_arg(c, token);

    // execute it
    if (c->argc)
        run_list(c);
    command_free(c);
}
コード例 #2
0
ファイル: cmdline.c プロジェクト: TXing123/prog1
command_t *
command_parse(parsestate_t *parsestate)
{
	int i = 0;
	command_t *cmd = command_alloc();
	if (!cmd)
		return NULL;

	int flag_in=0;
	int flag_out=0;
	int flag_err=0;
	while (1) {
		// EXERCISE: Read the next token from 'parsestate'.

		// Normal tokens go in the cmd->argv[] array.
		// Redirection file names go into cmd->redirect_filename[].
		// Open parenthesis tokens indicate a subshell command.
		// Other tokens complete the current command
		// and are not actually part of it;
		// use parse_ungettoken() to save those tokens for later.

		// There are a couple errors you should check.
		// First, be careful about overflow on normal tokens.
		// Each command_t only has space for MAXTOKENS tokens in
		// 'argv'. If there are too many tokens, reject the whole
		// command.
		// Second, redirection tokens (<, >, 2>) must be followed by
		// TOK_NORMAL tokens containing file names.
		// Third, a parenthesized subcommand can't be part of the
		// same command as other normal tokens.  For example,
		// "echo ( echo foo )" and "( echo foo ) echo" are both errors.
		// (You should figure out exactly how to check for this kind
		// of error. Try interacting with the actual 'bash' shell
		// for some ideas.)
		// 'goto error' when you encounter one of these errors,
		// which frees the current command and returns NULL.

		// Hint: An open parenthesis should recursively call
		// command_line_parse(). The command_t structure has a slot
		// you can use for parens; figure out how to use it!

		token_t token;
		memset(&token, 0, sizeof(token));
		parse_gettoken(parsestate, &token);


		switch (token.type) {
		case TOK_NORMAL:
			if(flag_out){
				flag_out=0;
				cmd->redirect_filename[1]=strdup(token.buffer);
				break;
			}
			else if(flag_in){
				flag_in=0;
				cmd->redirect_filename[0]=strdup(token.buffer);
				break;
			}
			else if(flag_err){
				flag_err=0;
				cmd->redirect_filename[2]=strdup(token.buffer);
				break;
			}
			if(i==MAXTOKENS) goto error;
			cmd->argv[i] = strdup(token.buffer);
			i++;
			break;
		case TOK_PIPE:
			cmd->controlop=CMD_PIPE;
			parse_ungettoken(parsestate);
			goto done;
		case TOK_DOUBLEPIPE:
			cmd->controlop=CMD_OR;
			parse_ungettoken(parsestate);
			goto done;
		case TOK_AMPERSAND:
			cmd->controlop=CMD_BACKGROUND;
			parse_ungettoken(parsestate);
			goto done;
		case TOK_DOUBLEAMP:
			cmd->controlop=CMD_AND;
			parse_ungettoken(parsestate);
			goto done;
		case TOK_SEMICOLON:
			cmd->controlop=CMD_SEMICOLON;
			parse_ungettoken(parsestate);
			goto done;
		case TOK_OPEN_PAREN:
			cmd->subshell=command_line_parse(parsestate,1);
			break;
		case TOK_CLOSE_PAREN:
			parse_ungettoken(parsestate);
			goto done;
		case TOK_END:
			parse_ungettoken(parsestate);
			cmd->controlop=CMD_END;
			goto done;
		case TOK_ERROR:
			goto error;
		case TOK_GREATER_THAN:
			flag_out=1;
			break;
		case TOK_LESS_THAN:
			flag_in=1;
			break;
		case TOK_2_GREATER_THAN:
			flag_err=1;
			break;
		default:
			parse_ungettoken(parsestate);
			goto done;
		}
	}

 done:
	// NULL-terminate the argv list
	cmd->argv[i] = 0;

	// EXERCISE: Make sure you return the right return value!

	if (i == 0 && cmd->subshell==NULL) {
		/* Empty command */
		command_free(cmd);
		return NULL;
	} else
		return cmd;
	
 error:
	command_free(cmd);
	return NULL;
}
コード例 #3
0
ファイル: cmdline.c プロジェクト: sauravn/ece695
command_t *
command_parse(parsestate_t *parsestate)
{
	int i = 0;
	command_t *cmd = command_alloc();
	if (!cmd)
	{
		printf("cmd alloc error\n");
		return NULL;
	}

	while (1) {
		// EXERCISE: Read the next token from 'parsestate'.

		// Normal tokens go in the cmd->argv[] array.
		// Redirection file names go into cmd->redirect_filename[].
		// Open parenthesis tokens indicate a subshell command.
		// Other tokens complete the current command
		// and are not actually part of it;
		// use parse_ungettoken() to save those tokens for later.

		// There are a couple errors you should check.
		// First, be careful about overflow on normal tokens.
		// Each command_t only has space for MAXTOKENS tokens in
		// 'argv'. If there are too many tokens, reject the whole
		// command.
		// Second, redirection tokens (<, >, 2>) must be followed by
		// TOK_NORMAL tokens containing file names.
		// Third, a parenthesized subcommand can't be part of the
		// same command as other normal tokens.  For example,
		// "echo ( echo foo )" and "( echo foo ) echo" are both errors.
		// (You should figure out exactly how to check for this kind
		// of error. Try interacting with the actual 'bash' shell
		// for some ideas.)
		// 'goto error' when you encounter one of these errors,
		// which frees the current command and returns NULL.

		// Hint: An open parenthesis should recursively call
		// command_line_parse(). The command_t structure has a slot
		// you can use for parens; figure out how to use it!

		if (i > MAXTOKENS)
			goto error;

		token_t token;
		parse_gettoken(parsestate, &token);

		switch (token.type) {
		case TOK_NORMAL:
			//printf("%s len: %d", token.buffer, strlen(token.buffer));
			if (cmd->subshell != NULL) {
				parse_ungettoken(parsestate);
				goto done;
			}
			if (strlen(token.buffer) != 0) {
				cmd->argv[i] = strdup(token.buffer);
				i++;
			}
			break;
		case TOK_LESS_THAN:
			//printf("input red\n");
			parse_gettoken(parsestate, &token);
			if (token.type != TOK_NORMAL)
				goto error;
			cmd->redirect_filename[0] = strdup(token.buffer);
						break;
		case TOK_GREATER_THAN:
			//printf("output red\n");
			parse_gettoken(parsestate, &token);
			if (token.type != TOK_NORMAL)
				goto error;
			cmd->redirect_filename[1] = strdup(token.buffer);
						break;
		case TOK_2_GREATER_THAN:
			//printf("stderr red\n");
			parse_gettoken(parsestate, &token);
			if (token.type != TOK_NORMAL)
				goto error;
			cmd->redirect_filename[2] = strdup(token.buffer);
			break;
		case TOK_OPEN_PAREN:
			cmd->subshell = command_line_parse(parsestate, PARENS_IN);
			//goto done;
			break;
		case TOK_CLOSE_PAREN:
		default:
			parse_ungettoken(parsestate);
			goto done;
		}
	}

 done:
	// NULL-terminate the argv list
	cmd->argv[i] = 0;

	// EXERCISE: Make sure you return the right return value!

	if (i == 0 && cmd->subshell == NULL) {
		/* Empty command */
		command_free(cmd);
		return NULL;
	} else
		return cmd;
	
 error:
	command_free(cmd);
	return NULL;
}
コード例 #4
0
ファイル: sh61.c プロジェクト: mamdouhweb/systems-programming
void eval_command_line(const char* s, zombies* z) {
    int type;
    char* token;
    // commandlist contains command groups separated by ';' or '&'
    command** commandlist = (command**) malloc(sizeof(command*));
    // keep track of how many command groups wehave
    int listcontent = 1;
    // Your code here!

    // build the command
    command* c = command_alloc();
    // the first command group
    commandlist[0] = c;
    while ((s = parse_shell_token(s, &type, &token)) != NULL) {
        if(type == TOKEN_CONTROL) {
            // seeing a ';' means we have to make a new command group
            if(token[0] == ';') {
                c = command_alloc();
                commandlist = (command**) realloc(commandlist, (listcontent + 1)*sizeof(command*));
                commandlist[listcontent] = c;
                ++listcontent;
                // seeing a '&' means we have to make a new command group
            } else if(token[0] == '&' && !token[1]) {
                c->background = 1;
                c = command_alloc();
                commandlist = (command**) realloc(commandlist, (listcontent + 1)*sizeof(command*));
                commandlist[listcontent] = c;
                ++listcontent;
                // putting into new command group so that we can conditionally evaluate it
            } else if(token[0] == '&' && token[1] == '&') {
                c = command_alloc();
                c->needcondition = 0;
                commandlist = (command**) realloc(commandlist, (listcontent + 1)*sizeof(command*));
                commandlist[listcontent] = c;
                ++listcontent;
                // within a command group, mark it as piping if seeing '|'
            } else if(token[0] == '|' && !token[1]) {
                c->piping = 1;
                command_append_arg(c, type, token);
                // putting into new command group so that we can conditionally evaluate it
            } else if(token[0] == '|' && token[1] == '|') {
                c = command_alloc();
                c->needcondition = 1;
                commandlist = (command**) realloc(commandlist, (listcontent + 1)*sizeof(command*));
                commandlist[listcontent] = c;
                ++listcontent;
            }
        } else if(type == TOKEN_REDIRECTION) {
            // redirecting standard input
            if(token[0] == '<' || token[0] == '0') {
                c->redirectstdin = 1;
                // redirecting standard output
            } else if(token[0] == '>' || token[0] == '1') {
                c->redirectstdout = 1;
                // redirecting standard error
            } else if(token[0] == '2' && token[1] == '>') {
                c->redirectstderr = 1;
            }
        } else {
            // the token following a redirection token must be a file name that should be dup'ed
            // then clears the flag
            if(c->redirectstdin) {
                c->stdinfilename = token;
                c->redirectstdin = 0;
            } else if(c->redirectstdout) {
                c->stdoutfilename = token;
                c->redirectstdout = 0;
            } else if(c->redirectstderr) {
                c->stderrfilename = token;
                c->redirectstderr = 0;
                // all other normal tokens
            } else {
                command_append_arg(c, type, token);
            }
        }
    }

    // execute the command
    int condition = -1;	// exit condition of previous command
    for(int i = 0; i < listcontent; i++) {
        if (commandlist[i]->argc)
            // test if this command group should run
            if (commandlist[i]->needcondition == -1 || (commandlist[i]->needcondition == 0 && condition == 0) || (commandlist[i]->needcondition == 1 && condition != 0))
                eval_command(commandlist[i], &condition, z);
        command_free(commandlist[i]);
    }
    free(commandlist);
}