PostgreSQL Source Code  git master
fe-lobj.c File Reference
#include "postgres_fe.h"
#include <unistd.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/stat.h>
#include "libpq-fe.h"
#include "libpq-int.h"
#include "libpq/libpq-fs.h"
#include "port/pg_bswap.h"
Include dependency graph for fe-lobj.c:

Go to the source code of this file.

Macros

#define LO_BUFSIZE   8192
 

Functions

static int lo_initialize (PGconn *conn)
 
static Oid lo_import_internal (PGconn *conn, const char *filename, Oid oid)
 
static pg_int64 lo_hton64 (pg_int64 host64)
 
static pg_int64 lo_ntoh64 (pg_int64 net64)
 
int lo_open (PGconn *conn, Oid lobjId, int mode)
 
int lo_close (PGconn *conn, int fd)
 
int lo_truncate (PGconn *conn, int fd, size_t len)
 
int lo_truncate64 (PGconn *conn, int fd, pg_int64 len)
 
int lo_read (PGconn *conn, int fd, char *buf, size_t len)
 
int lo_write (PGconn *conn, int fd, const char *buf, size_t len)
 
int lo_lseek (PGconn *conn, int fd, int offset, int whence)
 
pg_int64 lo_lseek64 (PGconn *conn, int fd, pg_int64 offset, int whence)
 
Oid lo_creat (PGconn *conn, int mode)
 
Oid lo_create (PGconn *conn, Oid lobjId)
 
int lo_tell (PGconn *conn, int fd)
 
pg_int64 lo_tell64 (PGconn *conn, int fd)
 
int lo_unlink (PGconn *conn, Oid lobjId)
 
Oid lo_import (PGconn *conn, const char *filename)
 
Oid lo_import_with_oid (PGconn *conn, const char *filename, Oid lobjId)
 
int lo_export (PGconn *conn, Oid lobjId, const char *filename)
 

Macro Definition Documentation

◆ LO_BUFSIZE

#define LO_BUFSIZE   8192

Definition at line 42 of file fe-lobj.c.

Function Documentation

◆ lo_close()

int lo_close ( PGconn conn,
int  fd 
)

Definition at line 96 of file fe-lobj.c.

97 {
98  PQArgBlock argv[1];
99  PGresult *res;
100  int retval;
101  int result_len;
102 
103  if (lo_initialize(conn) < 0)
104  return -1;
105 
106  argv[0].isint = 1;
107  argv[0].len = 4;
108  argv[0].u.integer = fd;
110  &retval, &result_len, 1, argv, 1);
112  {
113  PQclear(res);
114  return retval;
115  }
116  else
117  {
118  PQclear(res);
119  return -1;
120  }
121 }
PGresult * PQfn(PGconn *conn, int fnid, int *result_buf, int *result_len, int result_is_int, const PQArgBlock *args, int nargs)
Definition: fe-exec.c:2980
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3411
static int lo_initialize(PGconn *conn)
Definition: fe-lobj.c:843
@ PGRES_COMMAND_OK
Definition: libpq-fe.h:120
static int fd(const char *x, int i)
Definition: preproc-init.c:105
PGconn * conn
Definition: streamutil.c:53
int isint
Definition: libpq-fe.h:281
union PQArgBlock::@183 u
int integer
Definition: libpq-fe.h:285
Oid fn_lo_close
Definition: libpq-int.h:287
PGlobjfuncs * lobjfuncs
Definition: libpq-int.h:531

References conn, fd(), pgLobjfuncs::fn_lo_close, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), res, and PQArgBlock::u.

Referenced by dumpLOs(), EndRestoreLO(), exportFile(), importFile(), lo_export(), lo_import_internal(), my_truncate(), overwrite(), and pickout().

◆ lo_creat()

Oid lo_creat ( PGconn conn,
int  mode 
)

Definition at line 438 of file fe-lobj.c.

439 {
440  PQArgBlock argv[1];
441  PGresult *res;
442  int retval;
443  int result_len;
444 
445  if (lo_initialize(conn) < 0)
446  return InvalidOid;
447 
448  argv[0].isint = 1;
449  argv[0].len = 4;
450  argv[0].u.integer = mode;
452  &retval, &result_len, 1, argv, 1);
454  {
455  PQclear(res);
456  return (Oid) retval;
457  }
458  else
459  {
460  PQclear(res);
461  return InvalidOid;
462  }
463 }
static PgChecksumMode mode
Definition: pg_checksums.c:55
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
Oid fn_lo_creat
Definition: libpq-int.h:288

