Problem z pipe i execl

Problem z pipe i execl
eNes
  • Rejestracja:ponad 5 lat
  • Ostatnio:ponad 3 lata
  • Postów:1
0

Na początku powiem, że moje doświadczenie w c to zrobienie kilku pętli 3 lata temu więc proszę o rady jak dla idioty, także nie planuje w tym języku zostawić dłużej niż potrzebuje na zajęcia.
Mam do napisania program tworzący dwa procesy gdzie pierwszy odczytuje tekst z klawiatury i wysyła go łączem do drugiego i oczekuje na potwierdzenie również przez łącze i kończy działanie po wysłaniu pustego tekstu. Drugi proces powinien czekać na komunikat i potwierdzać odbiór. Mam wykorzystać funkcje exec() i przekierowania przekierowywanie standardowych deskryptorów (drugi proces powinien
odczytywać deskryptor 0 i zapisywać na deskryptorze 1).

Jednak efekt jaki osiągnąłem jest taki, że raz duplikuje moją wpisaną wiadomość a raz odpisuje że odebrało

(zielone to wpisane przeze mnie)
screenshot-20211112222938.png

Kod rodzica

Kopiuj
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main()
{
    int pipefd[2];
    pid_t cpid;
    char buf[1024];
    char message[1024];

    if (pipe(pipefd) == -1) {
        printf("Error in pipe");
    }
    cpid = fork();
    if (cpid == -1) {
        printf("Error in fork");
    }
    if (cpid == 0) {    /* Child reads from pipe */
        close(pipefd[0]);
        close(pipefd[1]);
        execl("./child_pipe", "child_pipe", NULL);
        printf("Error in execl\n");

    } else {
        while (1) {
            fgets (message, 1023, stdin);
            if ((message[0] == '\n') || ( message[0] == '\r' && message[1] == '\n') || (message[0] == '\n')|| (message[0] == ' ')|| (message[0] == 0))
                    break;
            if (atoi(&message[0]) == 10) {
                    break;
            }
            if(write(pipefd[1], &message, 1023)==-1)
                printf("Error in close write\n");
            if(read(pipefd[0], &buf, 1023) == -1)
                printf("Error in read\n");
            printf("%s",buf);
        }
        exit(0);
    }
}

kod dziecka

Kopiuj
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

char message[1024];
char response[1024] = "Received\n";
int pipefd[2];

int main ()
{
    int i;
    while(1) {
        if((i = read(pipefd[1], &message, 1023)>0) && i!=-1){

            if (write(pipefd[0], &response, 1023)==-1)
                printf("Error in close write\n");
        }
        if(i==-1){
                printf("Error in read\n");
        }
    }


}

enedil
  • Rejestracja:prawie 12 lat
  • Ostatnio:około 12 godzin
  • Postów:1027
3
Kopiuj
int pipefd[2];

int main ()
{
    int i;
    while(1) {
        if((i = read(pipefd[1], &message, 1023)>0) && i!=-1){

no to powiedz, jaką ma wartość pipefd[1] jak robisz tego reada? A jaką wartość ma i po tym odczycie?

Podpowiedź - tamto co napisałeś, po dodaniu nawiasów, i jawnych castów, działa tak:

Kopiuj
        if((i = (int)(bool)(read(pipefd[1], &message, 1023)>0)) && i!=-1){
edytowany 2x, ostatnio: enedil
BG
  • Rejestracja:prawie 6 lat
  • Ostatnio:około 12 godzin
  • Postów:289
1

To co @enedil napisał, ale oprócz tego

  1. Skoro zamknąłeś w "dziecku" oba końce pipe, to jak child miałby z niego skorzystać ?
  2. Pipe to kanał jednokierunkowy. Twój proces główny sam ze sobą "gada". Jeśli chcesz mieć komunikację dwukierunkową, to użyj dwóch zestawów pipe
  3. Poczytaj manual do dup2, bo najprawdopodobniej to chciałeś zrobić
  4. Twój proces potomny wypisuje "Received" przypadkiem (zastanów się dlaczego ;) )
obscurity
hehe "manual do dup"

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.