为什么我在C工作中使用execvp有困难?

时间:2012-08-22 19:17:36

标签: c

我需要在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(为了打开gedit - 一个Ubuntu的ntpad),它不会打开它,或者如果写ls -a它没有显示任何输出作为Ubuntu的终端。

3 个答案:

答案 0 :(得分: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");
  }
}

答案 1 :(得分:1)

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

如果随机垃圾指向大字符串的非零数据,则空间不足以将假定的参数存储到新进程,通常为几百KB(对于某些系统,请参阅this page - 特定数字,以及获取系统最大参数大小的各种方法。)

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

因此,要查看这是否正在发生,请检查execvp的返回值。如果它甚至完全返回,则失败(如果成功,它将不会返回,因为新进程将执行!),因此检查errno的全局值以查看它失败的原因:

if (pID == 0)
{
    execvp(tmp[0], tmp);
    printf("exec failed: %s\n", strerror(errno));
    exit(1);
}

答案 2 :(得分:0)

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

execv(tmp[0], tmp);