C Linux Programmierung, Problem mit unnamed Pipes

Somtaaw

Lieutenant
Registriert
Jan. 2008
Beiträge
658
So, ich komme einfach nicht auf das problem... hab da ein bischen Quellcode für euch...
Kurze Erklärung:

Ich versuche von einem Prozess via unnamed Pipe es in den zweiten zu schicken, und schließe dann die pipe wieder... (das klappt noch ganz gut)... Und dann möchte ich vom Child-Prozess etwas zurück an den elternprozess schicken.. was dann aber nur noch zu dem tollen fehler "fdopen: Bad file descriptor" führt... Hab das ganze mal versucht indem ich 2 unterschiedliche Pipes erstelle damit beide generell nur eine richtung haben, da bekomme ich aber einen speichererror.. mit nur einer pipe die umgedreht werden sollte, eben den oben genannten error... Vielleicht könnt ihr mir helfen..

header.h:
Code:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>
#include <limits.h>

void signalhandler(int sig);
void child(char *output);
void parent(char *input);

FILE *newfile, *finput, *foutput, *reading, *writing;
int fd[2], rfd[2];
pid_t pid;
main.c:
Code:
#include "header2.h"

int main(int argc, char *argv[])
{
	int c;
	char *input,*output;
	
	(void) signal(SIGHUP, signalhandler);
	(void) signal(SIGINT, signalhandler);
	(void) signal(SIGQUIT, signalhandler);
	
	if(argc!=5)
	{
		printf("Falsche Anzahl der Argumente\n");
		return EXIT_FAILURE;
	}
	else
	{
		while((c=getopt(argc,argv,"i:o:")) != EOF)
		{
			switch(c)
			{
				case 'i':
					input = optarg;
					break;
				case 'o':
					output = optarg;
					break;
				default:
					return EXIT_FAILURE;
					break;
			}
		}
	}
	
	if (pipe (fd) < 0) 
	{
		printf("Fehler beim erstellen der Pipe!");
		return EXIT_FAILURE;
	}
/*	if (pipe (rfd) < 0) 
	{
		printf("Fehler beim erstellen der Pipe!");
		return EXIT_FAILURE;
	}*/
	
	pid = fork();
	switch(pid)
	{
		case 1:
			return EXIT_FAILURE;
			break;
		case 0:
			child(output);
			break;
		default:
			parent(input);	
			break;
	}
	close(fd[0]);
	close(fd[1]);
	return EXIT_SUCCESS;
}
function.c:
Code:
#include "header2.h"

void signalhandler(int sig)
{
	fclose(finput);
	fclose(foutput);
	fclose(reading);
	fclose(writing);
	fclose(newfile);
	close(fd[0]);
	close(fd[1]);
	return EXIT_SUCCESS;
}

void parent(char *input)
{
	char puffer[256];
	
	finput = fopen(input, "r");
	printf("Parent running\n");
	
	close (fd[0]);   
	
	if ((writing = fdopen (fd[1], "w")) == NULL) 
	{
		perror ("fdopen");
		return EXIT_FAILURE;
	}
	
	while(fgets(puffer,256,finput) != NULL)
	{
		fputs(puffer,writing);
		fflush(writing);
	}
	fclose(finput);
	fclose(writing);
	
	close(fd[1]);
	
	if ((reading = fdopen (fd[0], "r")) == NULL) 
	{
		perror ("fdopen");
		return EXIT_FAILURE;
	}
	
	printf("Child running\n");
	while(fgets(puffer,256,reading) != NULL)
	{
		fputs(puffer,finput);
	}
	fclose(finput);
	fclose(reading);
	
	
	if (waitpid(pid, NULL, 0) < 0)
	{
		fprintf(stderr, "Fehler bei waitpid()");
	}
}

void child(char *output)
{
	char puffer[256];
	
	foutput = fopen(output, "r");
	newfile = fopen("temp","w+");
	
	while(fgets(puffer,256,foutput) != NULL)
	{
		fputs(puffer,newfile);
	}
	fclose(foutput);
	
	foutput = fopen(output,"w+");
	
	close(fd[1]);
	
	if ((reading = fdopen (fd[0], "r")) == NULL) 
	{
		perror ("fdopen");
		return EXIT_FAILURE;
	}
	
	printf("Child running\n");
	while(fgets(puffer,256,reading) != NULL)
	{
		fputs(puffer,foutput);
	}
	fclose(reading);
	fclose(foutput);
	
	close (fd[0]);   
	
	if ((writing = fdopen (fd[1], "w")) == NULL) 
	{
		perror ("fdopen");
		return EXIT_FAILURE;
	}
	
	while(fgets(puffer,256,newfile) != NULL)
	{
		fputs(puffer,writing);
		fflush(writing);
	}
	fclose(writing);
	fclose(newfile);
}
 
was du da mit fdopen machst is völliger quark.
beim aufruf von pipe() bekommste zwei file descriptors. einer zum lesen und einer zum schreiben.

nach fork() schließt du im parent einen dieser fds, im child den anderen. dann ist diese eine pipe nur IN EINER RICHTUNG benutzbar. fdopen() kannst du dir im übigen sparen.

wenn du in die gegenrichtung senden willst brauchst du ZWEI pipes. Selbst wenn du versuchen würdest das mit einer pipe zu machen (was theoretisch möglich wäre wenn du kein close() aufrufst) würdest du schnell ein anderes problem kriegen. unnamed pipes sind nämlich nicht gepuffert. d.h. wenn du im child was in die pipe schreibst und anschließend die gleiche pipe liest, bekommste das zurück was du selbst grad geschrieben hast.

also duplex-kommunikation IMMER mit zwei unterschiedlichen pipes machen.
 
Wie man an dem Artefakt in meinem header und meinen text den ich oben geschrieben hab bei meinem problem, hätte man erkennen können, dass ich schon versucht hab eine zweite pipe zu machen "rfd[2]".. aber das führte bei mir dazu dass mir mein tolles linux irgend ein speicherwirrwarr ausgegeben hat.. keine ahnung warum :/
Aber dann hast du mir meine befürchtung dass ich nach der benutzung einer pipe diese ned umdrehen kann grad bestätigt.. jetzt ´muss ich nur schaun wie ich das anders löse -.-


*edit: Ich bin ja so ein idiot... meine 2 Pipes funktionierne ja ! Ich idiot hab nur ein file als readable geöffnet was ich eigentlich als writeable öffnen müsste :D
 
Zuletzt bearbeitet:
Zurück
Oben