Pipes
O exemplo abaixo ilustra a utilização de pipes dentro de um mesmo processo. Rode-o e explique o seu funcionamento.
main()
{
int pipefd[2], n;
char buff[100];
if (pipe(pipefd) < 0)
printf("pipe error");
printf("read fd = %d, write fd = %d\n", pipefd[0], pipefd[1]);
if (write(pipefd[1], "hello world\n", 12) != 12)
printf("write error");
if ((n = read(pipefd[0], buff, sizeof(buff))) <= 0)
printf("read error");
write(1, buff, n); /* fd 1 = stdout */
exit(0);
}Exemplo abaixo mostra um sistema produtor/consumidor. Compile-o e rode. Explique o funcionamento do sistema, detalhando as ações do pai e do filho. Faça um diagrama (edite o desenho com caracteres ASCII) explicando o funcionamento.
#include stdio.h
#include errno.h
#include sys/errno.h
#define MAXBUFF 1024 main()
{
int childpid, pipe1[2], pipe2[2];
printf("Inicio do programa Client_Server\n\n");
if (pipe(pipe1) menor 0 || pipe(pipe2) < 0)
{
perror("can't create pipes");
exit(0);
}
printf("Os pipes foram criados corretamente\n");
if ((childpid = fork()) < 0)
{
perror("can't fork");
}
else if (childpid > 0)
{
/* parent */
close(pipe1[0]);
close(pipe2[1]);
client(pipe2[0], pipe1[1]);
while (wait((int *) 0) != childpid);
/* wait for child */
close(pipe1[1]);
close(pipe2[0]);
exit(0);
}
else
{
/* child */
close(pipe1[1]);
close(pipe2[0]);
server(pipe1[0], pipe2[1]);
close(pipe1[0]);
close(pipe2[1]);
exit(0);
}
}
/* Esta e' a funcao cliente */
client(int readfd, intwritefd)
{
char buff[MAXBUFF];
int n;
/*
* Read the filename from standard input,
* write it to the IPC descriptor.
*/
if (fgets(buff, MAXBUFF, stdin) == NULL)
perror("client: filename read error");
n = strlen(buff);
if (buff[n-1] == '\n')
n--; /* ignore newline from fgets() */
if (write(writefd, buff, n) != n)
perror("client: filename write error");
/*
* Read the data from the IPC descriptor and write
* to standard output.
*/
while ((n = read(readfd, buff, MAXBUFF)) > 0)
if (write(1, buff, n) != n) /* fd 1 = stdout */
perror("client: data write error");
if (n m < 0)
{
perror("client: data read error");
}
}
/* Esta e' a funcao servidor */
server(int readfd, int writefd)
{
char buff[MAXBUFF];
char errmesg[256];
int n;
long int fd;
extern int errno;
extern char *sys_errlist[];
/*
* Read the filename from the IPC descriptor.
*/
if ((n = read(readfd, buff, MAXBUFF)) < = 0)
perror("server: filename read error");
buff[n] = '\0'; /* null terminate filename */
if ((fd = open(buff, 0)) < 0)
{
/*
* Error. Format an error message and send it back
* to the client.
*/
sprintf(errmesg, ":can't open.\n");
strcat(buff, errmesg);
n = strlen(buff);
if (write(writefd, buff, n) != n)
perror("server: errmesg write error");
}
else
{
/*
* Read the data from the file and write to
* the IPC descriptor.
*/
while ((n = read(fd, buff, MAXBUFF)) > 0)
if (write(writefd, buff, n) != n)
perror("server: data write error");
if (n < 0)
{
perror("server: read error");
}
}
} Quais as limitações deste mecanismo de comunicação entre processos para a implementação de pares servidor/cliente?
Modifique o exemplo de modo que o servidor seja uma calcuradora com as 4 operações aritméticas básicas. Projete um sistema de entrada/saída adequado.