Дочерний элемент некорректно завершается в fork

#c #exec #fork #strcpy

#c #exec #fork #strcpy

Вопрос:

Я пишу программу на c для класса, который представляет собой небольшую оболочку. Пользователь вводит команду, и код выполняет ее с помощью exec() функции.

Мне нужно иметь fork в процессе, чтобы вся работа выполнялась в дочернем процессе. Единственная проблема заключается в том, что дочерний элемент не завершается должным образом и не выполняет команду. Когда я запускаю код без fork, он выполняет команды идеально.

Проблема, похоже, возникает из-за того, что я создаю строку, которая будет использоваться в execv вызове. Это строка кода, в которой я вызываю strcpy . Если я прокомментирую это, все будет работать нормально. Я также попытался изменить его на strncat с той же проблемой. Я понятия не имею, что является причиной этого, и приветствую любую помощь.

 #include <sys/wait.h>
#include <vector>
#include <sstream>
#include <cstdlib>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

string *tokenize(string line);
void setCommand(string *ary);

string command;
static int argument_length;

int main() {
    string argument;
    cout << "Please enter a unix command:n";
    getline(cin, argument);
    string *ary = tokenize(argument);

    //begin fork process
    pid_t pID = fork();
    if (pID == 0) { // child
        setCommand(ary);

        char *full_command[argument_length];
        for (int i = 0; i <= argument_length; i  ) {
            if (i == 0) {
                full_command[i] = (char *) command.c_str();
                //  cout<<"full_command " <<i << " = "<<full_command[i]<<endl;
            } else if (i == argument_length) {
                full_command[i] = (char *) 0;
            } else {
                full_command[i] = (char *) ary[i].c_str();
            //  cout<<"full_command " <<i << " = "<<full_command[i]<<endl;
            }
        }    

        char* arg1;
        const char *tmpStr=command.c_str();        
        strcpy(arg1, tmpStr);
        execv((const char*) arg1, full_command);
        cout<<"I'm the child"<<endl;
    } else if (pID < 0) { //error
        cout<<"Could not fork"<<endl;
    } else { //Parent
        int childExitStatus;
        pid_t wpID = waitpid(pID, amp;childExitStatus, WCONTINUED);
        cout<<"wPID = "<< wpID<<endl;
        if(WIFEXITED(childExitStatus))
            cout<<"Completed "<<ary[0]<<endl;
        else
            cout<<"Could not terminate child properly."<<WEXITSTATUS(childExitStatus)<<endl;
    }

    // cout<<"Command = "<<command<<endl;
    return 0;
}

string *tokenize(string line) //splits lines of text into seperate words
{
    int counter = 0;
    string tmp = "";
    istringstream first_ss(line, istringstream::in);
    istringstream second_ss(line, istringstream::in);

    while (first_ss >> tmp) {
        counter  ;
    }

    argument_length = counter;
    string *ary = new string[counter];
    int i = 0;
    while (second_ss >> tmp) {
        ary[i] = tmp;
        i  ;
    }

    return ary;
}

void setCommand(string *ary) {
    command = "/bin/"   ary[0];

// codeblock paste stops here
  

Комментарии:

1. Я очистил ваш код и все еще не могу понять, что вы пытаетесь сделать. Я предполагаю, что вы тоже многого не понимаете. Обратитесь за помощью к вашему инструктору.

Ответ №1:

Вы сказали:

Это строка кода, в которой я вызываю strcpy.

Вы не выделили никакой памяти для хранения вашей строки. Первым параметром strcpy является указатель назначения, и вы используете неинициализированное значение для этого указателя. Со страницы руководства strcpy:

char *strcpy(char * s1, const char * s2);

Функции stpcpy() и strcpy() копируют строку s2 в s1 (включая завершающий символ `’).

Могут быть и другие проблемы, но это первое, на что я обратил внимание.

Комментарии:

1. Сейчас я действительно ненавижу себя за то, насколько простым было это исправление, но, похоже, именно в этом и заключалась проблема. Я изменил определение arg1 на char arg1 [команда. length()] и сейчас это работает идеально. Огромное спасибо!