#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()] и сейчас это работает идеально. Огромное спасибо!