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

extern int errno;

void parseArgs(char *path, char *argv[]) {
    while (*path != '\0') {
        while (*path == ' ' || *path == '\t' || *path == '\n') {
            *path++ = '\0';
        }
        *argv++ = path;
        while (*path != '\0' && *path != ' ' && *path != '\t' && *path != '\n') {
            path++;
        }
    }
    *argv = '\0';
}

int execArgs(char *argv[], int amp) {
    pid_t process;
    int check;

    if ((process = fork()) < 0) {
        fprintf(stderr, "Forking child failed\n%s\n", strerror(errno));
        errno = 0;
        return EXIT_FAILURE;
    } else if (process == 0) {
        if (execvp(*argv, argv) < 0) {
            fprintf(stderr, "Execution failed\n%s\n", strerror(errno));
            errno = 0;
            return EXIT_FAILURE;
        }
    } else {
        while (wait(&check) != process) {
            //do nothing
        }
    }
    return EXIT_SUCCESS;
}

int main (void) {
    char path[1024];
    char *argv[64];
    //int amp = 0;

    while (1) {
        printf("[root@localhost]$ ");
        fgets(path, 1024, stdin);
        puts("");
        parseArgs(path, argv);
        if (strcmp(argv[0], "exit") == 0) {
            return EXIT_SUCCESS;
        }
        execArgs(argv, 0);
    }
}

我这里有问题。这个问题似乎是一个解析错误,因为每当我尝试访问ls一个目录时,我都会得到ls: cannot access : No such file or directory. 奇怪的是,如果我去,ls ..我会得到:

ls: cannot access : No such file or directory
..:
cat  cat.c  cat.c~  m4

注意:以上是上一级目录的内容!

此外 - 我怀疑这些问题是相关的 - 我不能cd进入目录,但是我不能 100% 确定这一点,因为它不会抛出任何类似目录不存在的东西;我只是得到一个空格(但我的 cwd 没有更新)。

任何帮助,将不胜感激!

供参考,一些测试输入

[thanasi@localhost m4]$ ./cli
[root@localhost /home/thanasi/Systems Programming/m4]$ ls

ls: cannot access : No such file or directory
[root@localhost /home/thanasi/Systems Programming/m4]$ ls ..

ls: cannot access : No such file or directory
..:
cat  cat.c  cat.c~  m4
[root@localhost /home/thanasi/Systems Programming/m4]$ cd test

[root@localhost /home/thanasi/Systems Programming/m4]$ cd /test           

/usr/bin/cd: line 2: cd: /test: No such file or directory
[root@localhost /home/thanasi/Systems Programming/m4]$ ^C

并且确认目录'test'确实存在:

[thanasi@localhost m4]$ ls -al
total 36
drwxrwxr-x. 3 thanasi thanasi  4096 Mar 17 22:00 .
drwxrwxr-x. 3 thanasi thanasi  4096 Mar 17 20:36 ..
-rwxrwxr-x. 1 thanasi thanasi 13175 Mar 17 22:00 cli
-rw-rw-r--. 1 thanasi thanasi  1222 Mar 17 22:00 cli.c
-rw-rw-r--. 1 thanasi thanasi  1221 Mar 17 22:00 cli.c~
drwxr-xr-x. 2 root    root     4096 Mar 17 21:32 test
4

1 回答 1

3

通常,您获得的输入fgets以换行符结尾。假设你得到{'l', 's', '\n', '\0'}path. 然后,当parseArgs设置argv[0]指向 中的第一个字符时path,下一次迭代用 覆盖换行符'\0',并设置argv[1] = &path[2];

void parseArgs(char *path, char *argv[]) {
    while (*path != '\0') {
        while (*path == ' ' || *path == '\t' || *path == '\n') {
            *path++ = '\0';
        }
        *argv++ = path;
        while (*path != '\0' && *path != ' ' && *path != '\t' && *path != '\n') {
            path++;
        }
    }
    *argv = '\0';
}

所以你的argv数组包含一个指向最后一个实参数和NULL终止数组之间的空字符串的指针。因此ls尝试列出""不存在的 - 的内容。

因为你不能确定你得到的输入是否fgets以换行符结尾,所以请注意分配

if (*path) *argv++ = path;

为了避免这种情况。

于 2013-03-17T12:42:58.123 回答