References conn, pgLobjfuncs::fn_lo_creat, PQArgBlock::integer, InvalidOid, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, mode, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), res, and PQArgBlock::u.

Referenced by importFile(), and lo_import_internal().

◆ lo_create()

Oid lo_create ( PGconn conn,
Oid  lobjId 
)

Definition at line 474 of file fe-lobj.c.

475 {
476  PQArgBlock argv[1];
477  PGresult *res;
478  int retval;
479  int result_len;
480 
481  if (lo_initialize(conn) < 0)
482  return InvalidOid;
483 
484  /* Must check this on-the-fly because it's not there pre-8.1 */
485  if (conn->lobjfuncs->fn_lo_create == 0)
486  {
487  libpq_append_conn_error(conn, "cannot determine OID of function %s",
488  "lo_create");
489  return InvalidOid;
490  }
491 
492  argv[0].isint = 1;
493  argv[0].len = 4;
494  argv[0].u.integer = lobjId;
496  &retval, &result_len, 1, argv, 1);
498  {
499  PQclear(res);
500  return (Oid) retval;
501  }
502  else
503  {
504  PQclear(res);
505  return InvalidOid;
506  }
507 }
void libpq_append_conn_error(PGconn *conn, const char *fmt,...)
Definition: fe-misc.c:1372
Oid fn_lo_create
Definition: libpq-int.h:289

References conn, pgLobjfuncs::fn_lo_create, PQArgBlock::integer, InvalidOid, PQArgBlock::isint, PQArgBlock::len, libpq_append_conn_error(), lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), res, and PQArgBlock::u.

Referenced by lo_import_internal(), and StartRestoreLO().

◆ lo_export()

int lo_export ( PGconn conn,
Oid  lobjId,
const char *  filename 
)

Definition at line 748 of file fe-lobj.c.

749 {
750  int result = 1;
751  int fd;
752  int nbytes,
753  tmp;
754  char buf[LO_BUFSIZE];
755  int lobj;
756  char sebuf[PG_STRERROR_R_BUFLEN];
757 
758  /*
759  * open the large object.
760  */
761  lobj = lo_open(conn, lobjId, INV_READ);
762  if (lobj == -1)
763  {
764  /* we assume lo_open() already set a suitable error message */
765  return -1;
766  }
767 
768  /*
769  * create the file to be written to
770  */
771  fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC | PG_BINARY, 0666);
772  if (fd < 0)
773  {
774  /* We must do lo_close before setting the errorMessage */
775  int save_errno = errno;
776 
777  (void) lo_close(conn, lobj);
778  /* deliberately overwrite any error from lo_close */
780  libpq_append_conn_error(conn, "could not open file \"%s\": %s",
781  filename,
782  strerror_r(save_errno, sebuf, sizeof(sebuf)));
783  return -1;
784  }
785 
786  /*
787  * read in from the large object and write to the file
788  */
789  while ((nbytes = lo_read(conn, lobj, buf, LO_BUFSIZE)) > 0)
790  {
791  tmp = write(fd, buf, nbytes);
792  if (tmp != nbytes)
793  {
794  /* We must do lo_close before setting the errorMessage */
795  int save_errno = errno;
796 
797  (void) lo_close(conn, lobj);
798  (void) close(fd);
799  /* deliberately overwrite any error from lo_close */
801  libpq_append_conn_error(conn, "could not write to file \"%s\": %s",
802  filename,
803  strerror_r(save_errno, sebuf, sizeof(sebuf)));
804  return -1;
805  }
806  }
807 
808  /*
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
812  * failure result.
813  */
814  if (nbytes < 0 ||
815  lo_close(conn, lobj) != 0)
816  {
817  /* assume lo_read() or lo_close() left a suitable error message */
818  result = -1;
819  }
820 
821  /* if we already failed, don't overwrite that msg with a close error */
822  if (close(fd) != 0 && result >= 0)
823  {
824  libpq_append_conn_error(conn, "could not write to file \"%s\": %s",
825  filename, strerror_r(errno, sebuf, sizeof(sebuf)));
826  result = -1;
827  }
828 
829  return result;
830 }
#define PG_BINARY
Definition: c.h:1252
int lo_close(PGconn *conn, int fd)
Definition: fe-lobj.c:96
#define LO_BUFSIZE
Definition: fe-lobj.c:42
int lo_read(PGconn *conn, int fd, char *buf, size_t len)
Definition: fe-lobj.c:245
int lo_open(PGconn *conn, Oid lobjId, int mode)
Definition: fe-lobj.c:57
#define close(a)
Definition: win32.h:12
#define write(a, b, c)
Definition: win32.h:14
#define INV_READ
Definition: libpq-fs.h:22
#define pqClearConnErrorState(conn)
Definition: libpq-int.h:879
static char * filename
Definition: pg_dumpall.c:119
static char * buf
Definition: pg_test_fsync.c:72
#define PG_STRERROR_R_BUFLEN
Definition: port.h:256
#define strerror_r
Definition: port.h:255

References buf, close, conn, fd(), filename, INV_READ, libpq_append_conn_error(), LO_BUFSIZE, lo_close(), lo_open(), lo_read(), PG_BINARY, PG_STRERROR_R_BUFLEN, pqClearConnErrorState, strerror_r, and write.

Referenced by do_lo_export(), and main().

◆ lo_hton64()

static pg_int64 lo_hton64 ( pg_int64  host64)
static

Definition at line 1023 of file fe-lobj.c.

1024 {
1025  union
1026  {
1027  pg_int64 i64;
1028  uint32 i32[2];
1029  } swap;
1030  uint32 t;
1031 
1032  /* High order half first, since we're doing MSB-first */
1033  t = (uint32) (host64 >> 32);
1034  swap.i32[0] = pg_hton32(t);
1035 
1036  /* Now the low order half */
1037  t = (uint32) host64;
1038  swap.i32[1] = pg_hton32(t);
1039 
1040  return swap.i64;
1041 }
unsigned int uint32
Definition: c.h:492
#define pg_hton32(x)
Definition: pg_bswap.h:121
PG_INT64_TYPE pg_int64
Definition: postgres_ext.h:47

References pg_hton32.

Referenced by lo_lseek64(), and lo_truncate64().

◆ lo_import()

Oid lo_import ( PGconn conn,
const char *  filename 
)

Definition at line 626 of file fe-lobj.c.

627 {
629 }
static Oid lo_import_internal(PGconn *conn, const char *filename, Oid oid)
Definition: fe-lobj.c:647

References conn, filename, InvalidOid, and lo_import_internal().

Referenced by do_lo_import(), and main().

◆ lo_import_internal()

static Oid lo_import_internal ( PGconn conn,
const char *  filename,
Oid  oid 
)
static

Definition at line 647 of file fe-lobj.c.

648 {
649  int fd;
650  int nbytes,
651  tmp;
652  char buf[LO_BUFSIZE];
653  Oid lobjOid;
654  int lobj;
655  char sebuf[PG_STRERROR_R_BUFLEN];
656 
657  if (conn == NULL)
658  return InvalidOid;
659 
660  /* Since this is the beginning of a query cycle, reset the error state */
662 
663  /*
664  * open the file to be read in
665  */
666  fd = open(filename, O_RDONLY | PG_BINARY, 0666);
667  if (fd < 0)
668  { /* error */
669  libpq_append_conn_error(conn, "could not open file \"%s\": %s",
670  filename, strerror_r(errno, sebuf, sizeof(sebuf)));
671  return InvalidOid;
672  }
673 
674  /*
675  * create an inversion object
676  */
677  if (oid == InvalidOid)
678  lobjOid = lo_creat(conn, INV_READ | INV_WRITE);
679  else
680  lobjOid = lo_create(conn, oid);
681 
682  if (lobjOid == InvalidOid)
683  {
684  /* we assume lo_create() already set a suitable error message */
685  (void) close(fd);
686  return InvalidOid;
687  }
688 
689  lobj = lo_open(conn, lobjOid, INV_WRITE);
690  if (lobj == -1)
691  {
692  /* we assume lo_open() already set a suitable error message */
693  (void) close(fd);
694  return InvalidOid;
695  }
696 
697  /*
698  * read in from the file and write to the large object
699  */
700  while ((nbytes = read(fd, buf, LO_BUFSIZE)) > 0)
701  {
702  tmp = lo_write(conn, lobj, buf, nbytes);
703  if (tmp != nbytes)
704  {
705  /*
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.
710  */
711  (void) close(fd);
712  return InvalidOid;
713  }
714  }
715 
716  if (nbytes < 0)
717  {
718  /* We must do lo_close before setting the errorMessage */
719  int save_errno = errno;
720 
721  (void) lo_close(conn, lobj);
722  (void) close(fd);
723  /* deliberately overwrite any error from lo_close */
725  libpq_append_conn_error(conn, "could not read from file \"%s\": %s",
726  filename,
727  strerror_r(save_errno, sebuf, sizeof(sebuf)));
728  return InvalidOid;
729  }
730 
731  (void) close(fd);
732 
733  if (lo_close(conn, lobj) != 0)
734  {
735  /* we assume lo_close() already set a suitable error message */
736  return InvalidOid;
737  }
738 
739  return lobjOid;
740 }
Oid lo_creat(PGconn *conn, int mode)
Definition: fe-lobj.c:438
int lo_write(PGconn *conn, int fd, const char *buf, size_t len)
Definition: fe-lobj.c:295
Oid lo_create(PGconn *conn, Oid lobjId)
Definition: fe-lobj.c:474
#define read(a, b, c)
Definition: win32.h:13
#define INV_WRITE
Definition: libpq-fs.h:21

References buf, close, conn, fd(), filename, INV_READ, INV_WRITE, InvalidOid, libpq_append_conn_error(), LO_BUFSIZE, lo_close(), lo_creat(), lo_create(), lo_open(), lo_write(), PG_BINARY, PG_STRERROR_R_BUFLEN, pqClearConnErrorState, read, and strerror_r.

Referenced by lo_import(), and lo_import_with_oid().

◆ lo_import_with_oid()

Oid lo_import_with_oid ( PGconn conn,
const char *  filename,
Oid  lobjId 
)

Definition at line 641 of file fe-lobj.c.

642 {
643  return lo_import_internal(conn, filename, lobjId);
644 }

References conn, filename, and lo_import_internal().

◆ lo_initialize()

static int lo_initialize ( PGconn conn)
static

Definition at line 843 of file fe-lobj.c.

844 {
845  PGresult *res;
846  PGlobjfuncs *lobjfuncs;
847  int n;
848  const char *query;
849  const char *fname;
850  Oid foid;
851 
852  /* Nothing we can do with no connection */
853  if (conn == NULL)
854  return -1;
855 
856  /* Since this is the beginning of a query cycle, reset the error state */
858 
859  /* Nothing else to do if we already collected info */
860  if (conn->lobjfuncs != NULL)
861  return 0;
862 
863  /*
864  * Allocate the structure to hold the function OIDs. We don't store it
865  * into the PGconn until it's successfully filled.
866  */
867  lobjfuncs = (PGlobjfuncs *) malloc(sizeof(PGlobjfuncs));
868  if (lobjfuncs == NULL)
869  {
870  libpq_append_conn_error(conn, "out of memory");
871  return -1;
872  }
873  MemSet((char *) lobjfuncs, 0, sizeof(PGlobjfuncs));
874 
875  /*
876  * Execute the query to get all the functions at once. (Not all of them
877  * may exist in older server versions.)
878  */
879  query = "select proname, oid from pg_catalog.pg_proc "
880  "where proname in ("
881  "'lo_open', "
882  "'lo_close', "
883  "'lo_creat', "
884  "'lo_create', "
885  "'lo_unlink', "
886  "'lo_lseek', "
887  "'lo_lseek64', "
888  "'lo_tell', "
889  "'lo_tell64', "
890  "'lo_truncate', "
891  "'lo_truncate64', "
892  "'loread', "
893  "'lowrite') "
894  "and pronamespace = (select oid from pg_catalog.pg_namespace "
895  "where nspname = 'pg_catalog')";
896 
897  res = PQexec(conn, query);
898  if (res == NULL)
899  {
900  free(lobjfuncs);
901  return -1;
902  }
903 
905  {
906  free(lobjfuncs);
907  PQclear(res);
908  libpq_append_conn_error(conn, "query to initialize large object functions did not return data");
909  return -1;
910  }
911 
912  /*
913  * Examine the result and put the OID's into the struct
914  */
915  for (n = 0; n < PQntuples(res); n++)
916  {
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;
945  }
946 
947  PQclear(res);
948 
949  /*
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
952  * only if used)
953  */
954  if (lobjfuncs->fn_lo_open == 0)
955  {
956  libpq_append_conn_error(conn, "cannot determine OID of function %s",
957  "lo_open");
958  free(lobjfuncs);
959  return -1;
960  }
961  if (lobjfuncs->fn_lo_close == 0)
962  {
963  libpq_append_conn_error(conn, "cannot determine OID of function %s",
964  "lo_close");
965  free(lobjfuncs);
966  return -1;
967  }
968  if (lobjfuncs->fn_lo_creat == 0)
969  {
970  libpq_append_conn_error(conn, "cannot determine OID of function %s",
971  "lo_creat");
972  free(lobjfuncs);
973  return -1;
974  }
975  if (lobjfuncs->fn_lo_unlink == 0)
976  {
977  libpq_append_conn_error(conn, "cannot determine OID of function %s",
978  "lo_unlink");
979  free(lobjfuncs);
980  return -1;
981  }
982  if (lobjfuncs->fn_lo_lseek == 0)
983  {
984  libpq_append_conn_error(conn, "cannot determine OID of function %s",
985  "lo_lseek");
986  free(lobjfuncs);
987  return -1;
988  }
989  if (lobjfuncs->fn_lo_tell == 0)
990  {
991  libpq_append_conn_error(conn, "cannot determine OID of function %s",
992  "lo_tell");
993  free(lobjfuncs);
994  return -1;
995  }
996  if (lobjfuncs->fn_lo_read == 0)
997  {
998  libpq_append_conn_error(conn, "cannot determine OID of function %s",
999  "loread");
1000  free(lobjfuncs);
1001  return -1;
1002  }
1003  if (lobjfuncs->fn_lo_write == 0)
1004  {
1005  libpq_append_conn_error(conn, "cannot determine OID of function %s",
1006  "lowrite");
1007  free(lobjfuncs);
1008  return -1;
1009  }
1010 
1011  /*
1012  * Put the structure into the connection control
1013  */
1014  conn->lobjfuncs = lobjfuncs;
1015  return 0;
1016 }
#define MemSet(start, val, len)
Definition: c.h:999
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3481
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:2262
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3876
#define free(a)
Definition: header.h:65
#define malloc(a)
Definition: header.h:50
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:76
@ PGRES_TUPLES_OK
Definition: libpq-fe.h:123
ExecStatusType resultStatus
Definition: libpq-int.h:180

References conn, pgLobjfuncs::fn_lo_close, pgLobjfuncs::fn_lo_creat, pgLobjfuncs::fn_lo_create, pgLobjfuncs::fn_lo_lseek, pgLobjfuncs::fn_lo_lseek64, pgLobjfuncs::fn_lo_open, pgLobjfuncs::fn_lo_read, pgLobjfuncs::fn_lo_tell, pgLobjfuncs::fn_lo_tell64, pgLobjfuncs::fn_lo_truncate, pgLobjfuncs::fn_lo_truncate64, pgLobjfuncs::fn_lo_unlink, pgLobjfuncs::fn_lo_write, free, if(), libpq_append_conn_error(), pg_conn::lobjfuncs, malloc, MemSet, PGRES_TUPLES_OK, PQclear(), pqClearConnErrorState, PQexec(), PQgetvalue(), PQntuples(), res, and pg_result::resultStatus.

Referenced by lo_close(), lo_creat(), lo_create(), lo_lseek(), lo_lseek64(), lo_open(), lo_read(), lo_tell(), lo_tell64(), lo_truncate(), lo_truncate64(), lo_unlink(), and lo_write().

◆ lo_lseek()

int lo_lseek ( PGconn conn,
int  fd,
int  offset,
int  whence 
)

Definition at line 344 of file fe-lobj.c.

345 {
346  PQArgBlock argv[3];
347  PGresult *res;
348  int retval;
349  int result_len;
350 
351  if (lo_initialize(conn) < 0)
352  return -1;
353 
354  argv[0].isint = 1;
355  argv[0].len = 4;
356  argv[0].u.integer = fd;
357 
358  argv[1].isint = 1;
359  argv[1].len = 4;
360  argv[1].u.integer = offset;
361 
362  argv[2].isint = 1;
363  argv[2].len = 4;
364  argv[2].u.integer = whence;
365 
367  &retval, &result_len, 1, argv, 3);
369  {
370  PQclear(res);
371  return retval;
372  }
373  else
374  {
375  PQclear(res);
376  return -1;
377  }
378 }
Oid fn_lo_lseek
Definition: libpq-int.h:291

