Skip to content

Commit c5b8daa

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 cf9d992 commit c5b8daa

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
@@ -569,10 +569,16 @@ lo_import_internal(PGconn *conn, const char *filename, Oid oid)
569569

570570
if (nbytes < 0)
571571
{
572+
/* We must do lo_close before setting the errorMessage */
573+
int save_errno = errno;
574+
575+
(void) lo_close(conn, lobj);
576+
(void) close(fd);
572577
printfPQExpBuffer(&conn->errorMessage,
573578
libpq_gettext("could not read from file \"%s\": %s\n"),
574-
filename, pqStrerror(errno, sebuf, sizeof(sebuf)));
575-
lobjOid = InvalidOid;
579+
filename,
580+
pqStrerror(save_errno, sebuf, sizeof(sebuf)));
581+
return InvalidOid;
576582
}
577583

578584
(void) close(fd);
@@ -617,11 +623,15 @@ lo_export(PGconn *conn, Oid lobjId, const char *filename)
617623
*/
618624
fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC | PG_BINARY, 0666);
619625
if (fd < 0)
620-
{ /* error */
626+
{
627+
/* We must do lo_close before setting the errorMessage */
628+
int save_errno = errno;
629+
630+
(void) lo_close(conn, lobj);
621631
printfPQExpBuffer(&conn->errorMessage,
622632
libpq_gettext("could not open file \"%s\": %s\n"),
623-
filename, pqStrerror(errno, sebuf, sizeof(sebuf)));
624-
(void) lo_close(conn, lobj);
633+
filename,
634+
pqStrerror(save_errno, sebuf, sizeof(sebuf)));
625635
return -1;
626636
}
627637

@@ -633,11 +643,15 @@ lo_export(PGconn *conn, Oid lobjId, const char *filename)
633643
tmp = write(fd, buf, nbytes);
634644
if (tmp != nbytes)
635645
{
636-
printfPQExpBuffer(&conn->errorMessage,
637-
libpq_gettext("could not write to file \"%s\": %s\n"),
638-
filename, pqStrerror(errno, sebuf, sizeof(sebuf)));
646+
/* We must do lo_close before setting the errorMessage */
647+
int save_errno = errno;
648+
639649
(void) lo_close(conn, lobj);
640650
(void) close(fd);
651+
printfPQExpBuffer(&conn->errorMessage,
652+
libpq_gettext("could not write to file \"%s\": %s\n"),
653+
filename,
654+
pqStrerror(save_errno, sebuf, sizeof(sebuf)));
641655
return -1;
642656
}
643657
}
@@ -655,7 +669,8 @@ lo_export(PGconn *conn, Oid lobjId, const char *filename)
655669
result = -1;
656670
}
657671

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

0 commit comments

Comments
 (0)