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