postgres.git / summary / log / commit / refs

commit    bb3aa7a484a53d80784c367e2ff272b8730e338d
Author:   Tom Lane <tgl@sss.pgh.pa.us>
Date:     Tue Oct 09 01:52:48 2012 +0000
First released in: 9.3.0, 8.3.22, 8.4.15, 9.0.11, 9.1.7, 9.2.2

    Fix lo_import and lo_export to return useful error messages more often.
    
    I found that these functions tend to return -1 while leaving an empty error
    message string in the PGconn, if they suffer some kind of I/O error on the
    file.  The reason is that lo_close, which thinks it's executed a perfectly
    fine SQL command, clears the errorMessage.  The minimum-change workaround
    is to reorder operations here so that we don't fill the errorMessage until
    after lo_close.


src/interfaces/libpq/fe-lobj.c | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/interfaces/libpq/fe-lobj.c b/src/interfaces/libpq/fe-lobj.c index 27f93e6af78..b7e79942051 100644 --- a/src/interfaces/libpq/fe-lobj.c +++ b/src/interfaces/libpq/fe-lobj.c @@ -571,10 +571,16 @@ lo_import_internal(PGconn *conn, const char *filename, const Oid oid) if (nbytes < 0) { + /* We must do lo_close before setting the errorMessage */ + int save_errno = errno; + + (void) lo_close(conn, lobj); + (void) close(fd); printfPQExpBuffer(&conn->errorMessage, libpq_gettext("could not read from file \"%s\": %s\n"), - filename, pqStrerror(errno, sebuf, sizeof(sebuf))); - lobjOid = InvalidOid; + filename, + pqStrerror(save_errno, sebuf, sizeof(sebuf))); + return InvalidOid; } (void) close(fd); @@ -619,11 +625,15 @@ lo_export(PGconn *conn, Oid lobjId, const char *filename) */ fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC | PG_BINARY, 0666); if (fd < 0) - { /* error */ + { + /* We must do lo_close before setting the errorMessage */ + int save_errno = errno; + + (void) lo_close(conn, lobj); printfPQExpBuffer(&conn->errorMessage, libpq_gettext("could not open file \"%s\": %s\n"), - filename, pqStrerror(errno, sebuf, sizeof(sebuf))); - (void) lo_close(conn, lobj); + filename, + pqStrerror(save_errno, sebuf, sizeof(sebuf))); return -1; } @@ -635,11 +645,15 @@ lo_export(PGconn *conn, Oid lobjId, const char *filename) tmp = write(fd, buf, nbytes); if (tmp != nbytes) { - printfPQExpBuffer(&conn->errorMessage, - libpq_gettext("could not write to file \"%s\": %s\n"), - filename, pqStrerror(errno, sebuf, sizeof(sebuf))); + /* We must do lo_close before setting the errorMessage */ + int save_errno = errno; + (void) lo_close(conn, lobj); (void) close(fd); + printfPQExpBuffer(&conn->errorMessage, + libpq_gettext("could not write to file \"%s\": %s\n"), + filename, + pqStrerror(save_errno, sebuf, sizeof(sebuf))); return -1; } } @@ -657,7 +671,8 @@ lo_export(PGconn *conn, Oid lobjId, const char *filename) result = -1; } - if (close(fd)) + /* if we already failed, don't overwrite that msg with a close error */ + if (close(fd) && result >= 0) { printfPQExpBuffer(&conn->errorMessage, libpq_gettext("could not write to file \"%s\": %s\n"), [parent: a883c02449cf]