所以我必须实现对执行外部命令的支持(对于Linux编程语言)。 这是我到目前为止,我使用readline库的历史功能,但这是无关紧要的......有人可以告诉我,我做错了什么? (我认为这就是我打电话的方式" execvp") 所以这是我的代码:
#include<fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <readline/readline.h>
#include <readline/history.h>
#define BUFFER_SIZE 256
#define READFILE_SIZE 4096
char ** parseCMD( char * );
void EXEC(char *, char *);
int main(int argc, char ** argv)
{
char myPrompt[]= {'>', '_', '\0'};
char *currLine = (char* ) malloc(sizeof(char) * BUFFER_SIZE),
*command = (char* ) malloc(sizeof(char) * BUFFER_SIZE),
*argument = (char* ) malloc(sizeof(char) * BUFFER_SIZE);
currLine = readline(myPrompt);
while((strcmp(currLine, "exit") != 0))
{
command = strtok(currLine, " ");
argument = strtok( NULL, "");
EXEC(command, argument);
currLine = readline(myPrompt);
}
return 0;
}
char ** parseCMD( char * buff )
{
int i = 0, n = strlen(buff), j, count = 0;
char ** CMDargs = (char **) malloc( sizeof( char ) * 100 * 100);
if( buff == NULL )
return NULL;
for(i; i < n; i ++)
{
j = 0;
char * aux = (char *) malloc( sizeof( char ) * 100);
while( buff[i] != ' ' || buff[i] != '\t' || buff[i] != '\n')
aux[j++] = buff[i++];
aux[j] = '\0';
CMDargs[count] = strdup( aux );
count++;
//printf("Argument %d is: %s", count - 1, CMDargs[count - 1]);
free(aux);
}
CMDargs[ count ] = NULL;
return CMDargs;
}
void EXEC(char *command, char *argBuffer)
{
pid_t pid;
int status, fd[2], n;
char s[255];
char ** Args;
pipe( fd );
Args = parseCMD( argBuffer );
if ((pid = fork()) < 0)
{
printf("ERROR: forking child process failed\n");
exit(1);
}
else if (pid == 0)
{
close(fd[0]);
dup2(fd[1],1);
if (execvp(command, Args) < 0)
{
printf("ERROR: execvp call failed\n");
exit(1);
}
close(fd[1]);
}
else
{
close(fd[1]);
while( ( n = read( fd[0], s, 255 ) ) > 0 )
{
s[n] = '\0';
printf("%s",s);
}
while (wait(&status) != pid);
close(fd[0]);
}
}
答案 0 :(得分:1)
这里有太多的错误,问问自己,当我输入空命令时会发生什么(变量命令为NULL,稍后你会得到段错误),如果我输入没有参数的命令会有什么问题(变量参数是NULL,稍后您将获得段错误),如果我输入带参数的命令会发生什么? (虽然函数parseCMD中的循环永远不会终止,最终你将访问不应该访问的东西)。也许你有时间学习使用调试器。尝试逐行执行程序并观察发生的情况。