From: vippstar on
Hello comp.unix.programmer

note: APUE is Advanced Programming on the UNIX Environment
<http://www.kohala.com/start/apue.html>

Reading on chapter 3.9 of APUE, there is this code:

#include "apue.h"
#define BUFFSIZE 4096
int
main(void)
{
int n;
char buf[BUFFSIZE];
while ((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0)
if (write(STDOUT_FILENO, buf, n) != n)
err_sys("write error");
if (n < 0)
err_sys("read error");
exit(0);
}

apue.h contains all the prototypes etc.


write(2) man page says
RETURN VALUE
On success, the number of bytes written are returned (zero
indicates nothing was written). On error, -1 is returned, and errno
is set appropriately. If count is zero
and the file descriptor refers to a regular file, 0 will be
returned without causing any other effect. For a special file, the
results are not portable.

My question is:
Therefore why is the author taking write(..., n) != n as an error?
Also, what if the read call succeeds, but write returns -1?
err_sys("read error"); would be called and that is incorrect.

Am I missing something here?
From: fatfish on

> My question is:
> Therefore why is the author taking write(..., n) != n as an error?

in section 3.8 of APUE, Stevens wrote:
ssize_t write(int filedes, const void *buf, size_t nbytes);
Returns: number of bytes written if OK, 1 on error

The return value is usually equal to the nbytes argument; otherwise,
an error has occurred. A common cause for a write error is either
filling up a disk or exceeding the file size limit for a given process
(Section 7.11 and Exercise 10.11).

> Also, what if the read call succeeds, but write returns -1?
> err_sys("read error"); would be called and that is incorrect.
>
From: Barry Margolin on
In article
<0d1ea936-ce6f-4e12-a3f4-fa3548747c6a(a)w56g2000hsf.googlegroups.com>,
vippstar(a)gmail.com wrote:

> Hello comp.unix.programmer
>
> note: APUE is Advanced Programming on the UNIX Environment
> <http://www.kohala.com/start/apue.html>
>
> Reading on chapter 3.9 of APUE, there is this code:
>
> #include "apue.h"
> #define BUFFSIZE 4096
> int
> main(void)
> {
> int n;
> char buf[BUFFSIZE];
> while ((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0)
> if (write(STDOUT_FILENO, buf, n) != n)
> err_sys("write error");
> if (n < 0)
> err_sys("read error");
> exit(0);
> }
>
> apue.h contains all the prototypes etc.
>
>
> write(2) man page says
> RETURN VALUE
> On success, the number of bytes written are returned (zero
> indicates nothing was written). On error, -1 is returned, and errno
> is set appropriately. If count is zero
> and the file descriptor refers to a regular file, 0 will be
> returned without causing any other effect. For a special file, the
> results are not portable.
>
> My question is:
> Therefore why is the author taking write(..., n) != n as an error?
> Also, what if the read call succeeds, but write returns -1?
> err_sys("read error"); would be called and that is incorrect.
>
> Am I missing something here?

Unless you put the descriptor in non-blocking mode, write() will
normally block until it's able to write everything you asked it to
write. The only reason it would not do this is if some error occurred
that prevented it from writing the whole thing.

--
Barry Margolin, barmar(a)alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: James Antill on
On Fri, 28 Dec 2007 19:52:26 -0800, vippstar wrote:

> Hello comp.unix.programmer
>
> note: APUE is Advanced Programming on the UNIX Environment
> <http://www.kohala.com/start/apue.html>
>
> Reading on chapter 3.9 of APUE, there is this code:
>
> #include "apue.h"
> #define BUFFSIZE 4096
> int
> main(void)
> {
> int n;
> char buf[BUFFSIZE];
> while ((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0)
> if (write(STDOUT_FILENO, buf, n) != n)
> err_sys("write error");
> if (n < 0)
> err_sys("read error");
> exit(0);
> }
[...]
> My question is:
> Therefore why is the author taking write(..., n) != n as an error?

It is and it's a very common error, and traditionally implementations
have tried very hard to make sure it doesn't break on actual files. One
reason it's a common error is that if you include all the extra things you
need to make it robust, the points you are trying to teach (what read and
write do, at this stage) can get lost in the noise.
Annoyingly though, almost no books go back and show you what the real
version looks like. For your reference, see:

http://www.and.org/vstr/basic_cat.c

> Also,
> what if the read call succeeds, but write returns -1? err_sys("read
> error"); would be called and that is incorrect.

n isn't assigned to, so that doesn't happen. Also err_sys() calls exit so
even if it was assigned to it wouldn't hit the second err_sys() call.

--
James Antill -- james(a)and.org
C String APIs use too much memory? ustr: length, ref count, size and
read-only/fixed. Ave. 44% overhead over strdup(), for 0-20B strings
http://www.and.org/ustr/