Re[2]: Нужна консультация fork, pipe, execvp
От: Saddam Россия http://saddam.narod.ru
Дата: 14.03.17 10:37
Оценка:
Здравствуйте, Masterspline, Вы писали:

M>Кстати, вот это тебе может быть полезно:


M>Курс на степике про сетевое программирование в Linux

Огромное спасибо за подсказки!
Работающий результат:
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <vector>
#include <string.h>
#include <sys/wait.h>

using namespace std;

void parse(char *s, char delim, std::vector<char *> &CmdList)
{
    unsigned int l=strlen(s);
    unsigned int i=0;
    CmdList.push_back(s);
    for (i=0;i<l;i++)
    {
        if (s[i]==delim)
        {
            s[i]=0;
            i++;
            while (s[i]==' ') {s[i]=0;i++;}
            if (strlen(&s[i])) CmdList.push_back(&s[i]);
            while (s[strlen(&s[i])-1]==' ') s[strlen(&s[i])-1]=0;
        }
    }
}
int main() {
    std::filebuf fb;
    fb.open ("./Pipe.log",std::ios::out);
    std::ostream os(&fb);
    std::vector<char *> CmdList;
    char cmdLine[1024];
    int iChildPID=0, subCount=0;
    //cin>>cmdLine;
    strcpy(cmdLine,"who | sort | uniq -c | sort -nk1");
    parse(cmdLine,'|',CmdList);
    int fd = 0;
    int OutPipe[2]={0,0},inFD=STDIN_FILENO;
    while (!CmdList.empty())
    {
        std::vector<char *> ParamList;
        parse(CmdList.front(),' ',ParamList);
        ParamList.push_back(NULL);
        if ( pipe(OutPipe) < 0 )
        {
            cerr << "Pipe error" << strerror(errno) << endl;
            return errno;
        }
        if (!(iChildPID=fork()))
        {
             close(OutPipe[0]);
             if (dup2(inFD, STDIN_FILENO) == -1) /*read from in_fd */
             {
                 cerr << "child STDIN dup2 error" << strerror(errno) << endl;
                 return errno;
             }
             if (dup2(OutPipe[1], STDOUT_FILENO) == -1)   /*write to fd[1]*/
             {
                 cerr << "child STDOUT dup2 error" << strerror(errno) << endl;
                 return errno;
             }
             else if (close(OutPipe[1]) == -1)
                {
                     cerr << "child CloseFD error" << strerror(errno) << endl;
                     return errno;
                }
            if (CmdList.size()==1)
            {
                fd = open("/home/saddam/result.out",   O_CREAT | O_RDWR );
                dup2(fd,1);
            }
            if (-1==execvp(CmdList.front(),ParamList.data()))
            {
                cerr << "error in execvp: " << strerror(errno) << endl;
                return errno;
            }
        }
        close(OutPipe[1]);   /* parent executes the rest of commands */
        close(inFD);
        inFD=OutPipe[0];
        subCount++;
        cout <<" PID:"<<iChildPID<<" Count:"<<subCount<< endl;
        CmdList.erase(CmdList.begin());
    }
    int status=0;
    int pid ;
    for (int i=0;i<subCount;i++)
    {
        cout <<"Waiting for "<<subCount-i<< endl;
        pid=wait(&status);
        cout <<"PID: "<<pid<<" terminated \n";
    }
    close(fd);
    cout <<"Master is finished!"<< endl; // prints !!!Hello World!!!
    fb.close();
    return 0;
}
- Вы знаете — жаль, просто по-человечески жаль Памелу Андерсон, которая никогда не сможет сыграть на баяне...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.