diff options
Diffstat (limited to 'src/backend/storage/file/fd.c')
-rw-r--r-- | src/backend/storage/file/fd.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c index 827a1e2620b..9e596e7868b 100644 --- a/src/backend/storage/file/fd.c +++ b/src/backend/storage/file/fd.c @@ -2279,11 +2279,16 @@ OpenTransientFilePerm(const char *fileName, int fileFlags, mode_t fileMode) * Routines that want to initiate a pipe stream should use OpenPipeStream * rather than plain popen(). This lets fd.c deal with freeing FDs if * necessary. When done, call ClosePipeStream rather than pclose. + * + * This function also ensures that the popen'd program is run with default + * SIGPIPE processing, rather than the SIG_IGN setting the backend normally + * uses. This ensures desirable response to, eg, closing a read pipe early. */ FILE * OpenPipeStream(const char *command, const char *mode) { FILE *file; + int save_errno; DO_DB(elog(LOG, "OpenPipeStream: Allocated %d (%s)", numAllocatedDescs, command)); @@ -2301,8 +2306,13 @@ OpenPipeStream(const char *command, const char *mode) TryAgain: fflush(stdout); fflush(stderr); + pqsignal(SIGPIPE, SIG_DFL); errno = 0; - if ((file = popen(command, mode)) != NULL) + file = popen(command, mode); + save_errno = errno; + pqsignal(SIGPIPE, SIG_IGN); + errno = save_errno; + if (file != NULL) { AllocateDesc *desc = &allocatedDescs[numAllocatedDescs]; @@ -2315,12 +2325,9 @@ TryAgain: if (errno == EMFILE || errno == ENFILE) { - int save_errno = errno; - ereport(LOG, (errcode(ERRCODE_INSUFFICIENT_RESOURCES), errmsg("out of file descriptors: %m; release and retry"))); - errno = 0; if (ReleaseLruFile()) goto TryAgain; errno = save_errno; |