Pipes

X

Xarky

Hi,
I wrote the following program (source code below). I am using
pipes, were the parent reads and the child writes.

My problem is that I am writing the same line in the pipe for a
fixed number of times 50 (made a for loop). When writing it back it
to string I made a counter(cnt) to count the occurances of each
string. The problem is that never gives me 50, but 43.

Probably my problem is with the file descriptors.
Can some one help me pls.
Thanks in advance


/* Source code */
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
#define MAX 20
main()
{
system ("clear");

pid_t pid;
int fd[2];
ssize_t data;
char buff[MAX];
char msg[] = "hello, world.\n\0";

if (pipe(fd) < 0) // creating pipe
printf ("Error encountered: %s.\n", strerror(errno));

else // no error encountered
{
if ((pid = fork()) == -1)
printf ("Error encountered: %s.\n", strerror(errno));

else if (pid == 0) // child to write
{
close (fd[0]); // closing reading part
int i;

for (i=0; i<500; i++)
write (fd[1], msg, sizeof(msg));

close (fd[1]); // terminating writing

_exit(0);
} // end child process

else // parent to read
{
close (fd[1]); // closing writing part
int cnt=0;

data = read (fd[0], buff, sizeof(buff)-1);
while (data != 0)
{
cnt++;
write (fileno(stdout), buff, data);
data = read (fd[0], buff, sizeof(buff)-1);
} // end loop

printf ("Number of strings counted is %d.\n", cnt);

close (fd[0]); // terminating reading
} // end parent process
} // end else
} // end main
 
Z

Zoran Cutura

Xarky said:
Hi,
I wrote the following program (source code below). I am using
pipes, were the parent reads and the child writes.

please take your question to an appropriate newsgroup. I.e.
comp.unix.programmer

here we try to stick to the C language as defined by the ISO C
standard(s).
 
D

Dan Pop

In said:
/* Source code */
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
^^^^^^^^^^
At this point, you have left the realm of c.l.c and entered the realm of
comp.unix.programmer. You should have been able to figure this out by
yourself!

Dan
 
C

CBFalconer

Xarky said:
I wrote the following program (source code below). I am using
pipes, were the parent reads and the child writes.
^^^^^ ^^^^^^ ^^^^^

You are already off-topic for c.l.c. See refs below
 
E

exonic

On Thu, 15 Apr 2004 07:58:38 -0700, Xarky wrote:

your program loop is 500 not 50, but I still understand. I dont care if
you've left the scope of comp.lang.c, this is still valid in my opinion.
besides what else would you talk about besides syntax if it wasn't.

[ snip ]
/* Source code */
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
missing a couple headers like unistd.h, stdlib.h and string.h
#define MAX 20

[ snip ]

from the look of the logic, it is possible to do multiple writes, and then
in the parent thread, one read would take in the data from both those
writes. This is possibly what's happening, a better way to check
integrity, and ensure teh data is coming across the pipe would be to
calculate total bytes written and total bytes read.
 
X

Xenos

Xarky said:
Hi,
I wrote the following program (source code below). I am using
pipes, were the parent reads and the child writes.

My problem is that I am writing the same line in the pipe for a
fixed number of times 50 (made a for loop). When writing it back it
to string I made a counter(cnt) to count the occurances of each
string. The problem is that never gives me 50, but 43.

Probably my problem is with the file descriptors.
Can some one help me pls.
Thanks in advance


/* Source code */
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
#define MAX 20
main()
{
system ("clear");

pid_t pid;
int fd[2];
ssize_t data;
char buff[MAX];
char msg[] = "hello, world.\n\0";

if (pipe(fd) < 0) // creating pipe
printf ("Error encountered: %s.\n", strerror(errno));

else // no error encountered
{
if ((pid = fork()) == -1)
printf ("Error encountered: %s.\n", strerror(errno));

else if (pid == 0) // child to write
{
close (fd[0]); // closing reading part
int i;

for (i=0; i<500; i++)
write (fd[1], msg, sizeof(msg));

close (fd[1]); // terminating writing

_exit(0);
} // end child process

else // parent to read
{
close (fd[1]); // closing writing part
int cnt=0;

data = read (fd[0], buff, sizeof(buff)-1);
while (data != 0)
{
cnt++;
write (fileno(stdout), buff, data);
data = read (fd[0], buff, sizeof(buff)-1);
} // end loop

printf ("Number of strings counted is %d.\n", cnt);

close (fd[0]); // terminating reading
} // end parent process
} // end else
} // end main


