Back to index

nagios-plugins  1.4.16
stdio-write.c
Go to the documentation of this file.
00001 /* POSIX compatible FILE stream write function.
00002    Copyright (C) 2008-2010 Free Software Foundation, Inc.
00003    Written by Bruno Haible <bruno@clisp.org>, 2008.
00004 
00005    This program is free software: you can redistribute it and/or modify
00006    it under the terms of the GNU General Public License as published by
00007    the Free Software Foundation; either version 3 of the License, or
00008    (at your option) any later version.
00009 
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013    GNU General Public License for more details.
00014 
00015    You should have received a copy of the GNU General Public License
00016    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00017 
00018 #include <config.h>
00019 
00020 /* Specification.  */
00021 #include <stdio.h>
00022 
00023 /* Replace these functions only if module 'sigpipe' is requested.  */
00024 #if GNULIB_SIGPIPE
00025 
00026 /* On native Windows platforms, SIGPIPE does not exist.  When write() is
00027    called on a pipe with no readers, WriteFile() fails with error
00028    GetLastError() = ERROR_NO_DATA, and write() in consequence fails with
00029    error EINVAL.  This write() function is at the basis of the function
00030    which flushes the buffer of a FILE stream.  */
00031 
00032 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
00033 
00034 #  include <errno.h>
00035 #  include <signal.h>
00036 #  include <io.h>
00037 
00038 #  define WIN32_LEAN_AND_MEAN  /* avoid including junk */
00039 #  include <windows.h>
00040 
00041 #  define CALL_WITH_SIGPIPE_EMULATION(RETTYPE, EXPRESSION, FAILED) \
00042   if (ferror (stream))                                                        \
00043     return (EXPRESSION);                                                      \
00044   else                                                                        \
00045     {                                                                         \
00046       RETTYPE ret;                                                            \
00047       SetLastError (0);                                                       \
00048       ret = (EXPRESSION);                                                     \
00049       if (FAILED && GetLastError () == ERROR_NO_DATA && ferror (stream))      \
00050         {                                                                     \
00051           int fd = fileno (stream);                                           \
00052           if (fd >= 0                                                         \
00053               && GetFileType ((HANDLE) _get_osfhandle (fd)) == FILE_TYPE_PIPE)\
00054             {                                                                 \
00055               /* Try to raise signal SIGPIPE.  */                             \
00056               raise (SIGPIPE);                                                \
00057               /* If it is currently blocked or ignored, change errno from     \
00058                  EINVAL to EPIPE.  */                                         \
00059               errno = EPIPE;                                                  \
00060             }                                                                 \
00061         }                                                                     \
00062       return ret;                                                             \
00063     }
00064 
00065 #  if !REPLACE_PRINTF_POSIX /* avoid collision with printf.c */
00066 int
00067 printf (const char *format, ...)
00068 {
00069   int retval;
00070   va_list args;
00071 
00072   va_start (args, format);
00073   retval = vfprintf (stdout, format, args);
00074   va_end (args);
00075 
00076   return retval;
00077 }
00078 #  endif
00079 
00080 #  if !REPLACE_FPRINTF_POSIX /* avoid collision with fprintf.c */
00081 int
00082 fprintf (FILE *stream, const char *format, ...)
00083 {
00084   int retval;
00085   va_list args;
00086 
00087   va_start (args, format);
00088   retval = vfprintf (stream, format, args);
00089   va_end (args);
00090 
00091   return retval;
00092 }
00093 #  endif
00094 
00095 #  if !REPLACE_VPRINTF_POSIX /* avoid collision with vprintf.c */
00096 int
00097 vprintf (const char *format, va_list args)
00098 {
00099   return vfprintf (stdout, format, args);
00100 }
00101 #  endif
00102 
00103 #  if !REPLACE_VFPRINTF_POSIX /* avoid collision with vfprintf.c */
00104 int
00105 vfprintf (FILE *stream, const char *format, va_list args)
00106 #undef vfprintf
00107 {
00108   CALL_WITH_SIGPIPE_EMULATION (int, vfprintf (stream, format, args), ret == EOF)
00109 }
00110 #  endif
00111 
00112 int
00113 putchar (int c)
00114 {
00115   return fputc (c, stdout);
00116 }
00117 
00118 int
00119 fputc (int c, FILE *stream)
00120 #undef fputc
00121 {
00122   CALL_WITH_SIGPIPE_EMULATION (int, fputc (c, stream), ret == EOF)
00123 }
00124 
00125 int
00126 fputs (const char *string, FILE *stream)
00127 #undef fputs
00128 {
00129   CALL_WITH_SIGPIPE_EMULATION (int, fputs (string, stream), ret == EOF)
00130 }
00131 
00132 int
00133 puts (const char *string)
00134 #undef puts
00135 {
00136   FILE *stream = stdout;
00137   CALL_WITH_SIGPIPE_EMULATION (int, puts (string), ret == EOF)
00138 }
00139 
00140 size_t
00141 fwrite (const void *ptr, size_t s, size_t n, FILE *stream)
00142 #undef fwrite
00143 {
00144   CALL_WITH_SIGPIPE_EMULATION (size_t, fwrite (ptr, s, n, stream), ret < n)
00145 }
00146 
00147 # endif
00148 #endif