/************************************************************************************************* * Emulation of system calls * Copyright (C) 2000-2003 Mikio Hirabayashi * This file is part of QDBM, Quick Database Manager. * QDBM is free software; you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License as published by the Free Software Foundation; either version * 2.1 of the License or any later version. QDBM is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * You should have received a copy of the GNU Lesser General Public License along with QDBM; if * not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA. *************************************************************************************************/ #include "myconf.h" /************************************************************************************************* * for systems without mmap *************************************************************************************************/ #if defined(_SYS_MSVC_) || defined(_SYS_MINGW_) || defined(_SYS_RISCOS_) || defined(MYNOMMAP) void *_qdbm_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset){ char *buf, *wp; int rv, rlen; if(flags & MAP_FIXED) return MAP_FAILED; if(lseek(fd, SEEK_SET, offset) == -1) return MAP_FAILED; if(!(buf = malloc(sizeof(int) * 3 + length))) return MAP_FAILED; wp = buf; *(int *)wp = fd; wp += sizeof(int); *(int *)wp = offset; wp += sizeof(int); *(int *)wp = prot; wp += sizeof(int); rlen = 0; while((rv = read(fd, wp + rlen, length - rlen)) > 0){ rlen += rv; } if(rv == -1 || rlen != length){ free(buf); return MAP_FAILED; } return wp; } int _qdbm_munmap(void *start, size_t length){ char *buf, *rp; int fd, offset, prot, rv, wlen; buf = (char *)start - sizeof(int) * 3; rp = buf; fd = *(int *)rp; rp += sizeof(int); offset = *(int *)rp; rp += sizeof(int); prot = *(int *)rp; rp += sizeof(int); if(prot & PROT_WRITE){ if(lseek(fd, offset, SEEK_SET) == -1){ free(buf); return -1; } wlen = 0; while(wlen < length){ rv = write(fd, rp + wlen, length - wlen); if(rv == -1){ if(errno == EINTR) continue; free(buf); return -1; } wlen += rv; } } free(buf); return 0; } int _qdbm_msync(const void *start, size_t length, int flags){ char *buf, *rp; int fd, offset, prot, rv, wlen; buf = (char *)start - sizeof(int) * 3; rp = buf; fd = *(int *)rp; rp += sizeof(int); offset = *(int *)rp; rp += sizeof(int); prot = *(int *)rp; rp += sizeof(int); if(prot & PROT_WRITE){ if(lseek(fd, offset, SEEK_SET) == -1) return -1; wlen = 0; while(wlen < length){ rv = write(fd, rp + wlen, length - wlen); if(rv == -1){ if(errno == EINTR) continue; return -1; } wlen += rv; } } return 0; } #endif /************************************************************************************************* * for Win32 *************************************************************************************************/ #if defined(_SYS_MSVC_) || defined(_SYS_MINGW_) int _qdbm_win32_fcntl(int fd, int cmd, struct flock *lock){ HANDLE fh; OVERLAPPED ol; fh = (HANDLE)_get_osfhandle(fd); memset(&ol, 0, sizeof(OVERLAPPED)); ol.Offset = 0; ol.OffsetHigh = 0; ol.hEvent = 0; if(!LockFileEx(fh, lock->l_type == F_WRLCK ? LOCKFILE_EXCLUSIVE_LOCK : 0, 0, 0, 1, &ol)) return -1; return 0; } #endif #if defined(_SYS_MSVC_) DIR *_qdbm_win32_opendir(const char *name){ char expr[1024]; DIR *dir; HANDLE fh; WIN32_FIND_DATA data; sprintf(expr, "%s%c*", name, MYPATHCHR); if((fh = FindFirstFile(expr, &data)) == INVALID_HANDLE_VALUE) return NULL; if(!(dir = malloc(sizeof(DIR)))){ FindClose(fh); return NULL; } dir->fh = fh; dir->data = data; dir->first = TRUE; return dir; } int _qdbm_win32_closedir(DIR *dir){ if(!FindClose(dir->fh)){ free(dir); return -1; } free(dir); return 0; } struct dirent *_qdbm_win32_readdir(DIR *dir){ if(dir->first){ sprintf(dir->de.d_name, "%s", dir->data.cFileName); dir->first = FALSE; return &(dir->de); } if(!FindNextFile(dir->fh, &(dir->data))) return NULL; sprintf(dir->de.d_name, "%s", dir->data.cFileName); return &(dir->de); } #endif /************************************************************************************************* * for ZLIB *************************************************************************************************/ #if defined(MYZLIB) #include #define ZLIBBUFSIZ 8192 #define ZLIBCLEVEL 5 static char *_qdbm_deflate_impl(const char *ptr, int size, int *sp); static char *_qdbm_inflate_impl(const char *ptr, int size, int *sp); char *(*_qdbm_deflate)(const char *, int, int *) = _qdbm_deflate_impl; char *(*_qdbm_inflate)(const char *, int, int *) = _qdbm_inflate_impl; static char *_qdbm_deflate_impl(const char *ptr, int size, int *sp){ z_stream zs; char *buf, *swap; unsigned char obuf[ZLIBBUFSIZ]; int rv, asiz, bsiz, osiz; if(size < 0) size = strlen(ptr); zs.zalloc = Z_NULL; zs.zfree = Z_NULL; zs.opaque = Z_NULL; if(deflateInit(&zs, ZLIBCLEVEL) != Z_OK) return NULL; asiz = ZLIBBUFSIZ; if(!(buf = malloc(asiz))){ deflateEnd(&zs); return NULL; } bsiz = 0; zs.next_in = (unsigned char *)ptr; zs.avail_in = size; zs.next_out = obuf; zs.avail_out = ZLIBBUFSIZ; while((rv = deflate(&zs, Z_FINISH)) == Z_OK){ osiz = ZLIBBUFSIZ - zs.avail_out; if(bsiz + osiz > asiz){ asiz = asiz * 2 + osiz; if(!(swap = realloc(buf, asiz))){ free(buf); deflateEnd(&zs); return NULL; } buf = swap; } memcpy(buf + bsiz, obuf, osiz); bsiz += osiz; zs.next_out = obuf; zs.avail_out = ZLIBBUFSIZ; } if(rv != Z_STREAM_END){ free(buf); deflateEnd(&zs); return NULL; } osiz = ZLIBBUFSIZ - zs.avail_out; if(bsiz + osiz > asiz){ asiz = asiz * 2 + osiz; if(!(swap = realloc(buf, asiz))){ free(buf); deflateEnd(&zs); return NULL; } buf = swap; } memcpy(buf + bsiz, obuf, osiz); bsiz += osiz; *sp = bsiz; deflateEnd(&zs); return buf; } static char *_qdbm_inflate_impl(const char *ptr, int size, int *sp){ z_stream zs; char *buf, *swap; unsigned char obuf[ZLIBBUFSIZ]; int rv, asiz, bsiz, osiz; zs.zalloc = Z_NULL; zs.zfree = Z_NULL; zs.opaque = Z_NULL; if(inflateInit(&zs) != Z_OK) return NULL; asiz = ZLIBBUFSIZ; if(!(buf = malloc(asiz))){ deflateEnd(&zs); return NULL; } bsiz = 0; zs.next_in = (unsigned char *)ptr; zs.avail_in = size; zs.next_out = obuf; zs.avail_out = ZLIBBUFSIZ; while((rv = inflate(&zs, Z_NO_FLUSH)) == Z_OK){ osiz = ZLIBBUFSIZ - zs.avail_out; if(bsiz + osiz >= asiz){ asiz = asiz * 2 + osiz; if(!(swap = realloc(buf, asiz))){ free(buf); deflateEnd(&zs); return NULL; } buf = swap; } memcpy(buf + bsiz, obuf, osiz); bsiz += osiz; zs.next_out = obuf; zs.avail_out = ZLIBBUFSIZ; } if(rv != Z_STREAM_END){ free(buf); inflateEnd(&zs); return NULL; } osiz = ZLIBBUFSIZ - zs.avail_out; if(bsiz + osiz >= asiz){ asiz = asiz * 2 + osiz; if(!(swap = realloc(buf, asiz))){ free(buf); deflateEnd(&zs); return NULL; } buf = swap; } memcpy(buf + bsiz, obuf, osiz); bsiz += osiz; buf[bsiz] = '\0'; if(sp) *sp = bsiz; inflateEnd(&zs); return buf; } #else char *(*_qdbm_deflate)(const char *, int, int *) = NULL; char *(*_qdbm_inflate)(const char *, int, int *) = NULL; #endif /************************************************************************************************* * common settings *************************************************************************************************/ int _qdbm_dummyfunc(void){ return 0; } /* END OF FILE */