References conn, fd(), pgLobjfuncs::fn_lo_lseek, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), res, and PQArgBlock::u.

Referenced by overwrite(), and pickout().

◆ lo_lseek64()

pg_int64 lo_lseek64 ( PGconn conn,
int  fd,
pg_int64  offset,
int  whence 
)

Definition at line 385 of file fe-lobj.c.

386 {
387  PQArgBlock argv[3];
388  PGresult *res;
389  pg_int64 retval;
390  int result_len;
391 
392  if (lo_initialize(conn) < 0)
393  return -1;
394 
395  if (conn->lobjfuncs->fn_lo_lseek64 == 0)
396  {
397  libpq_append_conn_error(conn, "cannot determine OID of function %s",
398  "lo_lseek64");
399  return -1;
400  }
401 
402  argv[0].isint = 1;
403  argv[0].len = 4;
404  argv[0].u.integer = fd;
405 
406  offset = lo_hton64(offset);
407  argv[1].isint = 0;
408  argv[1].len = 8;
409  argv[1].u.ptr = (int *) &offset;
410 
411  argv[2].isint = 1;
412  argv[2].len = 4;
413  argv[2].u.integer = whence;
414 
416  (void *) &retval, &result_len, 0, argv, 3);
417  if (PQresultStatus(res) == PGRES_COMMAND_OK && result_len == 8)
418  {
419  PQclear(res);
420  return lo_ntoh64(retval);
421  }
422  else
423  {
424  PQclear(res);
425  return -1;
426  }
427 }
static pg_int64 lo_ntoh64(pg_int64 net64)
Definition: fe-lobj.c:1048
static pg_int64 lo_hton64(pg_int64 host64)
Definition: fe-lobj.c:1023
int * ptr
Definition: libpq-fe.h:284
Oid fn_lo_lseek64
Definition: libpq-int.h:292

References conn, fd(), pgLobjfuncs::fn_lo_lseek64, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, libpq_append_conn_error(), lo_hton64(), lo_initialize(), lo_ntoh64(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), PQArgBlock::ptr, res, and PQArgBlock::u.

Referenced by overwrite(), and pickout().

◆ lo_ntoh64()

static pg_int64 lo_ntoh64 ( pg_int64  net64)
static

Definition at line 1048 of file fe-lobj.c.

1049 {
1050  union
1051  {
1052  pg_int64 i64;
1053  uint32 i32[2];
1054  } swap;
1055  pg_int64 result;
1056 
1057  swap.i64 = net64;
1058 
1059  result = (uint32) pg_ntoh32(swap.i32[0]);
1060  result <<= 32;
1061  result |= (uint32) pg_ntoh32(swap.i32[1]);
1062 
1063  return result;
1064 }
#define pg_ntoh32(x)
Definition: pg_bswap.h:125

References pg_ntoh32.

Referenced by lo_lseek64(), and lo_tell64().

◆ lo_open()

int lo_open ( PGconn conn,
Oid  lobjId,
int  mode 
)

Definition at line 57 of file fe-lobj.c.

58 {
59  int fd;
60  int result_len;
61  PQArgBlock argv[2];
62  PGresult *res;
63 
64  if (lo_initialize(conn) < 0)
65  return -1;
66 
67  argv[0].isint = 1;
68  argv[0].len = 4;
69  argv[0].u.integer = lobjId;
70 
71  argv[1].isint = 1;
72  argv[1].len = 4;
73  argv[1].u.integer = mode;
74 
75  res = PQfn(conn, conn->lobjfuncs->fn_lo_open, &fd, &result_len, 1, argv, 2);
77  {
78  PQclear(res);
79  return fd;
80  }
81  else
82  {
83  PQclear(res);
84  return -1;
85  }
86 }
Oid fn_lo_open
Definition: libpq-int.h:286

References conn, fd(), pgLobjfuncs::fn_lo_open, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, mode, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), res, and PQArgBlock::u.

Referenced by dumpLOs(), exportFile(), importFile(), lo_export(), lo_import_internal(), my_truncate(), overwrite(), pickout(), and StartRestoreLO().

◆ lo_read()

int lo_read ( PGconn conn,
int  fd,
char *  buf,
size_t  len 
)

Definition at line 245 of file fe-lobj.c.

246 {
247  PQArgBlock argv[2];
248  PGresult *res;
249  int result_len;
250 
251  if (lo_initialize(conn) < 0)
252  return -1;
253 
254  /*
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
258  * int32.
259  */
260  if (len > (size_t) INT_MAX)
261  {
262  libpq_append_conn_error(conn, "argument of lo_read exceeds integer range");
263  return -1;
264  }
265 
266  argv[0].isint = 1;
267  argv[0].len = 4;
268  argv[0].u.integer = fd;
269 
270  argv[1].isint = 1;
271  argv[1].len = 4;
272  argv[1].u.integer = (int) len;
273 
275  (void *) buf, &result_len, 0, argv, 2);
277  {
278  PQclear(res);
279  return result_len;
280  }
281  else
282  {
283  PQclear(res);
284  return -1;
285  }
286 }
const void size_t len
Oid fn_lo_read
Definition: libpq-int.h:297

References buf, conn, fd(), pgLobjfuncs::fn_lo_read, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, len, libpq_append_conn_error(), lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), res, and PQArgBlock::u.

Referenced by lo_export().

◆ lo_tell()

int lo_tell ( PGconn conn,
int  fd 
)

Definition at line 515 of file fe-lobj.c.

516 {
517  int retval;
518  PQArgBlock argv[1];
519  PGresult *res;
520  int result_len;
521 
522  if (lo_initialize(conn) < 0)
523  return -1;
524 
525  argv[0].isint = 1;
526  argv[0].len = 4;
527  argv[0].u.integer = fd;
528 
530  &retval, &result_len, 1, argv, 1);
532  {
533  PQclear(res);
534  return retval;
535  }
536  else
537  {
538  PQclear(res);
539  return -1;
540  }
541 }
Oid fn_lo_tell
Definition: libpq-int.h:293

References conn, fd(), pgLobjfuncs::fn_lo_tell, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), res, and PQArgBlock::u.

◆ lo_tell64()

pg_int64 lo_tell64 ( PGconn conn,
int  fd 
)

Definition at line 548 of file fe-lobj.c.

549 {
550  pg_int64 retval;
551  PQArgBlock argv[1];
552  PGresult *res;
553  int result_len;
554 
555  if (lo_initialize(conn) < 0)
556  return -1;
557 
558  if (conn->lobjfuncs->fn_lo_tell64 == 0)
559  {
560  libpq_append_conn_error(conn, "cannot determine OID of function %s",
561  "lo_tell64");
562  return -1;
563  }
564 
565  argv[0].isint = 1;
566  argv[0].len = 4;
567  argv[0].u.integer = fd;
568 
570  (void *) &retval, &result_len, 0, argv, 1);
571  if (PQresultStatus(res) == PGRES_COMMAND_OK && result_len == 8)
572  {
573  PQclear(res);
574  return lo_ntoh64(retval);
575  }
576  else
577  {
578  PQclear(res);
579  return -1;
580  }
581 }
Oid fn_lo_tell64
Definition: libpq-int.h:294

References conn, fd(), pgLobjfuncs::fn_lo_tell64, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, libpq_append_conn_error(), lo_initialize(), lo_ntoh64(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), res, and PQArgBlock::u.

Referenced by pickout().

◆ lo_truncate()

int lo_truncate ( PGconn conn,
int  fd,
size_t  len 
)

Definition at line 131 of file fe-lobj.c.

132 {
133  PQArgBlock argv[2];
134  PGresult *res;
135  int retval;
136  int result_len;
137 
138  if (lo_initialize(conn) < 0)
139  return -1;
140 
141  /* Must check this on-the-fly because it's not there pre-8.3 */
142  if (conn->lobjfuncs->fn_lo_truncate == 0)
143  {
144  libpq_append_conn_error(conn, "cannot determine OID of function %s",
145  "lo_truncate");
146  return -1;
147  }
148 
149  /*
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
156  * himself.)
157  */
158  if (len > (size_t) INT_MAX)
159  {
160  libpq_append_conn_error(conn, "argument of lo_truncate exceeds integer range");
161  return -1;
162  }
163 
164  argv[0].isint = 1;
165  argv[0].len = 4;
166  argv[0].u.integer = fd;
167 
168  argv[1].isint = 1;
169  argv[1].len = 4;
170  argv[1].u.integer = (int) len;
171 
173  &retval, &result_len, 1, argv, 2);
174 
176  {
177  PQclear(res);
178  return retval;
179  }
180  else
181  {
182  PQclear(res);
183  return -1;
184  }
185 }
Oid fn_lo_truncate
Definition: libpq-int.h:295

