Header And Logo

PostgreSQL
| The world's most advanced open source database.

Defines | Functions | Variables

be-fsstubs.c File Reference

#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"
Include dependency graph for be-fsstubs.c:

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 Documentation

#define BUFSIZE   8192

Definition at line 62 of file be-fsstubs.c.

Referenced by lo_export(), and lo_import_internal().

#define CreateFSContext (  ) 
Value:

Definition at line 77 of file be-fsstubs.c.

Referenced by lo_creat(), lo_create(), lo_export(), lo_import_internal(), and lo_open().


Function Documentation

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   ) 
static Oid lo_import_internal ( text filename,
Oid  lobjOid 
) [static]

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

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;
}


Variable Documentation

LargeObjectDesc** cookies = NULL [static]

Definition at line 72 of file be-fsstubs.c.

int cookies_size = 0 [static]
MemoryContext fscxt = NULL [static]

Definition at line 75 of file be-fsstubs.c.