mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	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.
This commit is contained in:
		@@ -569,10 +569,16 @@ lo_import_internal(PGconn *conn, const char *filename, 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);
 | 
			
		||||
@@ -617,11 +623,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;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -633,11 +643,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;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -655,7 +669,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"),
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user