version 1.1.1.1, 2012/02/21 22:57:48
|
version 1.1.1.2, 2012/05/29 09:29:43
|
Line 1
|
Line 1
|
/* POSIX compatible FILE stream write function. |
/* POSIX compatible FILE stream write function. |
Copyright (C) 2008 Free Software Foundation, Inc. | Copyright (C) 2008-2011 Free Software Foundation, Inc. |
Written by Bruno Haible <bruno@clisp.org>, 2008. |
Written by Bruno Haible <bruno@clisp.org>, 2008. |
|
|
This program is free software: you can redistribute it and/or modify |
This program is free software: you can redistribute it and/or modify |
Line 20
|
Line 20
|
/* Specification. */ |
/* Specification. */ |
#include <stdio.h> |
#include <stdio.h> |
|
|
/* Replace these functions only if module 'sigpipe' is requested. */ | /* Replace these functions only if module 'nonblocking' or module 'sigpipe' is |
#if GNULIB_SIGPIPE | requested. */ |
| #if GNULIB_NONBLOCKING || GNULIB_SIGPIPE |
|
|
/* On native Windows platforms, SIGPIPE does not exist. When write() is |
/* On native Windows platforms, SIGPIPE does not exist. When write() is |
called on a pipe with no readers, WriteFile() fails with error |
called on a pipe with no readers, WriteFile() fails with error |
Line 38
|
Line 39
|
# define WIN32_LEAN_AND_MEAN /* avoid including junk */ |
# define WIN32_LEAN_AND_MEAN /* avoid including junk */ |
# include <windows.h> |
# include <windows.h> |
|
|
|
# if GNULIB_NONBLOCKING |
|
# define CLEAR_ERRNO \ |
|
errno = 0; |
|
# define HANDLE_ENOSPC \ |
|
if (errno == ENOSPC && ferror (stream)) \ |
|
{ \ |
|
int fd = fileno (stream); \ |
|
if (fd >= 0) \ |
|
{ \ |
|
HANDLE h = (HANDLE) _get_osfhandle (fd); \ |
|
if (GetFileType (h) == FILE_TYPE_PIPE) \ |
|
{ \ |
|
/* h is a pipe or socket. */ \ |
|
DWORD state; \ |
|
if (GetNamedPipeHandleState (h, &state, NULL, NULL, \ |
|
NULL, NULL, 0) \ |
|
&& (state & PIPE_NOWAIT) != 0) \ |
|
/* h is a pipe in non-blocking mode. \ |
|
Change errno from ENOSPC to EAGAIN. */ \ |
|
errno = EAGAIN; \ |
|
} \ |
|
} \ |
|
} \ |
|
else |
|
# else |
|
# define CLEAR_ERRNO |
|
# define HANDLE_ENOSPC |
|
# endif |
|
|
|
# if GNULIB_SIGPIPE |
|
# define CLEAR_LastError \ |
|
SetLastError (0); |
|
# define HANDLE_ERROR_NO_DATA \ |
|
if (GetLastError () == ERROR_NO_DATA && ferror (stream)) \ |
|
{ \ |
|
int fd = fileno (stream); \ |
|
if (fd >= 0 \ |
|
&& GetFileType ((HANDLE) _get_osfhandle (fd)) \ |
|
== FILE_TYPE_PIPE) \ |
|
{ \ |
|
/* Try to raise signal SIGPIPE. */ \ |
|
raise (SIGPIPE); \ |
|
/* If it is currently blocked or ignored, change errno from \ |
|
EINVAL to EPIPE. */ \ |
|
errno = EPIPE; \ |
|
} \ |
|
} \ |
|
else |
|
# else |
|
# define CLEAR_LastError |
|
# define HANDLE_ERROR_NO_DATA |
|
# endif |
|
|
# define CALL_WITH_SIGPIPE_EMULATION(RETTYPE, EXPRESSION, FAILED) \ |
# define CALL_WITH_SIGPIPE_EMULATION(RETTYPE, EXPRESSION, FAILED) \ |
if (ferror (stream)) \ | if (ferror (stream)) \ |
return (EXPRESSION); \ | return (EXPRESSION); \ |
else \ | else \ |
{ \ | { \ |
RETTYPE ret; \ | RETTYPE ret; \ |
SetLastError (0); \ | CLEAR_ERRNO \ |
ret = (EXPRESSION); \ | CLEAR_LastError \ |
if (FAILED && GetLastError () == ERROR_NO_DATA && ferror (stream)) \ | ret = (EXPRESSION); \ |
{ \ | if (FAILED) \ |
int fd = fileno (stream); \ | { \ |
if (fd >= 0 \ | HANDLE_ENOSPC \ |
&& GetFileType ((HANDLE) _get_osfhandle (fd)) == FILE_TYPE_PIPE)\ | HANDLE_ERROR_NO_DATA \ |
{ \ | ; \ |
/* Try to raise signal SIGPIPE. */ \ | } \ |
raise (SIGPIPE); \ | return ret; \ |
/* If it is currently blocked or ignored, change errno from \ | |
EINVAL to EPIPE. */ \ | |
errno = EPIPE; \ | |
} \ | |
} \ | |
return ret; \ | |
} |
} |
|
|
# if !REPLACE_PRINTF_POSIX /* avoid collision with printf.c */ |
# if !REPLACE_PRINTF_POSIX /* avoid collision with printf.c */ |
Line 92 fprintf (FILE *stream, const char *format, ...)
|
Line 140 fprintf (FILE *stream, const char *format, ...)
|
} |
} |
# endif |
# endif |
|
|
# if !REPLACE_VFPRINTF_POSIX /* avoid collision with vprintf.c */ | # if !REPLACE_VPRINTF_POSIX /* avoid collision with vprintf.c */ |
int |
int |
vprintf (const char *format, va_list args) |
vprintf (const char *format, va_list args) |
{ |
{ |
Line 100 vprintf (const char *format, va_list args)
|
Line 148 vprintf (const char *format, va_list args)
|
} |
} |
# endif |
# endif |
|
|
# if !REPLACE_VPRINTF_POSIX /* avoid collision with vfprintf.c */ | # if !REPLACE_VFPRINTF_POSIX /* avoid collision with vfprintf.c */ |
int |
int |
vfprintf (FILE *stream, const char *format, va_list args) |
vfprintf (FILE *stream, const char *format, va_list args) |
#undef vfprintf |
#undef vfprintf |