Annotation of embedaddon/libiconv/srclib/stdio-write.c, revision 1.1.1.1
1.1 misho 1: /* POSIX compatible FILE stream write function.
2: Copyright (C) 2008 Free Software Foundation, Inc.
3: Written by Bruno Haible <bruno@clisp.org>, 2008.
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 3 of the License, or
8: (at your option) 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, see <http://www.gnu.org/licenses/>. */
17:
18: #include <config.h>
19:
20: /* Specification. */
21: #include <stdio.h>
22:
23: /* Replace these functions only if module 'sigpipe' is requested. */
24: #if GNULIB_SIGPIPE
25:
26: /* On native Windows platforms, SIGPIPE does not exist. When write() is
27: called on a pipe with no readers, WriteFile() fails with error
28: GetLastError() = ERROR_NO_DATA, and write() in consequence fails with
29: error EINVAL. This write() function is at the basis of the function
30: which flushes the buffer of a FILE stream. */
31:
32: # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
33:
34: # include <errno.h>
35: # include <signal.h>
36: # include <io.h>
37:
38: # define WIN32_LEAN_AND_MEAN /* avoid including junk */
39: # include <windows.h>
40:
41: # define CALL_WITH_SIGPIPE_EMULATION(RETTYPE, EXPRESSION, FAILED) \
42: if (ferror (stream)) \
43: return (EXPRESSION); \
44: else \
45: { \
46: RETTYPE ret; \
47: SetLastError (0); \
48: ret = (EXPRESSION); \
49: if (FAILED && GetLastError () == ERROR_NO_DATA && ferror (stream)) \
50: { \
51: int fd = fileno (stream); \
52: if (fd >= 0 \
53: && GetFileType ((HANDLE) _get_osfhandle (fd)) == FILE_TYPE_PIPE)\
54: { \
55: /* Try to raise signal SIGPIPE. */ \
56: raise (SIGPIPE); \
57: /* If it is currently blocked or ignored, change errno from \
58: EINVAL to EPIPE. */ \
59: errno = EPIPE; \
60: } \
61: } \
62: return ret; \
63: }
64:
65: # if !REPLACE_PRINTF_POSIX /* avoid collision with printf.c */
66: int
67: printf (const char *format, ...)
68: {
69: int retval;
70: va_list args;
71:
72: va_start (args, format);
73: retval = vfprintf (stdout, format, args);
74: va_end (args);
75:
76: return retval;
77: }
78: # endif
79:
80: # if !REPLACE_FPRINTF_POSIX /* avoid collision with fprintf.c */
81: int
82: fprintf (FILE *stream, const char *format, ...)
83: {
84: int retval;
85: va_list args;
86:
87: va_start (args, format);
88: retval = vfprintf (stream, format, args);
89: va_end (args);
90:
91: return retval;
92: }
93: # endif
94:
95: # if !REPLACE_VFPRINTF_POSIX /* avoid collision with vprintf.c */
96: int
97: vprintf (const char *format, va_list args)
98: {
99: return vfprintf (stdout, format, args);
100: }
101: # endif
102:
103: # if !REPLACE_VPRINTF_POSIX /* avoid collision with vfprintf.c */
104: int
105: vfprintf (FILE *stream, const char *format, va_list args)
106: #undef vfprintf
107: {
108: CALL_WITH_SIGPIPE_EMULATION (int, vfprintf (stream, format, args), ret == EOF)
109: }
110: # endif
111:
112: int
113: putchar (int c)
114: {
115: return fputc (c, stdout);
116: }
117:
118: int
119: fputc (int c, FILE *stream)
120: #undef fputc
121: {
122: CALL_WITH_SIGPIPE_EMULATION (int, fputc (c, stream), ret == EOF)
123: }
124:
125: int
126: fputs (const char *string, FILE *stream)
127: #undef fputs
128: {
129: CALL_WITH_SIGPIPE_EMULATION (int, fputs (string, stream), ret == EOF)
130: }
131:
132: int
133: puts (const char *string)
134: #undef puts
135: {
136: FILE *stream = stdout;
137: CALL_WITH_SIGPIPE_EMULATION (int, puts (string), ret == EOF)
138: }
139:
140: size_t
141: fwrite (const void *ptr, size_t s, size_t n, FILE *stream)
142: #undef fwrite
143: {
144: CALL_WITH_SIGPIPE_EMULATION (size_t, fwrite (ptr, s, n, stream), ret < n)
145: }
146:
147: # endif
148: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>