execvp() - неподдерживаемая опция SysV
Я пытаюсь написать простую оболочку на C, которая принимает команду и использует дочерний процесс для выполнения этой команды. Например, если я введу:
ps -ael
мой дочерний процесс должен выполнить эту команду вместе с ее аргументами. Я распечатываю свои команды, поскольку они хранятся в массиве. Вот что я вижу:
Array[0] = ps
Array[1] = -ael
Array[2] = NULL
Когда я выполняю, я получаю это:
error: unsupported SysV option
Usage:
ps [options]
Try 'ps --help <simple|list|output|threads|misc|all>'
or 'ps --help <s|l|o|t|m|a>'
for additional help text.
For more details see ps(1).
Мой код ниже.
int main(void)
{
char *args[MAX_LINE/2 +1]; // command line arguments
char *cmdLine;
int should_run = 1; // flag to determine when to exit the program
int i, x;
printf("osh> ");
fflush(stdout);
fgets(cmdLine, MAX_LINE, stdin);
char *token = strtok(cmdLine, " ");
int position = 0;
while (token != NULL)
{
args[position++] = token;
token = strtok(NULL, " ");
}
i = 0;
while (args[i] != NULL)
{
printf("Array[%d] = %s\n", i, args[i]);
i++;
}
if (args[i] == NULL) printf("Array[%d] = NULL", i);
x = 0;
pid_t pid;
/* fork a child process*/
pid = fork();
if (pid < 0)
{
/*Error occured*/
fprintf(stderr, "Fork failed.");
return 1;
}
else if (pid == 0)
{
/*child process*/
execvp(args[0], args); //error here
}
else
{
/*Parent process*/
wait(NULL);
printf("\nChild complete\n");
}
}
1 ответ
Строка, возвращаемая fgets()
включает символ новой строки, но вы не удаляете его из строки. Итак, вы устанавливаете args[1]
в "-ael\n"
, а также \n
не является допустимым вариантом.
Включить новую строку в свой strtok()
разделители:
char *token = strtok(cmdLine, " \n");
int position = 0;
while (token != NULL)
{
args[position++] = token;
token = strtok(NULL, " \n");
}
и тогда он не будет включен в токены.
Вы должны были увидеть это в своем выводе, я готов поспорить, что он напечатан:
Array[0] = ps
Array[1] = -ael
Array[2] = NULL
с пустой строкой там.
Кстати, я не вижу, где вы когда-либо устанавливали последний аргумент NULL
, while
цикл останавливается, когда strtok()
возвращается NULL
поэтому он никогда не присваивает этот результат args[position++]
, Вам нужно добавить:
args[position] = NULL;
после петли.
И нет необходимости if (args[i] == NULL)
- цикл до этого останавливается при выполнении этого условия, поэтому он гарантированно будет истинным.