Envoi et réception d’un tableau de caractères à l’aide de la tuyauterie via argv en C

Donc, j’essaie de créer un tuyau qui envoie des tableaux de caractères dans des tuyaux qui se connectent via argv []. Pour l’instant, je suis bloqué à la réception du tableau (paramètre qui est envoyé à c_param du parent à l’enfant.) Dans interface.c pour recevoir les caractères 3 et 5 à la firebase database db.c. Je sais que 3 et 5 sont l’index pour argv [] sur lequel mes pipes sont, mais je ne sais pas comment le prendre et imprimer mon message dans db.c.

interface.c crée les canaux, les fourchettes dans un processus parent et un processus enfant. Le paramètre char array est transféré vers le processus enfant vers char array c_param. À l’aide de snprintf, j’ai transformé mon canal en un caractère à envoyer à l’aide de execl avec mon tableau de caractères c_param.

interface.c:

int main (int argc, char *argv[]) { int to_Child[2]; int to_Parent[2]; int id, toChildPipe, toParentPipe, err; char param[100] = "This is the parameter!"; char sendPipe[100]; char recPipe[100]; /*CREATING PIPE*/ toChildPipe = pipe(to_Child); toParentPipe = pipe(to_Parent); if(toChildPipe == -1 || toParentPipe == -1) { printf ("Error on pipe creation: %d", errno); exit (1); } /*Creating Child Process*/ id = fork(); if(id == 0) { /** * * IN THE CHILD Process * */ close(to_Child[1]); //reading close(to_Parent[0]); //writing char c_param[100]; toChildPipe = read(to_Child[0], c_param, 100); if (toChildPipe == -1) { //If failed printf("Error on read from pipe from parent: %d\n",errno); //exit with error exit(2); }//Error pipe from parent snprintf(sendPipe,sizeof(sendPipe), "%d",to_Parent[0]); snprintf(recPipe,sizeof(recPipe), "%d",to_Child[0]); err = execl("./db","db",sendPipe,recPipe,(char *)0); if(err == -1) { printf("Error on execl: %d\n", errno); }//Error execl toChildPipe = read(to_Child[0], c_param, 100); if (toChildPipe == -1) { //If failed printf("Error on read from pipe from parent: %d\n",errno); //exit with error exit(2); }//Error pipe from parent }//CHILD PROCESS else if (id > 0) { /** * *IN THE PARENT PROCESS * */ close(to_Child[0]); //writing close(to_Parent[1]); //reading toChildPipe = write(to_Child[1],param,100); if(toChildPipe == -1) { printf("Error on write to pipe: %d", errno); exit(3); } /*Piping was successful!*/ exit(0); }//PARENT PROCESS else { exit(4); } } 

db.c a démarré à partir d’interface.c execl et devrait recevoir les parameters via argv [], qui devrait ensuite l’afficher. db.c

 #include  #include  #include  #include  #include  #include  int main(int argc, char *argv[]) { FILE *finput; int j = 0; int fd; int toChildPipe; char c_param[100]; if(argc > 1) { for(j ; j < argc ; j++) printf("argv = %s\n", argv[j]); printf("argc = %d\n",argc); } fd = atoi(argv[1]); printf("Statement: %s\n", argv[fd]); strcpy(c_param, argv[3]); printf("filename: %s\n", c_param); } 

Ceci est la sortie actuelle que je reçois. Je suis conscient que les index 5 et 3 sont les index dont j’ai besoin pour envoyer un message et recevoir le message que je suis en train d’imprimer dans db.c

sortie (db.c):

 argv = db argv = 5 argv = 3 argc = 3 Statement: TERM=xterm 

J’espère vous avoir donné suffisamment d’informations. J’apprécie toute l’aide que vous êtes disposé à me donner. Merci d’avance!

Il y avait beaucoup de petites choses qui ne vont pas. Vos plus gros problèmes étaient vos hypothèses / assertions dans db.c propos des parameters qui lui ont été transmis par interface.c – il y avait une discordance totale entre ce qui était passé et ce qui était attendu. Il y avait aussi beaucoup de code étranger dans interface.c . En particulier, l’enfant lisait dans le tube avant d’exécuter db , il ne restait donc plus rien sur le tube pour que db puisse le lire.

Voici le code “fixe”, avec encore du code de débogage.

interface.c

 #include  #include  #include  #include  #include  int main(void) { int to_Child[2]; int to_Parent[2]; int id; char param[100] = "This is the parameter!"; char sendPipe[100]; char recPipe[100]; if (pipe(to_Child) == -1 || pipe(to_Parent) == -1) { printf("Error on pipe creation: %d", errno); exit(1); } printf("Pipes: C(%d,%d), P(%d,%d)\n", to_Child[0], to_Child[1], to_Parent[0], to_Parent[1]); id = fork(); if (id == 0) { close(to_Child[1]); // Child does not write to itself close(to_Parent[0]); // Child does not read what it writes snprintf(sendPipe, sizeof(sendPipe), "%d", to_Parent[1]); snprintf(recPipe, sizeof(recPipe), "%d", to_Child[0]); execl("./db", "db", sendPipe, recPipe, (char *)0); fprintf(stderr, "Error on execl: %d\n", errno); exit(2); } else if (id > 0) { close(to_Child[0]); // Parent does not read childs input close(to_Parent[1]); // Parent does not int nbytes = write(to_Child[1], param, 100); if (nbytes == -1) { fprintf(stderr, "Error on write to pipe: %d\n", errno); exit(3); } close(to_Child[1]); if ((nbytes = read(to_Parent[0], param, 100)) <= 0) { fprintf(stderr, "Error on read from pipe: %d\n", errno); exit(5); } printf("Data from pipe: [%.*s]\n", nbytes, param); exit(0); } else { perror("fork failed"); exit(4); } } 

### db.c

 #include  #include  #include  #include  #include  #include  int main(int argc, char *argv[]) { printf("argc = %d\n", argc); for (int j = 0; j < argc; j++) printf("argv[%d] = %s\n", j, argv[j]); if (argc != 3) { fprintf(stderr, "Usage: %s write-fd read-fd\n", argv[0]); return 1; } int ofd = atoi(argv[1]); int ifd = atoi(argv[2]); printf("ifd = %d; ofd = %d\n", ifd, ofd); char c_param[100]; int nbytes = read(ifd, c_param, sizeof(c_param)); if (nbytes <= 0) { fprintf(stderr, "Error: failed to read any data (%d)\n", errno); return 1; } printf("Child: [%.*s]\n", nbytes, c_param); assert(strlen(c_param) + sizeof(" - sent back to parent") <= sizeof(c_param)); strcat(c_param, " - sent back to parent"); if (write(ofd, c_param, nbytes) != nbytes) { fprintf(stderr, "Error: failed to write all the data (%d)\n", errno); return 1; } return 0; } 

Échantillon échantillon

 Pipes: C(3,4), P(5,6) argc = 3 argv[0] = db argv[1] = 6 argv[2] = 3 ifd = 3; ofd = 6 Child: [This is the parameter!] Data from pipe: [This is the parameter! - sent back to parent] 

Notez que le code rapporte les erreurs en erreur standard (c'est pour cela qu'il est). Il délimite également les données imprimées, ce qui facilite la détection des problèmes imprévus. Cela ne suppose pas que les données sont remplies de null; il limite la longueur imprimée à la longueur lue, bien que les données comportent en réalité de nombreuses valeurs nuls à la fin.