简体   繁体   English

简单的Linux Shell-execvp()失败

[英]Simple Linux Shell - execvp() failing

I need some help with a simple shell for class, and I'm worried I don't quite understand how the execvp() function works. 我需要一个用于类的简单shell的帮助,而且我担心我不太了解execvp()函数的工作方式。

The shell does not do much, does not support piping, redirection, scripting or anything fancy like that. Shell并没有做很多事情,不支持管道,重定向,脚本或类似的东西。 It only reads a command, reads in the options (with the command as option[0]), and forks. 它仅读取命令,读取选项(命令为option [0]),然后派生。

It worked a few times, then started giving me errors about not being able to find commands. 它工作了几次,然后开始给我有关无法找到命令的错误。 Other similar questions posted here had to do with piping or redirection. 此处发布的其他类似问题与管道或重定向有关。

Please forgive the noobcode, it's not pretty, but I hope it's legible: 请原谅noobcode,它虽然不漂亮,但我希望它清晰易读:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>

#define OPT_AMT 10

const size_t SIZE = 256;
int i = 0;
int o = 0;

int main(void) {

    // initializing data

    int exit = 0;
    char cwd[SIZE];
    char cmd[SIZE];
    char input[SIZE * OPT_AMT];
    char *opt[OPT_AMT];
    getcwd(cwd, SIZE);

    // main loop

    while (exit == 0) {
        // reset everything
        o = 1;
        i = 0;
        cmd[0] = "\0";
        while (i < OPT_AMT) {
            opt[i++] = "\0";
        }

        // get input
        printf("%s $ ", cwd);
        scanf("%s", cmd);
        gets(input);
        opt[0] = cmd;

        char *t = strtok(input, " ");
        while (t != NULL) {
            opt[o++] = t;
            t = strtok(NULL, " ");
        }

        // if exit, exit
        if (strcmp(cmd, "exit") == 0) {
            exit = 1;
        }
        // else fork and execute
        else {
            pid_t pID = fork();

            if (pID == 0) { // child process
                execvp(cmd, opt);
            } else if (pID < 0) { // failed to fork
                printf("\nFailed to fork\n");
            } else { // parent process
                wait(0);
            }
        }
    }

    // cleanup

    printf("\nFinished!  Exiting...\n");
    return 0;
}

Anything blatantly wrong? 有什么公然的错误吗? I most recently added the exit condition and the resetting the options array. 我最近添加了退出条件和重置options数组。

Also, this is my first question, so remind me of any rules I may have broken. 另外,这是我的第一个问题,因此请提醒我可能违反的任何规则。

For starters, this 对于初学者,这

cmd[0] = "\0";

ought to be 必定是

cmd[0] = '\0';

Listen to your compiler's warnings. 听您的编译器的警告。

To enable them use the options -Wall -Wextra -pedantic (for gcc). 要启用它们,请使用-Wall -Wextra -pedantic选项(对于gcc)。


Also you might better want to initalise opt 's elements to point to "nothing", that is NULL but to the literal "\\0" : 另外,您可能最好将opt的元素初始化为指向“ nothing”,即NULL但指向文字"\\0"

    while (i < OPT_AMT) {
        opt[i++] = NULL;
    }

as execvp() requires opt to be a NULL -terminated array of C-"strings" (thanks Paul for mentioning/wording the relevant background). 因为execvp()要求optNULL终止的C-“字符串”数组(感谢Paul提及/措辞相关背景)。


Also^2: Do not use gets() , as it's evil and not even part of the C Standard anymore. 另外^ 2:不要使用gets() ,因为它很邪恶,甚至不再是C标准的一部分。 Instead of 代替

gets(input);

use 采用

fgets(input, sizeof input, stdin);

gets() easyly let's the user overflow the (input) buffer passed. gets()容易让用户使传递的(输入)缓冲区溢出。 (Mentioning this came to my mind without Paul, btw ... ;-)) (想到这一点,我没有保罗,顺便说一句; ;-))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM