#include "postgres.h"
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include "libpq/be-fsstubs.h"
#include "libpq/libpq-fs.h"
#include "miscadmin.h"
#include "storage/fd.h"
#include "storage/large_object.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/memutils.h"
Go to the source code of this file.
Defines | |
#define | BUFSIZE 8192 |
#define | CreateFSContext() |
Functions | |
static int | newLOfd (LargeObjectDesc *lobjCookie) |
static void | deleteLOfd (int fd) |
static Oid | lo_import_internal (text *filename, Oid lobjOid) |
Datum | lo_open (PG_FUNCTION_ARGS) |
Datum | lo_close (PG_FUNCTION_ARGS) |
int | lo_read (int fd, char *buf, int len) |
int | lo_write (int fd, const char *buf, int len) |
Datum | lo_lseek (PG_FUNCTION_ARGS) |
Datum | lo_lseek64 (PG_FUNCTION_ARGS) |
Datum | lo_creat (PG_FUNCTION_ARGS) |
Datum | lo_create (PG_FUNCTION_ARGS) |
Datum | lo_tell (PG_FUNCTION_ARGS) |
Datum | lo_tell64 (PG_FUNCTION_ARGS) |
Datum | lo_unlink (PG_FUNCTION_ARGS) |
Datum | loread (PG_FUNCTION_ARGS) |
Datum | lowrite (PG_FUNCTION_ARGS) |
Datum | lo_import (PG_FUNCTION_ARGS) |
Datum | lo_import_with_oid (PG_FUNCTION_ARGS) |
Datum | lo_export (PG_FUNCTION_ARGS) |
static void | lo_truncate_internal (int32 fd, int64 len) |
Datum | lo_truncate (PG_FUNCTION_ARGS) |
Datum | lo_truncate64 (PG_FUNCTION_ARGS) |
void | AtEOXact_LargeObject (bool isCommit) |
void | AtEOSubXact_LargeObject (bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid) |
Variables | |
bool | lo_compat_privileges |
static LargeObjectDesc ** | cookies = NULL |
static int | cookies_size = 0 |
static MemoryContext | fscxt = NULL |
#define BUFSIZE 8192 |
Definition at line 62 of file be-fsstubs.c.
Referenced by lo_export(), and lo_import_internal().
#define CreateFSContext | ( | ) |
do { \ if (fscxt == NULL) \ fscxt = AllocSetContextCreate(TopMemoryContext, \ "Filesystem", \ ALLOCSET_DEFAULT_MINSIZE, \ ALLOCSET_DEFAULT_INITSIZE, \ ALLOCSET_DEFAULT_MAXSIZE); \ } while (0)
Definition at line 77 of file be-fsstubs.c.
Referenced by lo_creat(), lo_create(), lo_export(), lo_import_internal(), and lo_open().
void AtEOSubXact_LargeObject | ( | bool | isCommit, | |
SubTransactionId | mySubid, | |||
SubTransactionId | parentSubid | |||
) |
Definition at line 676 of file be-fsstubs.c.
References cookies_size, deleteLOfd(), i, inv_close(), NULL, and LargeObjectDesc::subid.
Referenced by AbortSubTransaction(), and CommitSubTransaction().
{ int i; if (fscxt == NULL) /* no LO operations in this xact */ return; for (i = 0; i < cookies_size; i++) { LargeObjectDesc *lo = cookies[i]; if (lo != NULL && lo->subid == mySubid) { if (isCommit) lo->subid = parentSubid; else { /* * Make sure we do not call inv_close twice if it errors out * for some reason. Better a leak than a crash. */ deleteLOfd(i); inv_close(lo); } } } }
void AtEOXact_LargeObject | ( | bool | isCommit | ) |
Definition at line 635 of file be-fsstubs.c.
References close_lo_relation(), cookies_size, deleteLOfd(), i, inv_close(), MemoryContextDelete(), and NULL.
Referenced by AbortTransaction(), CommitTransaction(), and PrepareTransaction().
{ int i; if (fscxt == NULL) return; /* no LO operations in this xact */ /* * Close LO fds and clear cookies array so that LO fds are no longer good. * On abort we skip the close step. */ for (i = 0; i < cookies_size; i++) { if (cookies[i] != NULL) { if (isCommit) inv_close(cookies[i]); deleteLOfd(i); } } /* Needn't actually pfree since we're about to zap context */ cookies = NULL; cookies_size = 0; /* Release the LO memory context to prevent permanent memory leaks. */ MemoryContextDelete(fscxt); fscxt = NULL; /* Give inv_api.c a chance to clean up, too */ close_lo_relation(isCommit); }
static void deleteLOfd | ( | int | fd | ) | [static] |
Definition at line 753 of file be-fsstubs.c.
Referenced by AtEOSubXact_LargeObject(), AtEOXact_LargeObject(), lo_close(), and lo_unlink().
{ cookies[fd] = NULL; }
Datum lo_close | ( | PG_FUNCTION_ARGS | ) |
Definition at line 127 of file be-fsstubs.c.
References cookies_size, DEBUG4, deleteLOfd(), elog, ereport, errcode(), errmsg(), ERROR, fd(), inv_close(), NULL, PG_GETARG_INT32, and PG_RETURN_INT32.
Referenced by dumpBlobs(), EndRestoreBlob(), exportFile(), importFile(), lo_export(), lo_import_internal(), my_truncate(), overwrite(), and pickout().
{ int32 fd = PG_GETARG_INT32(0); if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("invalid large-object descriptor: %d", fd))); #if FSDB elog(DEBUG4, "lo_close(%d)", fd); #endif inv_close(cookies[fd]); deleteLOfd(fd); PG_RETURN_INT32(0); }
Datum lo_creat | ( | PG_FUNCTION_ARGS | ) |
Definition at line 272 of file be-fsstubs.c.
References CreateFSContext, inv_create(), InvalidOid, and PG_RETURN_OID.
Referenced by importFile(), and lo_import_internal().
{ Oid lobjId; /* * We don't actually need to store into fscxt, but create it anyway to * ensure that AtEOXact_LargeObject knows there is state to clean up */ CreateFSContext(); lobjId = inv_create(InvalidOid); PG_RETURN_OID(lobjId); }
Datum lo_create | ( | PG_FUNCTION_ARGS | ) |
Definition at line 288 of file be-fsstubs.c.
References CreateFSContext, inv_create(), PG_GETARG_OID, and PG_RETURN_OID.
Referenced by lo_import_internal(), and StartRestoreBlob().
{ Oid lobjId = PG_GETARG_OID(0); /* * We don't actually need to store into fscxt, but create it anyway to * ensure that AtEOXact_LargeObject knows there is state to clean up */ CreateFSContext(); lobjId = inv_create(lobjId); PG_RETURN_OID(lobjId); }
Datum lo_export | ( | PG_FUNCTION_ARGS | ) |
Definition at line 507 of file be-fsstubs.c.
References buf, BUFSIZE, CloseTransientFile(), CreateFSContext, ereport, errcode(), errcode_for_file_access(), errhint(), errmsg(), ERROR, filename, inv_close(), inv_open(), inv_read(), INV_READ, OpenTransientFile(), PG_BINARY, PG_GETARG_OID, PG_GETARG_TEXT_PP, PG_RETURN_INT32, S_IRGRP, S_IROTH, S_IWGRP, S_IWOTH, superuser(), text_to_cstring_buffer(), and write.
Referenced by do_lo_export(), and main().
{ Oid lobjId = PG_GETARG_OID(0); text *filename = PG_GETARG_TEXT_PP(1); int fd; int nbytes, tmp; char buf[BUFSIZE]; char fnamebuf[MAXPGPATH]; LargeObjectDesc *lobj; mode_t oumask; #ifndef ALLOW_DANGEROUS_LO_FUNCTIONS if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser to use server-side lo_export()"), errhint("Anyone can use the client-side lo_export() provided by libpq."))); #endif CreateFSContext(); /* * open the inversion object (no need to test for failure) */ lobj = inv_open(lobjId, INV_READ, fscxt); /* * open the file to be written to * * Note: we reduce backend's normal 077 umask to the slightly friendlier * 022. This code used to drop it all the way to 0, but creating * world-writable export files doesn't seem wise. */ text_to_cstring_buffer(filename, fnamebuf, sizeof(fnamebuf)); oumask = umask(S_IWGRP | S_IWOTH); fd = OpenTransientFile(fnamebuf, O_CREAT | O_WRONLY | O_TRUNC | PG_BINARY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); umask(oumask); if (fd < 0) ereport(ERROR, (errcode_for_file_access(), errmsg("could not create server file \"%s\": %m", fnamebuf))); /* * read in from the inversion file and write to the filesystem */ while ((nbytes = inv_read(lobj, buf, BUFSIZE)) > 0) { tmp = write(fd, buf, nbytes); if (tmp != nbytes) ereport(ERROR, (errcode_for_file_access(), errmsg("could not write server file \"%s\": %m", fnamebuf))); } CloseTransientFile(fd); inv_close(lobj); PG_RETURN_INT32(1); }
Datum lo_import | ( | PG_FUNCTION_ARGS | ) |
Definition at line 422 of file be-fsstubs.c.
References filename, InvalidOid, lo_import_internal(), PG_GETARG_TEXT_PP, and PG_RETURN_OID.
Referenced by do_lo_import(), and main().
{ text *filename = PG_GETARG_TEXT_PP(0); PG_RETURN_OID(lo_import_internal(filename, InvalidOid)); }
Definition at line 443 of file be-fsstubs.c.
References Assert, buf, BUFSIZE, CloseTransientFile(), CreateFSContext, ereport, errcode(), errcode_for_file_access(), errhint(), errmsg(), ERROR, inv_close(), inv_create(), inv_open(), inv_write(), INV_WRITE, OpenTransientFile(), PG_BINARY, read, superuser(), and text_to_cstring_buffer().
Referenced by lo_import(), and lo_import_with_oid().
{ int fd; int nbytes, tmp PG_USED_FOR_ASSERTS_ONLY; char buf[BUFSIZE]; char fnamebuf[MAXPGPATH]; LargeObjectDesc *lobj; Oid oid; #ifndef ALLOW_DANGEROUS_LO_FUNCTIONS if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser to use server-side lo_import()"), errhint("Anyone can use the client-side lo_import() provided by libpq."))); #endif CreateFSContext(); /* * open the file to be read in */ text_to_cstring_buffer(filename, fnamebuf, sizeof(fnamebuf)); fd = OpenTransientFile(fnamebuf, O_RDONLY | PG_BINARY, S_IRWXU); if (fd < 0) ereport(ERROR, (errcode_for_file_access(), errmsg("could not open server file \"%s\": %m", fnamebuf))); /* * create an inversion object */ oid = inv_create(lobjOid); /* * read in from the filesystem and write to the inversion object */ lobj = inv_open(oid, INV_WRITE, fscxt); while ((nbytes = read(fd, buf, BUFSIZE)) > 0) { tmp = inv_write(lobj, buf, nbytes); Assert(tmp == nbytes); } if (nbytes < 0) ereport(ERROR, (errcode_for_file_access(), errmsg("could not read server file \"%s\": %m", fnamebuf))); inv_close(lobj); CloseTransientFile(fd); return oid; }
Datum lo_import_with_oid | ( | PG_FUNCTION_ARGS | ) |
Definition at line 434 of file be-fsstubs.c.
References filename, lo_import_internal(), PG_GETARG_OID, PG_GETARG_TEXT_PP, and PG_RETURN_OID.
{ text *filename = PG_GETARG_TEXT_PP(0); Oid oid = PG_GETARG_OID(1); PG_RETURN_OID(lo_import_internal(filename, oid)); }
Datum lo_lseek | ( | PG_FUNCTION_ARGS | ) |
Definition at line 229 of file be-fsstubs.c.
References cookies_size, ereport, errcode(), errmsg(), ERROR, fd(), inv_seek(), NULL, PG_GETARG_INT32, and PG_RETURN_INT32.
Referenced by overwrite(), and pickout().
{ int32 fd = PG_GETARG_INT32(0); int32 offset = PG_GETARG_INT32(1); int32 whence = PG_GETARG_INT32(2); int64 status; if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("invalid large-object descriptor: %d", fd))); status = inv_seek(cookies[fd], offset, whence); /* guard against result overflow */ if (status != (int32) status) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("lo_lseek result out of range for large-object descriptor %d", fd))); PG_RETURN_INT32((int32) status); }
Datum lo_lseek64 | ( | PG_FUNCTION_ARGS | ) |
Definition at line 254 of file be-fsstubs.c.
References cookies_size, ereport, errcode(), errmsg(), ERROR, fd(), inv_seek(), NULL, PG_GETARG_INT32, PG_GETARG_INT64, and PG_RETURN_INT64.
Referenced by overwrite(), and pickout().
{ int32 fd = PG_GETARG_INT32(0); int64 offset = PG_GETARG_INT64(1); int32 whence = PG_GETARG_INT32(2); int64 status; if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("invalid large-object descriptor: %d", fd))); status = inv_seek(cookies[fd], offset, whence); PG_RETURN_INT64(status); }
Datum lo_open | ( | PG_FUNCTION_ARGS | ) |
Definition at line 98 of file be-fsstubs.c.
References CreateFSContext, DEBUG4, elog, inv_open(), newLOfd(), NULL, PG_GETARG_INT32, PG_GETARG_OID, and PG_RETURN_INT32.
Referenced by dumpBlobs(), exportFile(), importFile(), lo_export(), lo_import_internal(), my_truncate(), overwrite(), pickout(), and StartRestoreBlob().
{ Oid lobjId = PG_GETARG_OID(0); int32 mode = PG_GETARG_INT32(1); LargeObjectDesc *lobjDesc; int fd; #if FSDB elog(DEBUG4, "lo_open(%u,%d)", lobjId, mode); #endif CreateFSContext(); lobjDesc = inv_open(lobjId, mode, fscxt); if (lobjDesc == NULL) { /* lookup failed */ #if FSDB elog(DEBUG4, "could not open large object %u", lobjId); #endif PG_RETURN_INT32(-1); } fd = newLOfd(lobjDesc); PG_RETURN_INT32(fd); }
int lo_read | ( | int | fd, | |
char * | buf, | |||
int | len | |||
) |
Definition at line 157 of file be-fsstubs.c.
References ACL_SELECT, ACLCHECK_OK, cookies_size, ereport, errcode(), errmsg(), ERROR, LargeObjectDesc::flags, GetUserId(), LargeObjectDesc::id, IFS_RD_PERM_OK, inv_read(), lo_compat_privileges, NULL, pg_largeobject_aclcheck_snapshot(), and LargeObjectDesc::snapshot.
Referenced by dumpBlobs(), exportFile(), lo_export(), loread(), and pickout().
{ int status; LargeObjectDesc *lobj; if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("invalid large-object descriptor: %d", fd))); lobj = cookies[fd]; /* We don't bother to check IFS_RDLOCK, since it's always set */ /* Permission checks --- first time through only */ if ((lobj->flags & IFS_RD_PERM_OK) == 0) { if (!lo_compat_privileges && pg_largeobject_aclcheck_snapshot(lobj->id, GetUserId(), ACL_SELECT, lobj->snapshot) != ACLCHECK_OK) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("permission denied for large object %u", lobj->id))); lobj->flags |= IFS_RD_PERM_OK; } status = inv_read(lobj, buf, len); return status; }
Datum lo_tell | ( | PG_FUNCTION_ARGS | ) |
Definition at line 304 of file be-fsstubs.c.
References cookies_size, ereport, errcode(), errmsg(), ERROR, fd(), inv_tell(), NULL, PG_GETARG_INT32, and PG_RETURN_INT32.
{ int32 fd = PG_GETARG_INT32(0); int64 offset; if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("invalid large-object descriptor: %d", fd))); offset = inv_tell(cookies[fd]); /* guard against result overflow */ if (offset != (int32) offset) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("lo_tell result out of range for large-object descriptor %d", fd))); PG_RETURN_INT32((int32) offset); }
Datum lo_tell64 | ( | PG_FUNCTION_ARGS | ) |
Definition at line 327 of file be-fsstubs.c.
References cookies_size, ereport, errcode(), errmsg(), ERROR, fd(), inv_tell(), NULL, PG_GETARG_INT32, and PG_RETURN_INT64.
Referenced by pickout().
{ int32 fd = PG_GETARG_INT32(0); int64 offset; if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("invalid large-object descriptor: %d", fd))); offset = inv_tell(cookies[fd]); PG_RETURN_INT64(offset); }
Datum lo_truncate | ( | PG_FUNCTION_ARGS | ) |
Definition at line 611 of file be-fsstubs.c.
References fd(), lo_truncate_internal(), PG_GETARG_INT32, and PG_RETURN_INT32.
{ int32 fd = PG_GETARG_INT32(0); int32 len = PG_GETARG_INT32(1); lo_truncate_internal(fd, len); PG_RETURN_INT32(0); }
Datum lo_truncate64 | ( | PG_FUNCTION_ARGS | ) |
Definition at line 621 of file be-fsstubs.c.
References fd(), lo_truncate_internal(), PG_GETARG_INT32, PG_GETARG_INT64, and PG_RETURN_INT32.
Referenced by my_truncate().
{ int32 fd = PG_GETARG_INT32(0); int64 len = PG_GETARG_INT64(1); lo_truncate_internal(fd, len); PG_RETURN_INT32(0); }
static void lo_truncate_internal | ( | int32 | fd, | |
int64 | len | |||
) | [static] |
Definition at line 576 of file be-fsstubs.c.
References ACL_UPDATE, ACLCHECK_OK, cookies_size, ereport, errcode(), errmsg(), ERROR, LargeObjectDesc::flags, GetUserId(), LargeObjectDesc::id, IFS_WR_PERM_OK, IFS_WRLOCK, inv_truncate(), lo_compat_privileges, NULL, pg_largeobject_aclcheck_snapshot(), and LargeObjectDesc::snapshot.
Referenced by lo_truncate(), and lo_truncate64().
{ LargeObjectDesc *lobj; if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("invalid large-object descriptor: %d", fd))); lobj = cookies[fd]; if ((lobj->flags & IFS_WRLOCK) == 0) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("large object descriptor %d was not opened for writing", fd))); /* Permission checks --- first time through only */ if ((lobj->flags & IFS_WR_PERM_OK) == 0) { if (!lo_compat_privileges && pg_largeobject_aclcheck_snapshot(lobj->id, GetUserId(), ACL_UPDATE, lobj->snapshot) != ACLCHECK_OK) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("permission denied for large object %u", lobj->id))); lobj->flags |= IFS_WR_PERM_OK; } inv_truncate(lobj, len); }
Datum lo_unlink | ( | PG_FUNCTION_ARGS | ) |
Definition at line 343 of file be-fsstubs.c.
References cookies_size, deleteLOfd(), ereport, errcode(), errmsg(), ERROR, GetUserId(), i, inv_close(), inv_drop(), lo_compat_privileges, NULL, PG_GETARG_OID, pg_largeobject_ownercheck(), and PG_RETURN_INT32.
Referenced by do_lo_unlink(), lo_manage(), and vacuumlo().
{ Oid lobjId = PG_GETARG_OID(0); /* Must be owner of the largeobject */ if (!lo_compat_privileges && !pg_largeobject_ownercheck(lobjId, GetUserId())) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be owner of large object %u", lobjId))); /* * If there are any open LO FDs referencing that ID, close 'em. */ if (fscxt != NULL) { int i; for (i = 0; i < cookies_size; i++) { if (cookies[i] != NULL && cookies[i]->id == lobjId) { inv_close(cookies[i]); deleteLOfd(i); } } } /* * inv_drop does not create a need for end-of-transaction cleanup and * hence we don't need to have created fscxt. */ PG_RETURN_INT32(inv_drop(lobjId)); }
int lo_write | ( | int | fd, | |
const char * | buf, | |||
int | len | |||
) |
Definition at line 191 of file be-fsstubs.c.
References ACL_UPDATE, ACLCHECK_OK, cookies_size, ereport, errcode(), errmsg(), ERROR, LargeObjectDesc::flags, GetUserId(), LargeObjectDesc::id, IFS_WR_PERM_OK, IFS_WRLOCK, inv_write(), lo_compat_privileges, NULL, pg_largeobject_aclcheck_snapshot(), and LargeObjectDesc::snapshot.
Referenced by dump_lo_buf(), importFile(), lo_import_internal(), lowrite(), and overwrite().
{ int status; LargeObjectDesc *lobj; if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("invalid large-object descriptor: %d", fd))); lobj = cookies[fd]; if ((lobj->flags & IFS_WRLOCK) == 0) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("large object descriptor %d was not opened for writing", fd))); /* Permission checks --- first time through only */ if ((lobj->flags & IFS_WR_PERM_OK) == 0) { if (!lo_compat_privileges && pg_largeobject_aclcheck_snapshot(lobj->id, GetUserId(), ACL_UPDATE, lobj->snapshot) != ACLCHECK_OK) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("permission denied for large object %u", lobj->id))); lobj->flags |= IFS_WR_PERM_OK; } status = inv_write(lobj, buf, len); return status; }
Datum loread | ( | PG_FUNCTION_ARGS | ) |
Definition at line 383 of file be-fsstubs.c.
References fd(), lo_read(), palloc(), PG_GETARG_INT32, PG_RETURN_BYTEA_P, SET_VARSIZE, VARDATA, and VARHDRSZ.
{ int32 fd = PG_GETARG_INT32(0); int32 len = PG_GETARG_INT32(1); bytea *retval; int totalread; if (len < 0) len = 0; retval = (bytea *) palloc(VARHDRSZ + len); totalread = lo_read(fd, VARDATA(retval), len); SET_VARSIZE(retval, totalread + VARHDRSZ); PG_RETURN_BYTEA_P(retval); }
Datum lowrite | ( | PG_FUNCTION_ARGS | ) |
Definition at line 401 of file be-fsstubs.c.
References fd(), lo_write(), PG_GETARG_BYTEA_P, PG_GETARG_INT32, PG_RETURN_INT32, VARDATA, and VARSIZE.
{ int32 fd = PG_GETARG_INT32(0); bytea *wbuf = PG_GETARG_BYTEA_P(1); int bytestowrite; int totalwritten; bytestowrite = VARSIZE(wbuf) - VARHDRSZ; totalwritten = lo_write(fd, VARDATA(wbuf), bytestowrite); PG_RETURN_INT32(totalwritten); }
static int newLOfd | ( | LargeObjectDesc * | lobjCookie | ) | [static] |
Definition at line 710 of file be-fsstubs.c.
References Assert, cookies_size, i, MemoryContextAllocZero(), MemSet, NULL, and repalloc().
Referenced by lo_open().
{ int i, newsize; /* Try to find a free slot */ for (i = 0; i < cookies_size; i++) { if (cookies[i] == NULL) { cookies[i] = lobjCookie; return i; } } /* No free slot, so make the array bigger */ if (cookies_size <= 0) { /* First time through, arbitrarily make 64-element array */ i = 0; newsize = 64; cookies = (LargeObjectDesc **) MemoryContextAllocZero(fscxt, newsize * sizeof(LargeObjectDesc *)); cookies_size = newsize; } else { /* Double size of array */ i = cookies_size; newsize = cookies_size * 2; cookies = (LargeObjectDesc **) repalloc(cookies, newsize * sizeof(LargeObjectDesc *)); MemSet(cookies + cookies_size, 0, (newsize - cookies_size) * sizeof(LargeObjectDesc *)); cookies_size = newsize; } Assert(cookies[i] == NULL); cookies[i] = lobjCookie; return i; }
LargeObjectDesc** cookies = NULL [static] |
Definition at line 72 of file be-fsstubs.c.
int cookies_size = 0 [static] |
Definition at line 73 of file be-fsstubs.c.
Referenced by AtEOSubXact_LargeObject(), AtEOXact_LargeObject(), lo_close(), lo_lseek(), lo_lseek64(), lo_read(), lo_tell(), lo_tell64(), lo_truncate_internal(), lo_unlink(), lo_write(), and newLOfd().
MemoryContext fscxt = NULL [static] |
Definition at line 75 of file be-fsstubs.c.
Definition at line 57 of file be-fsstubs.c.
Referenced by check_object_ownership(), lo_read(), lo_truncate_internal(), lo_unlink(), and lo_write().