your problem is that write and read are not guaranteed to give you the exact
count you ask for, you have to check the return code. If the result is
neg., you have an error; 0, the pipe has been closed, and pos. is the number
actually read/written.

for example for you tell it to read 50 byte, if may give you any number
between 1 and 50 depending how much is actually in its buffer at the time.
you have to continue to read (adjusting your current pointer into the buffer
and the number to read) until you get all that you want.
 
J

Jens.Toerring

Xenos said:
Xarky said:
Hi,
I wrote the following program (source code below). I am using
pipes, were the parent reads and the child writes.

My problem is that I am writing the same line in the pipe for a
fixed number of times 50 (made a for loop). When writing it back it
to string I made a counter(cnt) to count the occurances of each
string. The problem is that never gives me 50, but 43.

Probably my problem is with the file descriptors.
Can some one help me pls.
Thanks in advance


/* Source code */
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
#define MAX 20
main()
{
system ("clear");

pid_t pid;
int fd[2];
ssize_t data;
char buff[MAX];
char msg[] = "hello, world.\n\0";

if (pipe(fd) < 0) // creating pipe
printf ("Error encountered: %s.\n", strerror(errno));

else // no error encountered
{
if ((pid = fork()) == -1)
printf ("Error encountered: %s.\n", strerror(errno));

else if (pid == 0) // child to write
{
close (fd[0]); // closing reading part
int i;

for (i=0; i<500; i++)
write (fd[1], msg, sizeof(msg));

close (fd[1]); // terminating writing

_exit(0);
} // end child process

else // parent to read
{
close (fd[1]); // closing writing part
int cnt=0;

data = read (fd[0], buff, sizeof(buff)-1);
while (data != 0)
{
cnt++;
write (fileno(stdout), buff, data);
data = read (fd[0], buff, sizeof(buff)-1);
} // end loop

printf ("Number of strings counted is %d.\n", cnt);

close (fd[0]); // terminating reading
} // end parent process
} // end else
} // end main
your problem is that write and read are not guaranteed to give you the exact
count you ask for, you have to check the return code. If the result is
neg., you have an error; 0, the pipe has been closed, and pos. is the number
actually read/written.
for example for you tell it to read 50 byte, if may give you any number
between 1 and 50 depending how much is actually in its buffer at the time.
you have to continue to read (adjusting your current pointer into the buffer
and the number to read) until you get all that you want.

Xenos, please respect that these kind of platform specific questions
are off-topic in this group as the OP already has been told, even
with a redirect to a probably more appropriate newsgroup like
comp.unix.programmer.

You can easily see why when you look at your own answer. On the
system I am working on the non-standard C function read() may
return values between -1 and 19 for the program of the OP and not
values between 1 to 50. And also what you claim to be the problem
in the code would be definitely _not_ the problem (i.e. the OPs
question why he has to call read() only 43 times instead of 50
times). Since I do not know which system you're talking about I
won't claim that your answer is wrong (on my prefered platform,
Linux, the result of 422 would actually be the most probable result,
going by the code, and 43 after replacing the 500 in the childs code
by 50 as according to what the OP wrote in the text) but it hope-
fully makes you understand why discussing platform specific problems
in clc is heavily frowned upon - it simply doesn't make sense. I would
be quite willing to discuss the OPs problem in comp.unix.programmer,
but here (in clc) it would be totally out of place - and I would also
guess that at least 80% of the regulars here know the answer very well
but all of them feeling the same way.

There are some C specific issues with that program (e.g. not declaring
main() to return an int and neglecting to return an int from main() or
the question why the OP feels it necessary to add another '\0' to the
end of a string (msg) that, from its definition, already has a '\0')
but that's obviously not of much concern for the OP at the moment (but
it actually plays some role in the unexpected results he gets, assuming
that the OP is using some kind of UNIX system).

Regards, Jens
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top