Проблемы с созданием программы C с использованием функций fork() и execvp()

Вот следующий код, с которым у меня сейчас проблемы:

#include <stdio.h>
#include <unistd.h>
#include<sys/types.h>
#include<sys/wait.h>

#define MAX_LINE 80

int main(void)
{
    char *args[MAX_LINE/2+1];
    int background= 0;//integer that acts a boolean for if & appears
    int should_run = 1;
    int status;

        while(should_run)//Just to keep the interface going until the user chooses to stop
        {
            printf("osh>");//prompt
            fflush(stdout);

            int i = 0;
            while(getchar() != '\n')//Use scanf until a new line is found
            {
                scanf("%s", &args[i]);

                if(strcmp(&args[i], "exit") == 0)//temporary exit protocal
                {
                    printf("Exiting now...");
                    return 0;
                }


                if(strcmp(&args[i], "&") == 0)//If we find a & in our input then we changed background to 1 or true
                    background = 1;
                printf("Args[%i] = %s\n", i, &args[i]);//Tester
                i++;
            }


            printf("Background = %i\n",background);//Test
            pid_t pid= fork();// Create new child process
            printf("process %i created\n", pid);//Test



            if(pid < 0)//fork() failed
            {
                printf("Fork Failed.\n");
                return 1;
            }

            else if(pid == 0)//Child process id
            {
                printf("Child process started %s command\n", &args[0]);
                if(execvp(args[0], args) < 0)//change the current child process to execute the input given by the user 
                                //with args[0] being the command and args being the parameters(ls -l is an example).
                {
                    printf("Command failed\n");
                }
                return 0;
            }

            else//Parent Process
            {
                if(background == 1)//If the user typed in a & then the parent will wait for a change in state from the child, if there is no &
                            //then we will just finish the parent process
                {
                    printf("Parent process waiting on child\n");
                    wait(NULL);
                }
            }

        }

    return 0;

У меня есть одна большая проблема и одна небольшая проблема прямо сейчас. Основная проблема заключается в том, что перед запуском execvp у меня есть метод printf, который говорит «Дочерний процесс запущен», и я получаю эту строку для печати, но больше ничего не происходит. Прерывания не выдаются, программа просто зависает на моей команде execvp.

Моя незначительная проблема заключается в том, что когда моя программа запускает подсказку «osh>», прежде чем запрашивать ввод. Теперь, если я, например, наберу «osh>ls -l», я получу args[0] = s, args1 = -l. Теперь, если я поставлю «osh> ls -l» именно в этом формате, я получу args[0] = ls, args1 = -l. Является ли это частью функции scanf(), которую я не использую здесь должным образом, чтобы убедиться, что я получаю символы после «osh>» и между пробелами в виде строк?

РЕДАКТИРОВАТЬ: вот мой вывод для пользовательского ввода "ls -l" Вывод для prog.c


person spstephens    schedule 03.03.2016    source источник
comment
Вы никогда не выделяете память для указателей в args. Любое их использование имеет неопределенное поведение.   -  person molbdnilo    schedule 03.03.2016
comment
Кроме того, если вы не сделаете ничего, чтобы убедиться, что указатель после последнего аргумента равен NULL. execvp() ожидает, что конец списка аргументов будет помечен таким образом.   -  person John Bollinger    schedule 04.03.2016


Ответы (1)


Проблема, с которой вы столкнулись с отсутствующим символом, заключается в том, что getchar() потребляет первый символ вашего ввода до того, как scanf нанесет удар по нему. Вы, вероятно, хотите сделать что-то вроде:

while (scanf("%s", &buffer) > 0)
{
    strcpy(args[i], buffer);
    /* then do stuff with args[i] */
}
person Haldean Brown    schedule 03.03.2016
comment
Во всяком случае, это было бы началом. Также нужно позаботиться о том, чтобы избежать переполнения буфера, и, поскольку есть дополнительная проблема с отсутствием места, выделенного для аргументов, возможно, strdup() будет полезной альтернативой strcpy() в этом случае. - person John Bollinger; 04.03.2016
comment
Для уверенности. Вы также должны проверять границы i, чтобы убедиться, что вы не переполняете сам массив. - person Haldean Brown; 04.03.2016