我需要在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的终端。
答案 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);