【问题标题】:Function chdir() is behaving weirdly函数 chdir() 行为怪异
【发布时间】:2015-10-01 14:49:36
【问题描述】:
int cmd_cd(char* argv[]) {
  if(argv[1] == NULL || strncmp("~", argv[1], 1) == 0){
    struct passwd *pw = getpwuid(getuid());
    if(argv[1] == NULL || strlen(argv[1]) == 1){
      argv[1] = pw->pw_dir;
    }
    else{
      char path[strlen(pw->pw_dir) + strlen(arg[1])];
      strcpy(path, pw->pw_dir);
      argv[1] = &argv[1][1];
      strcat(path, argv[1]);
      argv[1] = path;
    }
  }

  if(chdir(argv[1])<0) {
    printf("Not a valid path\n");
    return -1;
  }
  return 0;
}

上面是一个sn-p的代码,我正在尝试在其中制作一个玩具linux shell。但是上面的代码在我输入时有问题

$ cd ~/代码

它按预期执行,但在以下情况下,它显示“不是有效路径”。而且我不知道为什么。

$ cd ~/code/[name_of_some_valid_directory]

【问题讨论】:

  • 那里有任何路径还是只有一些路径? errno 失败时设置了什么值?
  • 如果 'argv' 具有通常的含义,那么它位于只读内存中,因此运行它的结果将是一个段错误事件。
  • strncmp("~", argv[1], 1) == 0) 如果您将其写为:argv[1][0] == '~' 会更简单、更快且更具可读性
  • 问题是关于运行时问题。因此,代码必须干净地编译、可执行并显示问题。发布的代码不符合任何标准
  • @user3629249: main()'s char** "string"s 不是 const 或只读的。

标签: c linux shell chdir


【解决方案1】:

path 在退出它定义的块时被删除。

试试这个:

int cmd_cd(char* argv[]) {
  char *path = NULL;
  if(argv[1] == NULL || strncmp("~", argv[1], 1) == 0){
    struct passwd *pw = getpwuid(getuid());
    if(argv[1] == NULL || strlen(argv[1]) == 1){
      argv[1] = pw->pw_dir;
    }
    else{
      path = malloc(strlen(pw->pw_dir) + strlen(arg[1]));
      if (path == NULL){
        printf("Memory allocation failed\n");
        return -1;
      }
      strcpy(path, pw->pw_dir);
      argv[1] = &argv[1][1];
      strcat(path, argv[1]);
      argv[1] = path;
    }
  }

  if(chdir(argv[1])<0) {
    printf("Not a valid path\n");
    if (path != NULL) free(path);
    return -1;
  }
  if (path != NULL) free(path);
  return 0;
}

如果需要使用mallocfree,请将#include &lt;stdlib.h&gt; 添加到代码的头部。

【讨论】:

  • 这个测试if (path != NULL) 是不需要的,因为在空指针上调用free() 是明确定义的。
【解决方案2】:

这里分配的值

argv[1] = path;

这里不再有效

if(chdir(argv[1])<0) {

因为定义path的作用域({...})已经被保留,所以argv[1]指向无效内存。

chdir() 的调用然后访问了这个无效内存,这反过来又引发了臭名昭著的未定义行为,从那时起任何事情都可能发生。

【讨论】:

    猜你喜欢
    • 2011-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-12
    • 2019-08-24
    • 2018-07-18
    • 1970-01-01
    相关资源
    最近更新 更多