我试图在手动执行程序后执行调用execv。
就我而言, c是一个结构,它将args作为一个字符串数组,在接收输入时传递参数。 nargs是参数的数量。 c-> args [0]将包含“ls”,“cat”等。
我尝试在我的子进程中打印args [0],fullPath等的值。它们都显示像“/ bin / ls”,“/ bin / cat”等值。但是当我调用execv时,它返回-1并且errno为2,我理解为“没有这样的文件或目录”的错误。但我确定该文件存在,因为这是我检查所有权限后我的PathResolver返回的内容。 任何人都可以指出我可能犯错的地方。
//儿童内部发生的部分
char *fullPath = PathResolver(c->args[0],1,&permission);
printf("FullPath: %s -- Permission: %d\n",fullPath,permission);
if(permission==0)
{
fprintf(stderr, "%s: Command not found\n",c->args[0]);
}
else if(permission==-1)
{
fprintf(stderr, "%s: Permission denied\n",c->args[0]);
}
else
{
char* args[c->nargs+1];
int m=0;
for(m=0;m<c->nargs;m++)
{
strcpy(args[m],c->args[m]);
}
args[c->nargs] = NULL;
printf("%d\n",execv(args[0], args));
printf("errno: %d\n",errno);
}
PathResolver功能
char* PathResolver(char *command, int ResolverMode, int *Permission)
{
*Permission = 0;
char *returnString;
returnString = malloc((sizeof(char)));
char *strPath = getenv("PATH");
char *del = ":";
char *strToken = strtok(strPath,del);
FILE *f;
while(strToken)
{
char filePath[100];
sprintf(filePath,"%s/%s",strToken,command);
if(access(filePath,F_OK)>=0)
{
if(access(filePath,X_OK)>=0)
{
*Permission = 1;
sprintf(returnString,"%s%s ",returnString,filePath);
if(ResolverMode == 1)
break;
}
else
{
*Permission = -1;
}
}
strToken = strtok(NULL,del);
}
sprintf(returnString,"%s\b",returnString);
return returnString;
}
答案 0 :(得分:1)
strcpy(args[m],c->args[m]);
是未定义的行为,因为args[m]
不是指向有效内存的指针。
以下可能更简单:
char * args[c->nargs + 1];
for (size_t m = 0; m != c->nargs; ++m)
{
args[m] = c->args[m];
}
args[c->nargs] = NULL;
无需复制字符串。
(这可能不是您的实际问题,但它肯定会阻止您的程序正确。)
答案 1 :(得分:0)
execv()
期望程序名称以完整路径为前缀作为第一个参数。
要搜索PATH
而不是提供路径,请使用execvp()
。
<强>更新强>:
也是这一行
returnString = malloc((sizeof(char)));
只会将1
字节分配给returnString
,这对于您使用returnString
的方式很少。