отправить несколько строк через канал дочернему процессу - PullRequest
0 голосов
/ 02 марта 2020

Я хочу, чтобы дочерний процесс прослушивал все oop родительский процесс. Если он получает «выход» от родителя, он завершается, и если он получает «cmd», он снова будет считывать фактическую команду для выполнения с помощью system (). Пока у меня есть этот код, но второе чтение просто дает мне то же самое ("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);
        }

1 Ответ

0 голосов
/ 02 марта 2020

Это выглядит неправильно для меня:

write (user_pipe[u_id], cmd, sizeof(cmd));//cmd command
write (user_pipe[u_id], argument.c_str(), sizeof(argument.c_str()));

Как определяется cmd? Ваш код верен, только если он определен как массив символов фиксированного размера. Вторая строка выглядит явно неправильно: argument.c_str() возвращает char const *, поэтому sizeof(argument.c_str()) вернет sizeof(char const *) независимо от действительного значения argument. Вы можете попробовать что-то вроде этого:

char const *carg = argument.c_str();
write(user_pipe[u_id], carg, strlen(carg) + 1);

Таким образом, полная строка (включая завершающий NUL) должна быть передана ребенку.

Тогда в ребенке я думаю, что вы должны будь осторожнее. Вы делаете

read (0, &buf, 100);

, но затем потребляете только первую NUL завершенную строку из buf. Операция read может прочитать больше, чем это. Вы должны проверить возвращаемое значение. В частности, убедитесь, что read возвращает значение> 0. В противном случае ничего не может быть прочитано (возможно, произошла ошибка), а содержимое buf не изменилось.

...