I want the child process to listen in a loop the parent process. If it receives "exit" from the parent it terminates and if it receives "cmd" will read again for the actual command to execute using system(). So far I have this code, but the second reading just gives me the same ("cmd")
child:
pid = fork();
if(pid == 0){
close(fd_pipe[1]); // Close writing end
dup2(fd_pipe[0],0); close(fd_pipe[0]);
//close(fd_pipe[0]);
//create file descriptor for user file
int userFile_fd =
open(users_table.at(get_user(u_id)).get_filename().c_str(), O_APPEND|O_WRONLY);
//redirect output to user file
dup2(userFile_fd,1);
close(userFile_fd);
//listen in a loop till receive "exit"
while(true){
char buf[100];
read (0, &buf, 100);
cout << buf << endl;
//logout
if(strstr(buf, bye) != NULL){
cout << "Exiting..." << endl;
kill(getpid(), SIGKILL);
break;
}
//command
else if(strcmp(buf, cmd) == 0){
read (0, &buf, 100);
cout << "reading buf again: "<<buf << endl;
system(buf);
}
}//end while
}//end if (child process)
parent:
while(status == true){
//get input
cout << ("ucmd>");
getline (cin, command);
//some preprocessing code and then...
//this works fine
else if(command.compare(logout)==0)
{
cout << " UM: Loggin out USER-"<<u_id<<" associated pipe ID: "<<user_pipe[u_id]<<endl;
char exit2[] = "exit";
write (user_pipe[u_id], exit2, sizeof(exit2));//sends exit message
}
//cmd
else if(command.compare(cmd)==0)
{
write (user_pipe[u_id], cmd, sizeof(cmd));//cmd command
write (user_pipe[u_id], argument.c_str(), sizeof(argument.c_str()));//cmd command
//call_cmd(u_id, argument);
}
This looks wrong to me:
write (user_pipe[u_id], cmd, sizeof(cmd));//cmd command
write (user_pipe[u_id], argument.c_str(), sizeof(argument.c_str()));
How is cmd
defined? Your code is only correct if it is defined as a fixed size array of characters. The second line looks definitely wrong: argument.c_str()
returns a char const *
, so sizeof(argument.c_str())
will return sizeof(char const *)
independent of the actual value of argument
. You can try something like this:
char const *carg = argument.c_str();
write(user_pipe[u_id], carg, strlen(carg) + 1);
That way the full string (including terminating NUL
) should be transferred to the child.
Then in the child I think you have to be more careful as well. You do
read (0, &buf, 100);
But then consume only the first NUL
terminated string from buf
. The read
operation may have read more than that. You should check the return value. In particular, make sure that read
returns a value > 0. Otherwise nothing may have been read (there may have been an error) and the contents of buf
are unchanged.