Skip to content

Commit 875406a

Browse files
committed
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.
1 parent 1e9d798 commit 875406a

File tree

1 file changed

+24
-9
lines changed

1 file changed

+24
-9
lines changed

src/interfaces/libpq/fe-lobj.c

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -571,10 +571,16 @@ lo_import_internal(PGconn *conn, const char *filename, const Oid oid)
571571

572572
if (nbytes < 0)
573573
{
574+
/* We must do lo_close before setting the errorMessage */
575+
int save_errno = errno;
576+
577+
(void) lo_close(conn, lobj);
578+
(void) close(fd);
574579
printfPQExpBuffer(&conn->errorMessage,
575580
libpq_gettext("could not read from file \"%s\": %s\n"),
576-
filename, pqStrerror(errno, sebuf, sizeof(sebuf)));
577-
lobjOid = InvalidOid;
581+
filename,
582+
pqStrerror(save_errno, sebuf, sizeof(sebuf)));
583+
return InvalidOid;
578584
}
579585

580586
(void) close(fd);
@@ -619,11 +625,15 @@ lo_export(PGconn *conn, Oid lobjId, const char *filename)
619625
*/
620626
fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC | PG_BINARY, 0666);
621627
if (fd < 0)
622-
{ /* error */
628+
{
629+
/* We must do lo_close before setting the errorMessage */
630+
int save_errno = errno;
631+
632+
(void) lo_close(conn, lobj);
623633
printfPQExpBuffer(&conn->errorMessage,
624634
libpq_gettext("could not open file \"%s\": %s\n"),
625-
filename, pqStrerror(errno, sebuf, sizeof(sebuf)));
626-
(void) lo_close(conn, lobj);
635+
filename,
636+
pqStrerror(save_errno, sebuf, sizeof(sebuf)));
627637
return -1;
628638
}
629639

@@ -635,11 +645,15 @@ lo_export(PGconn *conn, Oid lobjId, const char *filename)
635645
tmp = write(fd, buf, nbytes);
636646
if (tmp != nbytes)
637647
{
638-
printfPQExpBuffer(&conn->errorMessage,
639-
libpq_gettext("could not write to file \"%s\": %s\n"),
640-
filename, pqStrerror(errno, sebuf, sizeof(sebuf)));
648+
/* We must do lo_close before setting the errorMessage */
649+
int save_errno = errno;
650+
641651
(void) lo_close(conn, lobj);
642652
(void) close(fd);
653+
printfPQExpBuffer(&conn->errorMessage,
654+
libpq_gettext("could not write to file \"%s\": %s\n"),
655+
filename,
656+
pqStrerror(save_errno, sebuf, sizeof(sebuf)));
643657
return -1;
644658
}
645659
}
@@ -657,7 +671,8 @@ lo_export(PGconn *conn, Oid lobjId, const char *filename)
657671
result = -1;
658672
}
659673

660-
if (close(fd))
674+
/* if we already failed, don't overwrite that msg with a close error */
675+
if (close(fd) && result >= 0)
661676
{
662677
printfPQExpBuffer(&conn->errorMessage,
663678
libpq_gettext("could not write to file \"%s\": %s\n"),

0 commit comments

Comments
 (0)