References conn, fd(), pgLobjfuncs::fn_lo_truncate, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, len, libpq_append_conn_error(), lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), res, and PQArgBlock::u.

◆ lo_truncate64()

int lo_truncate64 ( PGconn conn,
int  fd,
pg_int64  len 
)

Definition at line 195 of file fe-lobj.c.

196 {
197  PQArgBlock argv[2];
198  PGresult *res;
199  int retval;
200  int result_len;
201 
202  if (lo_initialize(conn) < 0)
203  return -1;
204 
205  if (conn->lobjfuncs->fn_lo_truncate64 == 0)
206  {
207  libpq_append_conn_error(conn, "cannot determine OID of function %s",
208  "lo_truncate64");
209  return -1;
210  }
211 
212  argv[0].isint = 1;
213  argv[0].len = 4;
214  argv[0].u.integer = fd;
215 
216  len = lo_hton64(len);
217  argv[1].isint = 0;
218  argv[1].len = 8;
219  argv[1].u.ptr = (int *) &len;
220 
222  &retval, &result_len, 1, argv, 2);
223 
225  {
226  PQclear(res);
227  return retval;
228  }
229  else
230  {
231  PQclear(res);
232  return -1;
233  }
234 }
Oid fn_lo_truncate64
Definition: libpq-int.h:296

References conn, fd(), pgLobjfuncs::fn_lo_truncate64, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, len, libpq_append_conn_error(), lo_hton64(), lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), PQArgBlock::ptr, res, and PQArgBlock::u.

Referenced by my_truncate().

◆ lo_unlink()

int lo_unlink ( PGconn conn,
Oid  lobjId 
)

Definition at line 589 of file fe-lobj.c.

590 {
591  PQArgBlock argv[1];
592  PGresult *res;
593  int result_len;
594  int retval;
595 
596  if (lo_initialize(conn) < 0)
597  return -1;
598 
599  argv[0].isint = 1;
600  argv[0].len = 4;
601  argv[0].u.integer = lobjId;
602 
604  &retval, &result_len, 1, argv, 1);
606  {
607  PQclear(res);
608  return retval;
609  }
610  else
611  {
612  PQclear(res);
613  return -1;
614  }
615 }
Oid fn_lo_unlink
Definition: libpq-int.h:290

References conn, pgLobjfuncs::fn_lo_unlink, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), res, and PQArgBlock::u.

Referenced by do_lo_unlink(), and vacuumlo().

◆ lo_write()

int lo_write ( PGconn conn,
int  fd,
const char *  buf,
size_t  len 
)

Definition at line 295 of file fe-lobj.c.

296 {
297  PQArgBlock argv[2];
298  PGresult *res;
299  int result_len;
300  int retval;
301 
302  if (lo_initialize(conn) < 0)
303  return -1;
304 
305  /*
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
309  * int32.
310  */
311  if (len > (size_t) INT_MAX)
312  {
313  libpq_append_conn_error(conn, "argument of lo_write exceeds integer range");
314  return -1;
315  }
316 
317  argv[0].isint = 1;
318  argv[0].len = 4;
319  argv[0].u.integer = fd;
320 
321  argv[1].isint = 0;
322  argv[1].len = (int) len;
323  argv[1].u.ptr = (int *) unconstify(char *, buf);
324 
326  &retval, &result_len, 1, argv, 2);
328  {
329  PQclear(res);
330  return retval;
331  }
332  else
333  {
334  PQclear(res);
335  return -1;
336  }
337 }
#define unconstify(underlying_type, expr)
Definition: c.h:1224
Oid fn_lo_write
Definition: libpq-int.h:298

References buf, conn, fd(), pgLobjfuncs::fn_lo_write, PQArgBlock::integer, PQArgBlock::isint, PQArgBlock::len, len, libpq_append_conn_error(), lo_initialize(), pg_conn::lobjfuncs, PGRES_COMMAND_OK, PQclear(), PQfn(), PQresultStatus(), PQArgBlock::ptr, res, PQArgBlock::u, and unconstify.

Referenced by lo_import_internal().