#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().
1.7.1