[英]Creating a shell in C, execv() is unable to execute most commands
到目前为止,我知道在shell中可以使用的唯一命令是ls和echo。 当我尝试触摸或帮助之类的东西时,我什么也没有,也没有出现故障。
这是我执行命令的方法:
void mySystem(char * cmdargv[], char *searchpaths[], int numpaths, int numargs)
{
int pid=fork();
if(pid==0);
{
for(int i=0; i<numpaths; i++)
{
char * fullcmd = malloc(strlen(searchpaths[i] + strlen(cmdargv[0]) + 2));
sprintf(fullcmd, "%s/%s", searchpaths[i], cmdargv[0]);
//execv(fullcmd, cmdargv);
printf("%s",fullcmd);
free(fullcmd);
}
exit(0);
}
wait(NULL);
}
这是我的主要程序:
int main()
{
const char space[]="\n"; //"deliminator," specifies where to tokenize commands
int numpaths;
int numargs;
char *searchpaths[MAX_PATHS];
char *fullCMD[MAX_CMD];
InitializeArray(fullCMD, MAX_CMD);
InitializeArray(searchpaths, MAX_PATHS);
char cmd[MAX_CMD];
SaveSearchPaths(searchpaths, (int *) &numpaths); //fills the searchpaths array with
//the system PATH and returns the
//the size of the array, numpaths
while(1)
{
printf("> ");
fgets(cmd, MAX_CMD, stdin);
char *token;
token=strtok(cmd, space);
if(strncmp(cmd,"quit",4) == 0)
{
exit(0);
}
else if(strncmp(cmd, "path", 4)==0)
{
PrintAll(searchpaths, MAX_PATHS);
}
else
{
int i=0;
while(token!=NULL)
{
InsertStringAt(fullCMD,token,i);
token=strtok(NULL,space);
i++;
numargs+=1;
}
mySystem(fullCMD, searchpaths, numpaths, numargs);
}
InitializeArray()
函数将数组中的所有索引初始化为NULL
。 InsertStringAt()
将字符串插入数组中的某个索引中,并且SaveSearchPaths()
使用标记化的System PATH
填充searchpaths[]
数组。
当我在shell中输入ls时,会发生以下情况:
./a.out
> ls
a.out arrayOfStrings.c arrayOfStrings.h arrayOfStrings.h.gch arrayOfStrings.o arrayOfStringsTester.c arrayOfStringsTester.o myshell.c mySystem.c out SaveSearchPaths.c
当我提供帮助时会发生以下情况:
$ ./a.out
> help
$
什么都没发生。
当我触摸时会发生以下情况:
> touch file
*** Error in `./a.out': free(): invalid next size (fast): 0x00000000006a2130 ***
*** Error in `./a.out': free(): invalid next size (fast): 0x00000000006a2130 ***
Aborted (core dumped)
任何想法为什么只有ls似乎起作用?
你这里有错字
strlen(searchpaths[i] + strlen(cmdargv[0]) + 2)
/* ^ the ) goes here not ^ here
这是有效的,因为您要递增searchpaths[i]
指针并在结果指针上执行strlen()
,这可能会导致未定义的行为,但这是有效的代码,编译器应正确地对其进行编译。
正确的方法是
strlen(searchpaths[i]) + strlen(cmdargv[0]) + 2
另外,您应该检查malloc()
没有返回NULL
,这将指示错误。
如果存储strlen()
的结果,则可以防止这种情况,并处理更多错误。 适应它也是很好的恕我直言,因为有时您可能需要多次使用该值,并且由于strlen()
计算该值,在这种情况下将其存储起来更为有效,在这种情况下,唯一的好处就是清晰明了并改进处理错误和维护代码的能力。
尚未测试,希望能奏效。
void mySystem(char * cmdargv[], char *searchpaths[], int numpaths, int numargs)
{
int pid=fork();
if(pid==0) /* remove junk semicolon */
{
for(int i=0; i<numpaths; i++)
{
char * fullcmd = malloc(strlen(searchpaths[i]) + strlen(cmdargv[0]) + 2); /* improve this expression */
sprintf(fullcmd, "%s/%s", searchpaths[i], cmdargv[0]);
//execv(fullcmd, cmdargv);
printf("%s",fullcmd);
free(fullcmd);
}
exit(0);
}
wait(NULL);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.