My task is to write C code that will create a pipe between two process, writer and reader.
The program will be called communicate and should be run as such: "communicate 10".
When this is done it should be doing the equivalent of "writer 10 | reader".
Writer just simply prints a message n number of times. Reader gets what writer prints and prints it out with no more than 50 characters per line.
My writer and reader programs are correct. Here they are:
writer.c
Code:
#include <stdio.h> /*typically in /usr/include*/
#include <stdlib.h>
int main (int argc, char* argv [ ])
{
int count, i;
if (argc != 2)
{
fprintf(stderr, "usage: %s count\n", argv[0]);
exit (-1); /*signal error (other than 0) to shell*/
}
else
count = atoi (argv[1]);
for ( i = 0; i < count; i++ )
printf ("Hellohello");
return 0;
}
reader.c
Code:
#include <stdio.h> /*typically in /usr/include*/
#include <stdlib.h>
int main (int argc, char* argv [ ])
{
int count, c;
if (argc != 1)
{
fprintf(stderr, "usage: %s", argv[0]);
exit (-1); /*signal error (other than 0) to shell*/
}
else
{
count = 0;
while ((c = getchar()) != EOF)
{
putchar(c);
if(++count % 50 == 0)
{
putchar((char)'\n');
}
}
if(count % 50 != 0 )
{
putchar((char)'\n');
}
}
return 0;
}
Now my problem must be with my communicate program. I think it is pretty well commented so it should be easy to follow what's going on:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
#define READ_END 0
#define WRITE_END 1
int main(int argc, char* argv [ ])
{
if (argc != 2)
{
fprintf(stderr, "usage: %s count\n", argv[0]);
exit (-1); /*signal error (other than 0) to shell*/
}
int fd[2];
pid_t childpid;
pid_t childpid2;
/* create pipe */
if (pipe(fd) == -1){
fprintf(stderr,"Pipe failed");
return 1;
}
childpid = fork();
if (childpid == -1) {
printf("Error in fork; program terminated\n");
return -1;
}
if (childpid == 0) {// child #1
close(1);// close standard output (fd = 1)
dup(fd[WRITE_END]);// dup the writing end of pipe it it gets fd = 1
// close both ends of the pipe
close(fd[WRITE_END]);
close(fd[READ_END]);
execlp("writer", "writer", argv[1], NULL);// exec to writer code
}
else {// parent
int status;
wait(&status);
childpid2 = fork();// fork again
if (childpid2 == -1) {
printf("Error in fork; program terminated\n");
return -1;
}
if (childpid2 == 0) {// child #2
close(0);// close standard input (fd = 0)
dup(fd[READ_END]);// dup the reading end of the pipe it gets fd = 0
// close both ends of the pipe
close(fd[WRITE_END]);
close(fd[READ_END]);
execlp("reader", "reader", NULL);// exec to reader code
}
else {// parent
int status;
wait(&status);
}
//close both ends of the pipe
close(fd[WRITE_END]);
close(fd[READ_END]);
}
return 0;
}
When I run my communicate program, 2 things are going wrong:
1.) I have to hit like ctrl-d or ctrl-z to stop the program. Otherwise it just sits there after printing stuff. Not sure why this is happening, but that's not really a HUGE problem relatively speaking.
2.) It only works in multiples of 5. If I do communicate 5, it works great except for bullet point 1. If I do communicate 10, same story. However if I do anything not a multiple of 5 nothing happens. So communicate 1, nothing. communicate 7, nothing.
Could someone help me figure out what's wrong with my code? I'm a very novice C programmer, but not a novice programmer in general.
Thanks for the help!