Problem reading from pipe ("|") using read() -- Solved

Problem reading from pipe ("|") using read() -- Solved

Post by Herb L » Fri, 28 Aug 1992 04:58:59

First of all, thanks to those who tried to help even thought I didn't
provide enough info in my original post.  Thanks to David Wagner who
provided a subroutine for reading and checking the return value.

I have fixed the problem so that I can read from the pipe, but I don't
understand exactly why it works.  Here is my modification of David's
read routine that I used to read data:

        size_t tp_read(int fd, char *bufptr, size_t count)
            size_t nread = 0;
            int    i;

            for (i = 0; i < count; i += nread) {
                nread = read(fd, bufptr + i, count - i);
                if (nread < 0)
                    err("read: %s", sys_errlist[errno]);
                else if (nread == 0)

            return nread;

The data that I'm reading is in this format: ascii header, binary header,
binary data.  The binary data is broken into parts of equal sizes; i.e.,
the first data part contains 2000 bytes, the second part 2000 bytes, etc.  
The data part can be from ~250 bytes to ~64kb.

Now the part that I don't understand is this.  I read each section as

        nread = tp_read(fd, &ascii_header, ascii_bytes);
        nread = tp_read(fd, &binary_header, binary_bytes);
        while(...) {
          nread = tp_read(fd, &data, data_bytes);

Apparently, the program had tp_read(fd, (char *)&data, data_bytes).  
When I took out the cast, the program worked.  However, the original
program also cast the ascii_header and binary_header to (char *);
but I was always able to read the headers correctly.  I won't list out
the entire "data" structure since it is very long, but its members are
of type short, unsigned short, long, and float.  The ascii_header and
binary_header have similar members.

I also tried replacing tp_read() with the system read() after I got
the program to work; however, I was not able to read the data correctly.  
The headers come out fine though.  As I put it in the other post, the
data appears "all messed up."  What I mean by this is that I can't tell
from the output how the data is being read.  It doesn't appear to have
been offset.  It just looks like garbage.

If I go back and use the tp_read subroutine and check how many times
it went through the loop, everytime I checked the value came out to be
1.  So it seems that it was able to read all the data on the first try.  
Why doesn't it work if I just put read() in place of tp_read()?


Problem reading from pipe ("|") using read() -- Solved

Post by Jon Russell » Sat, 29 Aug 1992 08:20:13

Why would not receive a SIGPIPE writing to a connected socket
closed by the receiver.

The first write succeeds subsequent ones fail.

The application is sun rpc based, however I duplicated the behavior
in a straight socket based app. How can I handle the first write as an]
error ?

Thanks in advance.

Jonathan Russell            Bond Portfolio Analysis     212-783-7852

New York NY 10048           Seven World Trade Center    uunet!!bpa10!jon


1. Problem reading from pipe ("|") using read()

: First of all, my program reads input from standard in and writes to
: standard out.  I had used fread() and fwrite() to do I/O, but because I
: needed to do some ioctls, it was suggested that I use read() and
: write() instead.  I did not have any problems until I changed all my
: file pointers to file descriptors, fopen()/fclose() to open()/close(),
: and fread()/fwrite() to read()/write().
: My problem is this.  When I run the program by itself, e.g.:
:       run < input > output
: Everything is fine.  However, if I get the input from the pipe:
:       "some program" < input | run > output
: The input to the "run" program gets messed up.  I don't get any system

What does "messed up" mean?  You need to supply
more info if anyone is going to be able to help you
with this.  

What does your read call look like?

Are you using any other system calls (e.g fork()?)

: errors.  I believe the problem is with read(), but I don't know how or
: why it is doing this.  Someone suggested that it may be due to some
: buffering problem in read().  Can anyone elaborate on this?  Since the
: default for the program is standard in and standard out, I do not need
: to use open() to open standard in and standard out, right?  I've checked
: the file descriptors when I run the program and they are correct:  0 for
: input and 1 for output.
: Any suggestions to solving this?

I doubt it, unless you give us some more info...

: Thanks,
:       Herb
Frank O'Dwyer                                   Disclaimer:
Siemens-Nixdorf AG                              I will deny everything
Tel.  : +49 (89) 636-40639                      Fax.  : +49 (89) 636-45860

2. Disk Errors! Bad Blocks: Is there any way to mark them without reformatting?

3. ksh - no "read" from pipe, but not common "subshell" issue

4. Diamond Fire GL1000 pro

5. problem with "| while read"

6. GCC data alignment - how to turn off ?

7. Type "(", ")" and "{", "}" in X...

8. wildcards in hosts.lpd

9. named pipes versus the unnamed pipeline using "|"

10. simple question about using pipe "|"

11. "Tar-Baby": Data read/write dilemma using "tar"

12. no "read" from pipe, using ksh on Mac OS 10.4.3

13. cut -d\| -f2- (keeping the first and last "|")