postgres.git / summary / log / commit / refs

commit    9d8bc2f0aeaa7f7fceb393fe5740cb709c0f27e7
Author:   Tom Lane <tgl@sss.pgh.pa.us>
Date:     Thu May 16 19:04:46 2013 +0000
First released in: 9.3.0, 8.4.18, 9.0.14, 9.1.10, 9.2.5

    Fix fd.c to preserve errno where needed.
    
    PathNameOpenFile failed to ensure that the correct value of errno was
    returned to its caller after a failure (because it incorrectly supposed
    that free() can never change errno).  In some cases this would result
    in a user-visible failure because an expected ENOENT errno was replaced
    with something else.  Bogus EINVAL failures have been observed on OS X,
    for example.
    
    There were also a couple of places that could mangle an important value
    of errno if FDDEBUG was defined.  While the usefulness of that debug
    support is highly debatable, we might as well make it safe to use,
    so add errno save/restore logic to the DO_DB macro.
    
    Per bug #8167 from Nelson Minar, diagnosed by RhodiumToad.
    Back-patch to all supported branches.


src/backend/storage/file/fd.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c index 387092724d2..107907daa8c 100644 --- a/src/backend/storage/file/fd.c +++ b/src/backend/storage/file/fd.c @@ -108,9 +108,15 @@ static int max_safe_fds = 32; /* default if not changed */ /* Debugging.... */ #ifdef FDDEBUG -#define DO_DB(A) A +#define DO_DB(A) \ + do { \ + int _do_db_save_errno = errno; \ + A; \ + errno = _do_db_save_errno; \ + } while (0) #else -#define DO_DB(A) /* A */ +#define DO_DB(A) \ + ((void) 0) #endif #define VFD_CLOSED (-1) @@ -664,7 +670,7 @@ LruInsert(File file) if (vfdP->fd < 0) { DO_DB(elog(LOG, "RE_OPEN FAILED: %d", errno)); - return vfdP->fd; + return -1; } else { @@ -715,7 +721,7 @@ AllocateVfd(void) Index i; File file; - DO_DB(elog(LOG, "AllocateVfd. Size %lu", SizeVfdCache)); + DO_DB(elog(LOG, "AllocateVfd. Size %lu", (unsigned long) SizeVfdCache)); Assert(SizeVfdCache > 0); /* InitFileAccess not called? */ @@ -872,8 +878,11 @@ PathNameOpenFile(FileName fileName, int fileFlags, int fileMode) if (vfdP->fd < 0) { + int save_errno = errno; + FreeVfd(file); free(fnamecopy); + errno = save_errno; return -1; } ++nfile; [parent: ee249498a99a]