solaris.txt
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:6k
- #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 enabledn");
- } 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;
- }