1 /*-------------------------------------------------------------------------
4 * Front-end large object interface
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/interfaces/libpq/fe-lobj.c
13 *-------------------------------------------------------------------------
18 * As unlink/rename are #define'd in port.h (via postgres_fe.h), io.h
19 * must be included first on MS C. Might as well do it for all WIN32's
25 #include "postgres_fe.h"
38 #include "libpq-int.h"
39 #include "libpq/libpq-fs.h" /* must come after sys/stat.h */
40 #include "port/pg_bswap.h"
42 #define LO_BUFSIZE 8192
44 static int lo_initialize(PGconn
*conn
);
45 static Oid
lo_import_internal(PGconn
*conn
, const char *filename
, Oid oid
);
46 static pg_int64
lo_hton64(pg_int64 host64
);
47 static pg_int64
lo_ntoh64(pg_int64 net64
);
51 * opens an existing large object
53 * returns the file descriptor for use in later lo_* calls
54 * return -1 upon failure.
57 lo_open(PGconn
*conn
, Oid lobjId
, int mode
)
64 if (lo_initialize(conn
) < 0)
69 argv
[0].u
.integer
= lobjId
;
73 argv
[1].u
.integer
= mode
;
75 res
= PQfn(conn
, conn
->lobjfuncs
->fn_lo_open
, &fd
, &result_len
, 1, argv
, 2);
76 if (PQresultStatus(res
) == PGRES_COMMAND_OK
)
90 * closes an existing large object
92 * returns 0 upon success
93 * returns -1 upon failure.
96 lo_close(PGconn
*conn
, int fd
)
103 if (lo_initialize(conn
) < 0)
108 argv
[0].u
.integer
= fd
;
109 res
= PQfn(conn
, conn
->lobjfuncs
->fn_lo_close
,
110 &retval
, &result_len
, 1, argv
, 1);
111 if (PQresultStatus(res
) == PGRES_COMMAND_OK
)
125 * truncates an existing large object to the given size
127 * returns 0 upon success
128 * returns -1 upon failure
131 lo_truncate(PGconn
*conn
, int fd
, size_t len
)
138 if (lo_initialize(conn
) < 0)
141 /* Must check this on-the-fly because it's not there pre-8.3 */
142 if (conn
->lobjfuncs
->fn_lo_truncate
== 0)
144 libpq_append_conn_error(conn
, "cannot determine OID of function %s",
150 * Long ago, somebody thought it'd be a good idea to declare this function
151 * as taking size_t ... but the underlying backend function only accepts a
152 * signed int32 length. So throw error if the given value overflows
153 * int32. (A possible alternative is to automatically redirect the call
154 * to lo_truncate64; but if the caller wanted to rely on that backend
155 * function being available, he could have called lo_truncate64 for
158 if (len
> (size_t) INT_MAX
)
160 libpq_append_conn_error(conn
, "argument of lo_truncate exceeds integer range");
166 argv
[0].u
.integer
= fd
;
170 argv
[1].u
.integer
= (int) len
;
172 res
= PQfn(conn
, conn
->lobjfuncs
->fn_lo_truncate
,
173 &retval
, &result_len
, 1, argv
, 2);
175 if (PQresultStatus(res
) == PGRES_COMMAND_OK
)
189 * truncates an existing large object to the given size
191 * returns 0 upon success
192 * returns -1 upon failure
195 lo_truncate64(PGconn
*conn
, int fd
, pg_int64 len
)
202 if (lo_initialize(conn
) < 0)
205 if (conn
->lobjfuncs
->fn_lo_truncate64
== 0)
207 libpq_append_conn_error(conn
, "cannot determine OID of function %s",
214 argv
[0].u
.integer
= fd
;
216 len
= lo_hton64(len
);
219 argv
[1].u
.ptr
= (int *) &len
;
221 res
= PQfn(conn
, conn
->lobjfuncs
->fn_lo_truncate64
,
222 &retval
, &result_len
, 1, argv
, 2);
224 if (PQresultStatus(res
) == PGRES_COMMAND_OK
)
238 * read len bytes of the large object into buf
240 * returns the number of bytes read, or -1 on failure.
241 * the CALLER must have allocated enough space to hold the result returned
245 lo_read(PGconn
*conn
, int fd
, char *buf
, size_t len
)
251 if (lo_initialize(conn
) < 0)
255 * Long ago, somebody thought it'd be a good idea to declare this function
256 * as taking size_t ... but the underlying backend function only accepts a
257 * signed int32 length. So throw error if the given value overflows
260 if (len
> (size_t) INT_MAX
)
262 libpq_append_conn_error(conn
, "argument of lo_read exceeds integer range");
268 argv
[0].u
.integer
= fd
;
272 argv
[1].u
.integer
= (int) len
;
274 res
= PQfn(conn
, conn
->lobjfuncs
->fn_lo_read
,
275 (void *) buf
, &result_len
, 0, argv
, 2);
276 if (PQresultStatus(res
) == PGRES_COMMAND_OK
)
290 * write len bytes of buf into the large object fd
292 * returns the number of bytes written, or -1 on failure.
295 lo_write(PGconn
*conn
, int fd
, const char *buf
, size_t len
)
302 if (lo_initialize(conn
) < 0)
306 * Long ago, somebody thought it'd be a good idea to declare this function
307 * as taking size_t ... but the underlying backend function only accepts a
308 * signed int32 length. So throw error if the given value overflows
311 if (len
> (size_t) INT_MAX
)
313 libpq_append_conn_error(conn
, "argument of lo_write exceeds integer range");
319 argv
[0].u
.integer
= fd
;
322 argv
[1].len
= (int) len
;
323 argv
[1].u
.ptr
= (int *) unconstify(char *, buf
);
325 res
= PQfn(conn
, conn
->lobjfuncs
->fn_lo_write
,
326 &retval
, &result_len
, 1, argv
, 2);
327 if (PQresultStatus(res
) == PGRES_COMMAND_OK
)
341 * change the current read or write location on a large object
344 lo_lseek(PGconn
*conn
, int fd
, int offset
, int whence
)
351 if (lo_initialize(conn
) < 0)
356 argv
[0].u
.integer
= fd
;
360 argv
[1].u
.integer
= offset
;
364 argv
[2].u
.integer
= whence
;
366 res
= PQfn(conn
, conn
->lobjfuncs
->fn_lo_lseek
,
367 &retval
, &result_len
, 1, argv
, 3);
368 if (PQresultStatus(res
) == PGRES_COMMAND_OK
)
382 * change the current read or write location on a large object
385 lo_lseek64(PGconn
*conn
, int fd
, pg_int64 offset
, int whence
)
392 if (lo_initialize(conn
) < 0)
395 if (conn
->lobjfuncs
->fn_lo_lseek64
== 0)
397 libpq_append_conn_error(conn
, "cannot determine OID of function %s",
404 argv
[0].u
.integer
= fd
;
406 offset
= lo_hton64(offset
);
409 argv
[1].u
.ptr
= (int *) &offset
;
413 argv
[2].u
.integer
= whence
;
415 res
= PQfn(conn
, conn
->lobjfuncs
->fn_lo_lseek64
,
416 (void *) &retval
, &result_len
, 0, argv
, 3);
417 if (PQresultStatus(res
) == PGRES_COMMAND_OK
&& result_len
== 8)
420 return lo_ntoh64(retval
);
431 * create a new large object
432 * the mode is ignored (once upon a time it had a use)
434 * returns the oid of the large object created or
435 * InvalidOid upon failure
438 lo_creat(PGconn
*conn
, int mode
)
445 if (lo_initialize(conn
) < 0)
450 argv
[0].u
.integer
= mode
;
451 res
= PQfn(conn
, conn
->lobjfuncs
->fn_lo_creat
,
452 &retval
, &result_len
, 1, argv
, 1);
453 if (PQresultStatus(res
) == PGRES_COMMAND_OK
)
467 * create a new large object
468 * if lobjId isn't InvalidOid, it specifies the OID to (attempt to) create
470 * returns the oid of the large object created or
471 * InvalidOid upon failure
474 lo_create(PGconn
*conn
, Oid lobjId
)
481 if (lo_initialize(conn
) < 0)
484 /* Must check this on-the-fly because it's not there pre-8.1 */
485 if (conn
->lobjfuncs
->fn_lo_create
== 0)
487 libpq_append_conn_error(conn
, "cannot determine OID of function %s",
494 argv
[0].u
.integer
= lobjId
;
495 res
= PQfn(conn
, conn
->lobjfuncs
->fn_lo_create
,
496 &retval
, &result_len
, 1, argv
, 1);
497 if (PQresultStatus(res
) == PGRES_COMMAND_OK
)
512 * returns the current seek location of the large object
515 lo_tell(PGconn
*conn
, int fd
)
522 if (lo_initialize(conn
) < 0)
527 argv
[0].u
.integer
= fd
;
529 res
= PQfn(conn
, conn
->lobjfuncs
->fn_lo_tell
,
530 &retval
, &result_len
, 1, argv
, 1);
531 if (PQresultStatus(res
) == PGRES_COMMAND_OK
)
545 * returns the current seek location of the large object
548 lo_tell64(PGconn
*conn
, int fd
)
555 if (lo_initialize(conn
) < 0)
558 if (conn
->lobjfuncs
->fn_lo_tell64
== 0)
560 libpq_append_conn_error(conn
, "cannot determine OID of function %s",
567 argv
[0].u
.integer
= fd
;
569 res
= PQfn(conn
, conn
->lobjfuncs
->fn_lo_tell64
,
570 (void *) &retval
, &result_len
, 0, argv
, 1);
571 if (PQresultStatus(res
) == PGRES_COMMAND_OK
&& result_len
== 8)
574 return lo_ntoh64(retval
);
589 lo_unlink(PGconn
*conn
, Oid lobjId
)
596 if (lo_initialize(conn
) < 0)
601 argv
[0].u
.integer
= lobjId
;
603 res
= PQfn(conn
, conn
->lobjfuncs
->fn_lo_unlink
,
604 &retval
, &result_len
, 1, argv
, 1);
605 if (PQresultStatus(res
) == PGRES_COMMAND_OK
)
619 * imports a file as an (inversion) large object.
621 * returns the oid of that object upon success,
622 * returns InvalidOid upon failure
626 lo_import(PGconn
*conn
, const char *filename
)
628 return lo_import_internal(conn
, filename
, InvalidOid
);
632 * lo_import_with_oid -
633 * imports a file as an (inversion) large object.
634 * large object id can be specified.
636 * returns the oid of that object upon success,
637 * returns InvalidOid upon failure
641 lo_import_with_oid(PGconn
*conn
, const char *filename
, Oid lobjId
)
643 return lo_import_internal(conn
, filename
, lobjId
);
647 lo_import_internal(PGconn
*conn
, const char *filename
, Oid oid
)
652 char buf
[LO_BUFSIZE
];
655 char sebuf
[PG_STRERROR_R_BUFLEN
];
660 /* Since this is the beginning of a query cycle, reset the error state */
661 pqClearConnErrorState(conn
);
664 * open the file to be read in
666 fd
= open(filename
, O_RDONLY
| PG_BINARY
, 0666);
669 libpq_append_conn_error(conn
, "could not open file \"%s\": %s",
670 filename
, strerror_r(errno
, sebuf
, sizeof(sebuf
)));
675 * create an inversion object
677 if (oid
== InvalidOid
)
678 lobjOid
= lo_creat(conn
, INV_READ
| INV_WRITE
);
680 lobjOid
= lo_create(conn
, oid
);
682 if (lobjOid
== InvalidOid
)
684 /* we assume lo_create() already set a suitable error message */
689 lobj
= lo_open(conn
, lobjOid
, INV_WRITE
);
692 /* we assume lo_open() already set a suitable error message */
698 * read in from the file and write to the large object
700 while ((nbytes
= read(fd
, buf
, LO_BUFSIZE
)) > 0)
702 tmp
= lo_write(conn
, lobj
, buf
, nbytes
);
706 * If lo_write() failed, we are now in an aborted transaction so
707 * there's no need for lo_close(); furthermore, if we tried it
708 * we'd overwrite the useful error result with a useless one. So
709 * just nail the doors shut and get out of town.
718 /* We must do lo_close before setting the errorMessage */
719 int save_errno
= errno
;
721 (void) lo_close(conn
, lobj
);
723 /* deliberately overwrite any error from lo_close */
724 pqClearConnErrorState(conn
);
725 libpq_append_conn_error(conn
, "could not read from file \"%s\": %s",
727 strerror_r(save_errno
, sebuf
, sizeof(sebuf
)));
733 if (lo_close(conn
, lobj
) != 0)
735 /* we assume lo_close() already set a suitable error message */
744 * exports an (inversion) large object.
745 * returns -1 upon failure, 1 if OK
748 lo_export(PGconn
*conn
, Oid lobjId
, const char *filename
)
754 char buf
[LO_BUFSIZE
];
756 char sebuf
[PG_STRERROR_R_BUFLEN
];
759 * open the large object.
761 lobj
= lo_open(conn
, lobjId
, INV_READ
);
764 /* we assume lo_open() already set a suitable error message */
769 * create the file to be written to
771 fd
= open(filename
, O_CREAT
| O_WRONLY
| O_TRUNC
| PG_BINARY
, 0666);
774 /* We must do lo_close before setting the errorMessage */
775 int save_errno
= errno
;
777 (void) lo_close(conn
, lobj
);
778 /* deliberately overwrite any error from lo_close */
779 pqClearConnErrorState(conn
);
780 libpq_append_conn_error(conn
, "could not open file \"%s\": %s",
782 strerror_r(save_errno
, sebuf
, sizeof(sebuf
)));
787 * read in from the large object and write to the file
789 while ((nbytes
= lo_read(conn
, lobj
, buf
, LO_BUFSIZE
)) > 0)
791 tmp
= write(fd
, buf
, nbytes
);
794 /* We must do lo_close before setting the errorMessage */
795 int save_errno
= errno
;
797 (void) lo_close(conn
, lobj
);
799 /* deliberately overwrite any error from lo_close */
800 pqClearConnErrorState(conn
);
801 libpq_append_conn_error(conn
, "could not write to file \"%s\": %s",
803 strerror_r(save_errno
, sebuf
, sizeof(sebuf
)));
809 * If lo_read() failed, we are now in an aborted transaction so there's no
810 * need for lo_close(); furthermore, if we tried it we'd overwrite the
811 * useful error result with a useless one. So skip lo_close() if we got a
815 lo_close(conn
, lobj
) != 0)
817 /* assume lo_read() or lo_close() left a suitable error message */
821 /* if we already failed, don't overwrite that msg with a close error */
822 if (close(fd
) != 0 && result
>= 0)
824 libpq_append_conn_error(conn
, "could not write to file \"%s\": %s",
825 filename
, strerror_r(errno
, sebuf
, sizeof(sebuf
)));
836 * Initialize for a new large-object operation on an existing connection.
837 * Return 0 if OK, -1 on failure.
839 * If we haven't previously done so, we collect the function OIDs from
840 * pg_proc for all functions that are required for large object operations.
843 lo_initialize(PGconn
*conn
)
846 PGlobjfuncs
*lobjfuncs
;
852 /* Nothing we can do with no connection */
856 /* Since this is the beginning of a query cycle, reset the error state */
857 pqClearConnErrorState(conn
);
859 /* Nothing else to do if we already collected info */
860 if (conn
->lobjfuncs
!= NULL
)
864 * Allocate the structure to hold the function OIDs. We don't store it
865 * into the PGconn until it's successfully filled.
867 lobjfuncs
= (PGlobjfuncs
*) malloc(sizeof(PGlobjfuncs
));
868 if (lobjfuncs
== NULL
)
870 libpq_append_conn_error(conn
, "out of memory");
873 MemSet((char *) lobjfuncs
, 0, sizeof(PGlobjfuncs
));
876 * Execute the query to get all the functions at once. (Not all of them
877 * may exist in older server versions.)
879 query
= "select proname, oid from pg_catalog.pg_proc "
894 "and pronamespace = (select oid from pg_catalog.pg_namespace "
895 "where nspname = 'pg_catalog')";
897 res
= PQexec(conn
, query
);
904 if (res
->resultStatus
!= PGRES_TUPLES_OK
)
908 libpq_append_conn_error(conn
, "query to initialize large object functions did not return data");
913 * Examine the result and put the OID's into the struct
915 for (n
= 0; n
< PQntuples(res
); n
++)
917 fname
= PQgetvalue(res
, n
, 0);
918 foid
= (Oid
) atoi(PQgetvalue(res
, n
, 1));
919 if (strcmp(fname
, "lo_open") == 0)
920 lobjfuncs
->fn_lo_open
= foid
;
921 else if (strcmp(fname
, "lo_close") == 0)
922 lobjfuncs
->fn_lo_close
= foid
;
923 else if (strcmp(fname
, "lo_creat") == 0)
924 lobjfuncs
->fn_lo_creat
= foid
;
925 else if (strcmp(fname
, "lo_create") == 0)
926 lobjfuncs
->fn_lo_create
= foid
;
927 else if (strcmp(fname
, "lo_unlink") == 0)
928 lobjfuncs
->fn_lo_unlink
= foid
;
929 else if (strcmp(fname
, "lo_lseek") == 0)
930 lobjfuncs
->fn_lo_lseek
= foid
;
931 else if (strcmp(fname
, "lo_lseek64") == 0)
932 lobjfuncs
->fn_lo_lseek64
= foid
;
933 else if (strcmp(fname
, "lo_tell") == 0)
934 lobjfuncs
->fn_lo_tell
= foid
;
935 else if (strcmp(fname
, "lo_tell64") == 0)
936 lobjfuncs
->fn_lo_tell64
= foid
;
937 else if (strcmp(fname
, "lo_truncate") == 0)
938 lobjfuncs
->fn_lo_truncate
= foid
;
939 else if (strcmp(fname
, "lo_truncate64") == 0)
940 lobjfuncs
->fn_lo_truncate64
= foid
;
941 else if (strcmp(fname
, "loread") == 0)
942 lobjfuncs
->fn_lo_read
= foid
;
943 else if (strcmp(fname
, "lowrite") == 0)
944 lobjfuncs
->fn_lo_write
= foid
;
950 * Finally check that we got all required large object interface functions
951 * (ones that have been added later than the stone age are instead checked
954 if (lobjfuncs
->fn_lo_open
== 0)
956 libpq_append_conn_error(conn
, "cannot determine OID of function %s",
961 if (lobjfuncs
->fn_lo_close
== 0)
963 libpq_append_conn_error(conn
, "cannot determine OID of function %s",
968 if (lobjfuncs
->fn_lo_creat
== 0)
970 libpq_append_conn_error(conn
, "cannot determine OID of function %s",
975 if (lobjfuncs
->fn_lo_unlink
== 0)
977 libpq_append_conn_error(conn
, "cannot determine OID of function %s",
982 if (lobjfuncs
->fn_lo_lseek
== 0)
984 libpq_append_conn_error(conn
, "cannot determine OID of function %s",
989 if (lobjfuncs
->fn_lo_tell
== 0)
991 libpq_append_conn_error(conn
, "cannot determine OID of function %s",
996 if (lobjfuncs
->fn_lo_read
== 0)
998 libpq_append_conn_error(conn
, "cannot determine OID of function %s",
1003 if (lobjfuncs
->fn_lo_write
== 0)
1005 libpq_append_conn_error(conn
, "cannot determine OID of function %s",
1012 * Put the structure into the connection control
1014 conn
->lobjfuncs
= lobjfuncs
;
1020 * converts a 64-bit integer from host byte order to network byte order
1023 lo_hton64(pg_int64 host64
)
1032 /* High order half first, since we're doing MSB-first */
1033 t
= (uint32
) (host64
>> 32);
1034 swap
.i32
[0] = pg_hton32(t
);
1036 /* Now the low order half */
1037 t
= (uint32
) host64
;
1038 swap
.i32
[1] = pg_hton32(t
);
1045 * converts a 64-bit integer from network byte order to host byte order
1048 lo_ntoh64(pg_int64 net64
)
1059 result
= (uint32
) pg_ntoh32(swap
.i32
[0]);
1061 result
|= (uint32
) pg_ntoh32(swap
.i32
[1]);