diff options
| author | Eli Zaretskii | 2012-11-13 16:17:18 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2012-11-13 16:17:18 +0200 |
| commit | 3c4ca7155293ffc2d04708007131bcbc882d8913 (patch) | |
| tree | 61787be8cd43b6fb3d5159852fbd186eea404de7 /lib | |
| parent | 5ade42a5114255c43117065494b96d480c1e1588 (diff) | |
| parent | c708524567662c8911c5ab2695acc7bda0383705 (diff) | |
| download | emacs-3c4ca7155293ffc2d04708007131bcbc882d8913.tar.gz emacs-3c4ca7155293ffc2d04708007131bcbc882d8913.zip | |
Merge from trunk.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/close-stream.c | 78 | ||||
| -rw-r--r-- | lib/close-stream.h | 2 | ||||
| -rw-r--r-- | lib/fpending.c | 30 | ||||
| -rw-r--r-- | lib/fpending.h | 30 | ||||
| -rw-r--r-- | lib/gnulib.mk | 19 | ||||
| -rw-r--r-- | lib/makefile.w32-in | 14 |
6 files changed, 172 insertions, 1 deletions
diff --git a/lib/close-stream.c b/lib/close-stream.c new file mode 100644 index 00000000000..04fa5ece09d --- /dev/null +++ b/lib/close-stream.c | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | /* Close a stream, with nicer error checking than fclose's. | ||
| 2 | |||
| 3 | Copyright (C) 1998-2002, 2004, 2006-2012 Free Software Foundation, Inc. | ||
| 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 | #include "close-stream.h" | ||
| 21 | |||
| 22 | #include <errno.h> | ||
| 23 | #include <stdbool.h> | ||
| 24 | |||
| 25 | #include "fpending.h" | ||
| 26 | |||
| 27 | #if USE_UNLOCKED_IO | ||
| 28 | # include "unlocked-io.h" | ||
| 29 | #endif | ||
| 30 | |||
| 31 | /* Close STREAM. Return 0 if successful, EOF (setting errno) | ||
| 32 | otherwise. A failure might set errno to 0 if the error number | ||
| 33 | cannot be determined. | ||
| 34 | |||
| 35 | A failure with errno set to EPIPE may or may not indicate an error | ||
| 36 | situation worth signaling to the user. See the documentation of the | ||
| 37 | close_stdout_set_ignore_EPIPE function for details. | ||
| 38 | |||
| 39 | If a program writes *anything* to STREAM, that program should close | ||
| 40 | STREAM and make sure that it succeeds before exiting. Otherwise, | ||
| 41 | suppose that you go to the extreme of checking the return status | ||
| 42 | of every function that does an explicit write to STREAM. The last | ||
| 43 | printf can succeed in writing to the internal stream buffer, and yet | ||
| 44 | the fclose(STREAM) could still fail (due e.g., to a disk full error) | ||
| 45 | when it tries to write out that buffered data. Thus, you would be | ||
| 46 | left with an incomplete output file and the offending program would | ||
| 47 | exit successfully. Even calling fflush is not always sufficient, | ||
| 48 | since some file systems (NFS and CODA) buffer written/flushed data | ||
| 49 | until an actual close call. | ||
| 50 | |||
| 51 | Besides, it's wasteful to check the return value from every call | ||
| 52 | that writes to STREAM -- just let the internal stream state record | ||
| 53 | the failure. That's what the ferror test is checking below. */ | ||
| 54 | |||
| 55 | int | ||
| 56 | close_stream (FILE *stream) | ||
| 57 | { | ||
| 58 | const bool some_pending = (__fpending (stream) != 0); | ||
| 59 | const bool prev_fail = (ferror (stream) != 0); | ||
| 60 | const bool fclose_fail = (fclose (stream) != 0); | ||
| 61 | |||
| 62 | /* Return an error indication if there was a previous failure or if | ||
| 63 | fclose failed, with one exception: ignore an fclose failure if | ||
| 64 | there was no previous error, no data remains to be flushed, and | ||
| 65 | fclose failed with EBADF. That can happen when a program like cp | ||
| 66 | is invoked like this 'cp a b >&-' (i.e., with standard output | ||
| 67 | closed) and doesn't generate any output (hence no previous error | ||
| 68 | and nothing to be flushed). */ | ||
| 69 | |||
| 70 | if (prev_fail || (fclose_fail && (some_pending || errno != EBADF))) | ||
| 71 | { | ||
| 72 | if (! fclose_fail) | ||
| 73 | errno = 0; | ||
| 74 | return EOF; | ||
| 75 | } | ||
| 76 | |||
| 77 | return 0; | ||
| 78 | } | ||
diff --git a/lib/close-stream.h b/lib/close-stream.h new file mode 100644 index 00000000000..be3d4196b06 --- /dev/null +++ b/lib/close-stream.h | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | #include <stdio.h> | ||
| 2 | int close_stream (FILE *stream); | ||
diff --git a/lib/fpending.c b/lib/fpending.c new file mode 100644 index 00000000000..2591d534377 --- /dev/null +++ b/lib/fpending.c | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | /* fpending.c -- return the number of pending output bytes on a stream | ||
| 2 | Copyright (C) 2000, 2004, 2006-2007, 2009-2012 Free Software Foundation, | ||
| 3 | Inc. | ||
| 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 | /* Written by Jim Meyering. */ | ||
| 19 | |||
| 20 | #include <config.h> | ||
| 21 | |||
| 22 | #include "fpending.h" | ||
| 23 | |||
| 24 | /* Return the number of pending (aka buffered, unflushed) | ||
| 25 | bytes on the stream, FP, that is open for writing. */ | ||
| 26 | size_t | ||
| 27 | __fpending (FILE *fp) | ||
| 28 | { | ||
| 29 | return PENDING_OUTPUT_N_BYTES; | ||
| 30 | } | ||
diff --git a/lib/fpending.h b/lib/fpending.h new file mode 100644 index 00000000000..0365287ba76 --- /dev/null +++ b/lib/fpending.h | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | /* Declare __fpending. | ||
| 2 | |||
| 3 | Copyright (C) 2000, 2003, 2005-2006, 2009-2012 Free Software Foundation, | ||
| 4 | Inc. | ||
| 5 | |||
| 6 | This program is free software: you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 3 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 18 | |||
| 19 | Written by Jim Meyering. */ | ||
| 20 | |||
| 21 | #include <stddef.h> | ||
| 22 | #include <stdio.h> | ||
| 23 | |||
| 24 | #if HAVE_DECL___FPENDING | ||
| 25 | # if HAVE_STDIO_EXT_H | ||
| 26 | # include <stdio_ext.h> | ||
| 27 | # endif | ||
| 28 | #else | ||
| 29 | size_t __fpending (FILE *); | ||
| 30 | #endif | ||
diff --git a/lib/gnulib.mk b/lib/gnulib.mk index 23749331a83..324e5cb78fd 100644 --- a/lib/gnulib.mk +++ b/lib/gnulib.mk | |||
| @@ -21,7 +21,7 @@ | |||
| 21 | # the same distribution terms as the rest of that program. | 21 | # the same distribution terms as the rest of that program. |
| 22 | # | 22 | # |
| 23 | # Generated by gnulib-tool. | 23 | # Generated by gnulib-tool. |
| 24 | # Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=errno --avoid=fcntl --avoid=fcntl-h --avoid=fstat --avoid=msvc-inval --avoid=msvc-nothrow --avoid=raise --avoid=select --avoid=sigprocmask --avoid=sys_types --avoid=threadlib --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt c-ctype c-strcase careadlinkat crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo filemode getloadavg getopt-gnu gettime gettimeofday ignore-value intprops largefile lstat manywarnings mktime pselect pthread_sigmask readlink socklen stat-time stdalign stdarg stdbool stdio strftime strtoimax strtoumax symlink sys_stat sys_time time timer-time timespec-add timespec-sub utimens warnings | 24 | # Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=errno --avoid=fcntl --avoid=fcntl-h --avoid=fstat --avoid=msvc-inval --avoid=msvc-nothrow --avoid=raise --avoid=select --avoid=sigprocmask --avoid=sys_types --avoid=threadlib --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt c-ctype c-strcase careadlinkat close-stream crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo filemode getloadavg getopt-gnu gettime gettimeofday ignore-value intprops largefile lstat manywarnings mktime pselect pthread_sigmask readlink socklen stat-time stdalign stdarg stdbool stdio strftime strtoimax strtoumax symlink sys_stat sys_time time timer-time timespec-add timespec-sub utimens warnings |
| 25 | 25 | ||
| 26 | 26 | ||
| 27 | MOSTLYCLEANFILES += core *.stackdump | 27 | MOSTLYCLEANFILES += core *.stackdump |
| @@ -84,6 +84,14 @@ EXTRA_DIST += careadlinkat.h | |||
| 84 | 84 | ||
| 85 | ## end gnulib module careadlinkat | 85 | ## end gnulib module careadlinkat |
| 86 | 86 | ||
| 87 | ## begin gnulib module close-stream | ||
| 88 | |||
| 89 | libgnu_a_SOURCES += close-stream.c | ||
| 90 | |||
| 91 | EXTRA_DIST += close-stream.h | ||
| 92 | |||
| 93 | ## end gnulib module close-stream | ||
| 94 | |||
| 87 | ## begin gnulib module crypto/md5 | 95 | ## begin gnulib module crypto/md5 |
| 88 | 96 | ||
| 89 | libgnu_a_SOURCES += md5.c | 97 | libgnu_a_SOURCES += md5.c |
| @@ -183,6 +191,15 @@ EXTRA_DIST += filemode.h | |||
| 183 | 191 | ||
| 184 | ## end gnulib module filemode | 192 | ## end gnulib module filemode |
| 185 | 193 | ||
| 194 | ## begin gnulib module fpending | ||
| 195 | |||
| 196 | |||
| 197 | EXTRA_DIST += fpending.c fpending.h | ||
| 198 | |||
| 199 | EXTRA_libgnu_a_SOURCES += fpending.c | ||
| 200 | |||
| 201 | ## end gnulib module fpending | ||
| 202 | |||
| 186 | ## begin gnulib module getloadavg | 203 | ## begin gnulib module getloadavg |
| 187 | 204 | ||
| 188 | 205 | ||
diff --git a/lib/makefile.w32-in b/lib/makefile.w32-in index f0cea56f829..67171e07900 100644 --- a/lib/makefile.w32-in +++ b/lib/makefile.w32-in | |||
| @@ -26,9 +26,11 @@ LIBS = | |||
| 26 | GNULIBOBJS = $(BLD)/c-ctype.$(O) \ | 26 | GNULIBOBJS = $(BLD)/c-ctype.$(O) \ |
| 27 | $(BLD)/c-strcasecmp.$(O) \ | 27 | $(BLD)/c-strcasecmp.$(O) \ |
| 28 | $(BLD)/c-strncasecmp.$(O) \ | 28 | $(BLD)/c-strncasecmp.$(O) \ |
| 29 | $(BLD)/close-stream.$(O) \ | ||
| 29 | $(BLD)/dtoastr.$(O) \ | 30 | $(BLD)/dtoastr.$(O) \ |
| 30 | $(BLD)/dtotimespec.$(O) \ | 31 | $(BLD)/dtotimespec.$(O) \ |
| 31 | $(BLD)/execinfo.$(O) \ | 32 | $(BLD)/execinfo.$(O) \ |
| 33 | $(BLD)/fpending.$(O) \ | ||
| 32 | $(BLD)/getopt.$(O) \ | 34 | $(BLD)/getopt.$(O) \ |
| 33 | $(BLD)/getopt1.$(O) \ | 35 | $(BLD)/getopt1.$(O) \ |
| 34 | $(BLD)/gettime.$(O) \ | 36 | $(BLD)/gettime.$(O) \ |
| @@ -120,6 +122,13 @@ $(BLD)/c-strncasecmp.$(O) : \ | |||
| 120 | $(CONFIG_H) \ | 122 | $(CONFIG_H) \ |
| 121 | $(C_CTYPE_H) | 123 | $(C_CTYPE_H) |
| 122 | 124 | ||
| 125 | $(BLD)/close-stream.$(O) : \ | ||
| 126 | $(GNU_LIB)/close-stream.c \ | ||
| 127 | $(GNU_LIB)/close-stream.h \ | ||
| 128 | $(GNU_LIB)/fpending.h \ | ||
| 129 | $(NT_INC)/stdbool.h \ | ||
| 130 | $(CONFIG_H) | ||
| 131 | |||
| 123 | $(BLD)/dtoastr.$(O) : \ | 132 | $(BLD)/dtoastr.$(O) : \ |
| 124 | $(GNU_LIB)/dtoastr.c \ | 133 | $(GNU_LIB)/dtoastr.c \ |
| 125 | $(FTOASTR_C) | 134 | $(FTOASTR_C) |
| @@ -135,6 +144,11 @@ $(BLD)/execinfo.$(O) : \ | |||
| 135 | $(GNU_LIB)/execinfo.h \ | 144 | $(GNU_LIB)/execinfo.h \ |
| 136 | $(CONFIG_H) | 145 | $(CONFIG_H) |
| 137 | 146 | ||
| 147 | $(BLD)/fpending.$(O) : \ | ||
| 148 | $(GNU_LIB)/fpending.c \ | ||
| 149 | $(GNU_LIB)/fpending.h \ | ||
| 150 | $(CONFIG_H) | ||
| 151 | |||
| 138 | $(BLD)/getopt.$(O) : \ | 152 | $(BLD)/getopt.$(O) : \ |
| 139 | $(GNU_LIB)/getopt.c \ | 153 | $(GNU_LIB)/getopt.c \ |
| 140 | $(GNU_LIB)/getopt.h \ | 154 | $(GNU_LIB)/getopt.h \ |