dwww Home | Show directory contents | Find package

#ifdef OS_solaris
 * This is all for Solaris 2.6.
 *
 * Sun defined a new API in Solaris2.6 to be used when manipulating large
 * (>2Gbyte) files.  This API isn't present in 2.5.x, so we can't simply
 * call it -- that would mean two binaries, one for 2.5.x and the other for
 * 2.6. Not pretty.  So, what we do here is determine the OS on which we're
 * running at runtime, and adjust the underlying Berkeley DB calls to use
 * the new API if it's there.
 */

/* This must match the definition of stat64 in Solaris2.6 */
struct our_stat64 {
        dev_t   st_dev;
        long    st_pad1[3];     /* reserve for dev expansion */
        u_longlong_t st_ino;
        mode_t  st_mode;
        nlink_t st_nlink;
        uid_t   st_uid;
        gid_t   st_gid;
        dev_t   st_rdev;
        long    st_pad2[2];
        longlong_t st_size;
        timestruc_t mst_atime;
        timestruc_t mst_mtime;
        timestruc_t mst_ctime;
        long    st_blksize;
        longlong_t st_blocks;   /* large file support */
        char    st_fstype[_ST_FSTYPSZ];
        long    st_pad4[8];     /* expansion area */
};

#define MEGABYTE (1024 * 1024)

typedef int (*open_fn)(const char *path, int flags, ...);
typedef longlong_t (*lseek64_fn)(int fildes, longlong_t offset, int whence);
typedef longlong_t (*fstat64_fn)(int fildes, struct our_stat64 *s);
typedef void* (*mmap64_fn)(void* addr, size_t len, int prot, int flags,
int filedes, longlong_t off);

static fstat64_fn os_fstat64_fn = NULL;
static lseek64_fn os_lseek64_fn = NULL;
static mmap64_fn os_mmap64_fn = NULL;
static open_fn os_open64_fn = NULL;

static int dblayer_load_largefile_fns()
{
        void *lib_handle = NULL;
        void *function_found = NULL;
        int ret = 0;

        lib_handle = dlopen(NULL, RTLD_NOW);
        if (NULL == lib_handle)
                return (-1);

        function_found = dlsym(lib_handle,"open64");
        if (NULL == function_found)
                return (-1);
        os_open64_fn = (open_fn)function_found;

        function_found = dlsym(lib_handle,"lseek64");
        if (NULL == function_found)
                return (-1);
        os_lseek64_fn = (lseek64_fn)function_found;

        function_found = dlsym(lib_handle,"fstat64");
        if (NULL == function_found)
                return (-1);
        os_fstat64_fn = (fstat64_fn)function_found;

        function_found = dlsym(lib_handle,"mmap64");
        if (NULL == function_found)
                return (-1);
        os_mmap64_fn = (mmap64_fn)function_found;

        return 0;
}

/* Helper function for large seeks */
static int dblayer_seek_fn_solaris(int fd,
    size_t pgsize, db_pgno_t pageno, u_long relative, int whence)
{
        longlong_t offset = 0;
        longlong_t ret = 0;

        if (NULL == os_lseek64_fn) {
                return -1;
        }

        offset = (longlong_t)pgsize * pageno + relative;

        ret = (*os_lseek64_fn)(fd,offset,whence);

        return (ret == -1) ? errno : 0;
}

/* Helper function for large file mmap */
static int dblayer_map_solaris(fd, len, is_private, is_rdonly, addr)
        int fd, is_private, is_rdonly;
        size_t len;
        void **addr;
{
        void *p;
        int flags, prot;

        flags = is_private ? MAP_PRIVATE : MAP_SHARED;
        prot = PROT_READ | (is_rdonly ? 0 : PROT_WRITE);

        if ((p = (*os_mmap64_fn)(NULL,
            len, prot, flags, fd, (longlong_t)0)) == (void *)MAP_FAILED)
                return (errno);

        *addr = p;
        return (0);
}

/* Helper function for large fstat */
static int dblayer_ioinfo_solaris(const char *path,
    int fd, u_int32_t *mbytesp, u_int32_t *bytesp, u_int32_t *iosizep)
{
        struct our_stat64 sb;

        if (NULL == os_fstat64_fn) {
                return -1;
        }

        if ((*os_fstat64_fn)(fd, &sb) == -1)
                return (errno);

        /* Return the size of the file. */
        if (mbytesp != NULL)
                *mbytesp = (u_int32_t) (sb.st_size / (longlong_t)MEGABYTE);
        if (bytesp != NULL)
                *bytesp = (u_int32_t) (sb.st_size % (longlong_t)MEGABYTE);

        /*
         * Return the underlying filesystem blocksize, if available.  Default
         * to 8K on the grounds that most OS's use less than 8K as their VM
         * page size.
         */
        if (iosizep != NULL)
                *iosizep = sb.st_blksize;
        return (0);
}
#endif

#ifdef irix
 * A similar mess to Solaris: a new API added in IRIX6.2 to support large
 * files. We always build on 6.2 or later, so no need to do the same song
 * and dance as on Solaris -- we always have the header files for the
 * 64-bit API.
 */

/* Helper function for large seeks */
static int dblayer_seek_fn_irix(int fd,
    size_t pgsize, db_pgno_t pageno, u_long relative, int whence)
{
        off64_t offset = 0;
        off64_t ret = 0;

        offset = (off64_t)pgsize * pageno + relative;

        ret = lseek64(fd,offset,whence);

        return (ret == -1) ? errno : 0;
}

/* Helper function for large fstat */
static int dblayer_ioinfo_irix(const char *path,
    int fd, u_int32_t *mbytesp, u_int32_t *bytesp, u_int32_t *iosizep)
{
        struct stat64 sb;

        if (fstat64(fd, &sb) == -1) {
                return (errno);
        }

        /* Return the size of the file. */
        if (mbytesp != NULL)
                *mbytesp = (u_int32_t) (sb.st_size / (off64_t)MEGABYTE);
        if (bytesp != NULL)
                *bytesp = (u_int32_t) (sb.st_size % (off64_t)MEGABYTE);

        if (iosizep != NULL)
                *iosizep = sb.st_blksize;
        return (0);
}
#endif /* irix */

static int dblayer_override_libdb_functions(dblayer_private *priv)
{
#if defined(OS_solaris)
        int ret = 0;

        ret = dblayer_load_largefile_fns();
        if (0 != ret) {
                Debug("Not Solaris2.6: no large file support enabled\n");
        } else {
                /* Means we did get the XXX64 functions, so let's use them */
                db_jump_set((void*)os_open64_fn, DB_FUNC_OPEN);
                db_jump_set((void*)dblayer_seek_fn_solaris, DB_FUNC_SEEK);
                db_jump_set((void*)dblayer_ioinfo_solaris, DB_FUNC_IOINFO);
                db_jump_set((void*)dblayer_map_solaris, DB_FUNC_MAP);
                Debug("Solaris2.6: selected 64-bit file handling.\n");
         }
#else
#if defined (irix)
        db_jump_set((void*)dblayer_seek_fn_irix, DB_FUNC_SEEK);
        db_jump_set((void*)dblayer_ioinfo_irix, DB_FUNC_IOINFO);
#endif /* irix */
#endif /* OS_solaris */
        return 0;
}

Generated by dwww version 1.14 on Sat Aug 30 08:12:09 CEST 2025.