/*
 * chatpipe.c
 * 
 * Copyright 2026 osboxes <osboxes@osboxes>
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 * 
 * chat entre procesos usando pipes en la misma consola
 */

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <signal.h>


void ingreso(const char *,char *,int);
void leer(int,char *,int);
void grabar(int,char *);

void sig_usr1_h1(int);
void sig_usr1_h2(int);

int p1[2],p2[2];

int main(int argc, char **argv) {
	pipe(p1);
	pipe(p2);
	pid_t h1,h2;
	char linea[100];
	if ( (h1=fork()) ) {
		//padre
		if ( (h2=fork()) ) {
			// padre
			close(p1[0]);close(p1[1]);
			close(p2[0]);close(p2[1]);
			pid_t proc1 = wait(0); //espero fin de h1 o h2
			if ( proc1 == h1 ) kill(h2,SIGUSR1);
			else kill(h1,SIGUSR1);
			wait(0); //espero fin de h1 o h2
			printf("fin main\n");
		} else {
			//h2 escritor p2
			if ( fork() ) {
				//h2 escritor p2
				signal(SIGUSR1,sig_usr1_h2);
				close(p1[0]);close(p1[1]);
				close(p2[0]);
				do {
					ingreso("h2>",linea,100);
					grabar(p2[1],linea);
				} while(strcasecmp(linea,"chau") != 0);
				close(p2[1]);
				printf("fin h2\n");
			} else {        
				//hh2 lector p1
				close(p2[0]);close(p2[1]);
				close(p1[1]);
				memset(linea,0,100);
				do {
					leer(p1[0],linea,100);
				} while(strcasecmp(linea,"chau") != 0);
				close(p1[0]);
				printf("fin hh2\n");
			}
		}
	} else {
		//h1 escritor p1
		if ( fork() ) {
			//h1 escritor p1
			signal(SIGUSR1,sig_usr1_h1);
			close(p2[0]);close(p2[1]);
			close(p1[0]);
			do {
				ingreso("h1>",linea,100);
				grabar(p1[1],linea);
			} while(strcasecmp(linea,"chau") != 0);
			close(p1[1]);
			printf("fin h1\n");
		} else {
			//hh1 lector p2
			close(p1[0]);close(p1[1]);
			close(p2[1]);
			memset(linea,0,100);
			do {
				leer(p2[0],linea,100);
			} while(strcasecmp(linea,"chau") != 0);
			close(p2[0]);
			printf("fin hh1\n");
		}
	}
	return 0;
}

void ingreso(const char *prompt,char *buffer,int largo) {
	printf("%s",prompt);
	fgets(buffer,largo,stdin);
	buffer[strlen(buffer)-1]='\0';
}

void leer(int fd,char *buffer,int largo) {
	int n = read(fd,buffer,largo);
	if ( n != -1 ) buffer[n]='\0';
	if ( n ) printf("%s\n",buffer);
}

void grabar(int fd,char *p) {
	write(fd,p,strlen(p)+1);
}

void sig_usr1_h1(int signo) {
	char linea[100];
	strcpy(linea,"chau");
	grabar(p1[1],linea);
	close(p1[1]);
	wait(0);
	exit(0);
}
void sig_usr1_h2(int signo) {
	char linea[100];
	strcpy(linea,"chau");
	grabar(p2[1],linea);
	close(p2[1]);
	wait(0);
	exit(0);
}
