annotate lib/fwriteerror.c @ 5453:d29dafc60cf3

Merge from coreutils to support a more-standard getopt.
author Paul Eggert <eggert@cs.ucla.edu>
date Wed, 17 Nov 2004 01:13:54 +0000 (2004-11-17)
parents 86c722c44f87
children c8676e66b5da
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4709
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1 /* Detect write error on a stream.
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
2 Copyright (C) 2003 Free Software Foundation, Inc.
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
3 Written by Bruno Haible <bruno@clisp.org>, 2003.
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
4
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
5 This program is free software; you can redistribute it and/or modify
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
6 it under the terms of the GNU General Public License as published by
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
7 the Free Software Foundation; either version 2, or (at your option)
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
8 any later version.
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
9
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
10 This program is distributed in the hope that it will be useful,
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
13 GNU General Public License for more details.
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
14
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
15 You should have received a copy of the GNU General Public License
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
16 along with this program; if not, write to the Free Software Foundation,
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
17 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
18
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
19 #if HAVE_CONFIG_H
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
20 # include <config.h>
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
21 #endif
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
22
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
23 /* Specification. */
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
24 #include "fwriteerror.h"
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
25
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
26 #include <errno.h>
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
27
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
28 int
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
29 fwriteerror (FILE *fp)
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
30 {
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
31 /* Need to
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
32 1. test the error indicator of the stream,
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
33 2. flush the buffers (what fclose() would do), testing for error again.
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
34 We can equally well swap these steps; this leads to smaller code. */
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
35
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
36 /* Clear errno, so that on non-POSIX systems the caller doesn't see a
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
37 wrong value of errno when we return -1. */
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
38 errno = 0;
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
39
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
40 if (fflush (fp))
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
41 return -1; /* errno is set here */
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
42
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
43 if (ferror (fp))
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
44 {
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
45 /* The stream had an error earlier, but its errno was lost. If the
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
46 error was not temporary, we can get the same errno by writing and
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
47 flushing one more byte. We can do so because at this point the
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
48 stream's contents is garbage anyway. */
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
49 if (fputc ('\0', fp) == EOF)
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
50 return -1; /* errno is set here */
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
51 if (fflush (fp))
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
52 return -1; /* errno is set here */
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
53 /* Give up on errno. */
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
54 errno = 0;
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
55 return -1;
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
56 }
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
57
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
58 return 0;
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
59 }
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
60
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
61
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
62 #if TEST
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
63
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
64 /* Name of a file on which writing fails. On systems without /dev/full,
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
65 you can choose a filename on a full filesystem. */
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
66 #define UNWRITABLE_FILE "/dev/full"
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
67
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
68 int
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
69 main ()
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
70 {
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
71 static int sizes[] =
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
72 {
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
73 511, 512, 513,
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
74 1023, 1024, 1025,
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
75 2047, 2048, 2049,
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
76 4095, 4096, 4097,
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
77 8191, 8192, 8193
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
78 };
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
79 static char dummy[8193];
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
80 unsigned int i, j;
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
81
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
82 for (i = 0; i < sizeof (sizes) / sizeof (sizes[0]); i++)
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
83 {
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
84 size_t size = sizes[i];
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
85
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
86 for (j = 0; j < 2; j++)
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
87 {
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
88 /* Run a test depending on i and j:
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
89 Write size bytes and then calls fflush if j==1. */
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
90 FILE *stream = fopen (UNWRITABLE_FILE, "w");
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
91
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
92 if (stream == NULL)
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
93 {
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
94 fprintf (stderr, "Test %u:%u: could not open file\n", i, j);
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
95 continue;
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
96 }
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
97
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
98 fwrite (dummy, 347, 1, stream);
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
99 fwrite (dummy, size - 347, 1, stream);
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
100 if (j)
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
101 fflush (stream);
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
102
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
103 if (fwriteerror (stream) == -1)
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
104 {
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
105 if (errno != ENOSPC)
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
106 fprintf (stderr, "Test %u:%u: fwriteerror ok, errno = %d\n",
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
107 i, j, errno);
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
108 }
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
109 else
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
110 fprintf (stderr, "Test %u:%u: fwriteerror found no error!\n",
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
111 i, j);
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
112
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
113 if (fclose (stream))
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
114 fprintf (stderr, "Test %u:%u: fclose failed, errno = %d\n",
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
115 i, j, errno);
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
116 }
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
117 }
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
118
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
119 return 0;
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
120 }
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
121
86c722c44f87 New module 'fwriteerror'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
122 #endif