1

我需要在 C 中实现一个基本的 shell。我需要的一件事是实现一个具有命令的函数并执行它。我的代码:

    pID=fork();

    if (pID == 0)
       execvp(tmp[0], tmp);
    else if (pID > 0)
    {
       printf("%d", pID);
       wait(NULL);
    }
    else
      printf("Failed to create proccess \n");

问题是,无论我在 tmp 中输入什么命令,程序都会再次向我显示提示,除此之外什么也不做。例如,如果我写gedit(为了打开geditUbuntu 的 ntpad),它不会打开它,或者如果写ls -a它不会像 Ubuntu 的终端那样向我显示任何输出。

4

3 回答 3

2

execvp 应该可以工作。正如其他人提到的,您确实需要展示如何填充 tmp。也就是说,我猜这就是错误所在。tmp 需要是一个空终止的数组。

#include <stdio.h>
main( int argc, char * argv[] )
{
int    pid = fork;
char * tmp[2];
  memset( tmp, 0, sizeof(tmp) );
  tmp[0] = argv[0];
  if( 0 == pid )
  {
    if( -1 == execvp( tmp[0], tmp ) )
    {
      char errmsg[64];
      snprintf( errmsg, sizeof(errmsg), "exec '%s' failed", tmp[0] );
      perror( errmsg );
    }
  else if( 0 < pid )
  {
    printf("[%d] %s\n", pid, tmp[0]);
    wait(NULL);
  }
  else
  {
    perror("fork failed");
  }
}
于 2012-08-22T22:21:42.117 回答
1

虽然你没有告诉我们你通过tmp变量传递了什么 to execvp,但我的精神感觉告诉我你忘记了以空终止你的参数列表。NULL 参数告诉execvp最后一个参数在哪里,如果你没有输入 NULL,它将开始从堆栈中读取随机垃圾。

如果该随机垃圾指向大量非零数据,它将用完空间来存储新进程的假定参数,这通常是几百 KB(请参阅此页面以获取一些系统特定的数字,以及作为获取系统最大参数大小的各种方法)。

当参数数据过多时,系统调用execve(2)(由 内部调用execvp)失败并返回错误E2BIG

因此,要查看这是否发生在您身上,请检查execvp. 如果它甚至完全返回,它就失败了(如果它成功了,它就不会返回,因为一个新进程正在执行!),所以检查全局值errno以了解它失败的原因:

if (pID == 0)
{
    execvp(tmp[0], tmp);
    printf("exec failed: %s\n", strerror(errno));
    exit(1);
}
于 2012-08-22T22:35:39.207 回答
0

execvp() 需要完整路径。如果在 tmp[0] 中不是可执行文件的完整路径,请使用 execv()

execv(tmp[0], tmp);
于 2016-05-22T08:27:03.283 回答