⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_unix.c

📁 sqlite最新源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*** 2004 May 22**** The author disclaims copyright to this source code.  In place of** a legal notice, here is a blessing:****    May you do good and not evil.**    May you find forgiveness for yourself and forgive others.**    May you share freely, never taking more than you give.************************************************************************************ This file contains the VFS implementation for unix-like operating systems** include Linux, MacOSX, *BSD, QNX, VxWorks, AIX, HPUX, and others.**** There are actually several different VFS implementations in this file.** The differences are in the way that file locking is done.  The default** implementation uses Posix Advisory Locks.  Alternative implementations** use flock(), dot-files, various proprietary locking schemas, or simply** skip locking all together.**** This source file is organized into divisions where the logic for various** subfunctions is contained within the appropriate division.  PLEASE** KEEP THE STRUCTURE OF THIS FILE INTACT.  New code should be placed** in the correct division and should be clearly labeled.**** The layout of divisions is as follows:****   *  General-purpose declarations and utility functions.**   *  Unique file ID logic used by VxWorks.**   *  Various locking primitive implementations (all except proxy locking):**      + for Posix Advisory Locks**      + for no-op locks**      + for dot-file locks**      + for flock() locking**      + for named semaphore locks (VxWorks only)**      + for AFP filesystem locks (MacOSX only)**   *  sqlite3_file methods not associated with locking.**   *  Definitions of sqlite3_io_methods objects for all locking**      methods plus "finder" functions for each locking method.**   *  sqlite3_vfs method implementations.**   *  Locking primitives for the proxy uber-locking-method. (MacOSX only)**   *  Definitions of sqlite3_vfs objects for all locking methods**      plus implementations of sqlite3_os_init() and sqlite3_os_end().**** $Id: os_unix.c,v 1.241 2009/02/09 17:34:07 drh Exp $*/#include "sqliteInt.h"#if SQLITE_OS_UNIX              /* This file is used on unix only *//*** There are various methods for file locking used for concurrency** control:****   1. POSIX locking (the default),**   2. No locking,**   3. Dot-file locking,**   4. flock() locking,**   5. AFP locking (OSX only),**   6. Named POSIX semaphores (VXWorks only),**   7. proxy locking. (OSX only)**** Styles 4, 5, and 7 are only available of SQLITE_ENABLE_LOCKING_STYLE** is defined to 1.  The SQLITE_ENABLE_LOCKING_STYLE also enables automatic** selection of the appropriate locking style based on the filesystem** where the database is located.  */#if !defined(SQLITE_ENABLE_LOCKING_STYLE)#  if defined(__APPLE__)#    define SQLITE_ENABLE_LOCKING_STYLE 1#  else#    define SQLITE_ENABLE_LOCKING_STYLE 0#  endif#endif/*** Define the OS_VXWORKS pre-processor macro to 1 if building on ** vxworks, or 0 otherwise.*/#ifndef OS_VXWORKS#  if defined(__RTP__) || defined(_WRS_KERNEL)#    define OS_VXWORKS 1#  else#    define OS_VXWORKS 0#  endif#endif/*** These #defines should enable >2GB file support on Posix if the** underlying operating system supports it.  If the OS lacks** large file support, these should be no-ops.**** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch** on the compiler command line.  This is necessary if you are compiling** on a recent machine (ex: RedHat 7.2) but you want your code to work** on an older machine (ex: RedHat 6.0).  If you compile on RedHat 7.2** without this option, LFS is enable.  But LFS does not exist in the kernel** in RedHat 6.0, so the code won't work.  Hence, for maximum binary** portability you should omit LFS.**** The previous paragraph was written in 2005.  (This paragraph is written** on 2008-11-28.) These days, all Linux kernels support large files, so** you should probably leave LFS enabled.  But some embedded platforms might** lack LFS in which case the SQLITE_DISABLE_LFS macro might still be useful.*/#ifndef SQLITE_DISABLE_LFS# define _LARGE_FILE       1# ifndef _FILE_OFFSET_BITS#   define _FILE_OFFSET_BITS 64# endif# define _LARGEFILE_SOURCE 1#endif/*** standard include files.*/#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <time.h>#include <sys/time.h>#include <errno.h>#if SQLITE_ENABLE_LOCKING_STYLE# include <sys/ioctl.h># if OS_VXWORKS#  include <semaphore.h>#  include <limits.h># else#  include <sys/file.h>#  include <sys/param.h>#  include <sys/mount.h># endif#endif /* SQLITE_ENABLE_LOCKING_STYLE *//*** If we are to be thread-safe, include the pthreads header and define** the SQLITE_UNIX_THREADS macro.*/#if SQLITE_THREADSAFE# include <pthread.h># define SQLITE_UNIX_THREADS 1#endif/*** Default permissions when creating a new file*/#ifndef SQLITE_DEFAULT_FILE_PERMISSIONS# define SQLITE_DEFAULT_FILE_PERMISSIONS 0644#endif/* ** Default permissions when creating auto proxy dir */#ifndef SQLITE_DEFAULT_PROXYDIR_PERMISSIONS# define SQLITE_DEFAULT_PROXYDIR_PERMISSIONS 0755#endif/*** Maximum supported path-length.*/#define MAX_PATHNAME 512/*** Only set the lastErrno if the error code is a real error and not ** a normal expected return code of SQLITE_BUSY or SQLITE_OK*/#define IS_LOCK_ERROR(x)  ((x != SQLITE_OK) && (x != SQLITE_BUSY))/*** The unixFile structure is subclass of sqlite3_file specific to the unix** VFS implementations.*/typedef struct unixFile unixFile;struct unixFile {  sqlite3_io_methods const *pMethod;  /* Always the first entry */  struct unixOpenCnt *pOpen;       /* Info about all open fd's on this inode */  struct unixLockInfo *pLock;      /* Info about locks on this inode */  int h;                           /* The file descriptor */  int dirfd;                       /* File descriptor for the directory */  unsigned char locktype;          /* The type of lock held on this fd */  int lastErrno;                   /* The unix errno from the last I/O error */  void *lockingContext;            /* Locking style specific state */#if SQLITE_ENABLE_LOCKING_STYLE  int openFlags;                   /* The flags specified at open() */#endif#if SQLITE_THREADSAFE && defined(__linux__)  pthread_t tid;                   /* The thread that "owns" this unixFile */#endif#if OS_VXWORKS  int isDelete;                    /* Delete on close if true */  struct vxworksFileId *pId;       /* Unique file ID */#endif#ifndef NDEBUG  /* The next group of variables are used to track whether or not the  ** transaction counter in bytes 24-27 of database files are updated  ** whenever any part of the database changes.  An assertion fault will  ** occur if a file is updated without also updating the transaction  ** counter.  This test is made to avoid new problems similar to the  ** one described by ticket #3584.   */  unsigned char transCntrChng;   /* True if the transaction counter changed */  unsigned char dbUpdate;        /* True if any part of database file changed */  unsigned char inNormalWrite;   /* True if in a normal write operation */  /* If true, that means we are dealing with a database file that has  ** a range of locking bytes from PENDING_BYTE through PENDING_BYTE+511  ** which should never be read or written.  Asserts() will verify this */  unsigned char isLockable;      /* True if file might be locked */#endif#ifdef SQLITE_TEST  /* In test mode, increase the size of this structure a bit so that   ** it is larger than the struct CrashFile defined in test6.c.  */  char aPadding[32];#endif};/*** Include code that is common to all os_*.c files*/#include "os_common.h"/*** Define various macros that are missing from some systems.*/#ifndef O_LARGEFILE# define O_LARGEFILE 0#endif#ifdef SQLITE_DISABLE_LFS# undef O_LARGEFILE# define O_LARGEFILE 0#endif#ifndef O_NOFOLLOW# define O_NOFOLLOW 0#endif#ifndef O_BINARY# define O_BINARY 0#endif/*** The DJGPP compiler environment looks mostly like Unix, but it** lacks the fcntl() system call.  So redefine fcntl() to be something** that always succeeds.  This means that locking does not occur under** DJGPP.  But it is DOS - what did you expect?*/#ifdef __DJGPP__# define fcntl(A,B,C) 0#endif/*** The threadid macro resolves to the thread-id or to 0.  Used for** testing and debugging only.*/#if SQLITE_THREADSAFE#define threadid pthread_self()#else#define threadid 0#endif/*** Helper functions to obtain and relinquish the global mutex.*/static void unixEnterMutex(void){  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));}static void unixLeaveMutex(void){  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));}#ifdef SQLITE_DEBUG/*** Helper function for printing out trace information from debugging** binaries. This returns the string represetation of the supplied** integer lock-type.*/static const char *locktypeName(int locktype){  switch( locktype ){  case NO_LOCK: return "NONE";  case SHARED_LOCK: return "SHARED";  case RESERVED_LOCK: return "RESERVED";  case PENDING_LOCK: return "PENDING";  case EXCLUSIVE_LOCK: return "EXCLUSIVE";  }  return "ERROR";}#endif#ifdef SQLITE_LOCK_TRACE/*** Print out information about all locking operations.**** This routine is used for troubleshooting locks on multithreaded** platforms.  Enable by compiling with the -DSQLITE_LOCK_TRACE** command-line option on the compiler.  This code is normally** turned off.*/static int lockTrace(int fd, int op, struct flock *p){  char *zOpName, *zType;  int s;  int savedErrno;  if( op==F_GETLK ){    zOpName = "GETLK";  }else if( op==F_SETLK ){    zOpName = "SETLK";  }else{    s = fcntl(fd, op, p);    sqlite3DebugPrintf("fcntl unknown %d %d %d\n", fd, op, s);    return s;  }  if( p->l_type==F_RDLCK ){    zType = "RDLCK";  }else if( p->l_type==F_WRLCK ){    zType = "WRLCK";  }else if( p->l_type==F_UNLCK ){    zType = "UNLCK";  }else{    assert( 0 );  }  assert( p->l_whence==SEEK_SET );  s = fcntl(fd, op, p);  savedErrno = errno;  sqlite3DebugPrintf("fcntl %d %d %s %s %d %d %d %d\n",     threadid, fd, zOpName, zType, (int)p->l_start, (int)p->l_len,     (int)p->l_pid, s);  if( s==(-1) && op==F_SETLK && (p->l_type==F_RDLCK || p->l_type==F_WRLCK) ){    struct flock l2;    l2 = *p;    fcntl(fd, F_GETLK, &l2);    if( l2.l_type==F_RDLCK ){      zType = "RDLCK";    }else if( l2.l_type==F_WRLCK ){      zType = "WRLCK";    }else if( l2.l_type==F_UNLCK ){      zType = "UNLCK";    }else{      assert( 0 );    }    sqlite3DebugPrintf("fcntl-failure-reason: %s %d %d %d\n",       zType, (int)l2.l_start, (int)l2.l_len, (int)l2.l_pid);  }  errno = savedErrno;  return s;}#define fcntl lockTrace#endif /* SQLITE_LOCK_TRACE *//*** This routine translates a standard POSIX errno code into something** useful to the clients of the sqlite3 functions.  Specifically, it is** intended to translate a variety of "try again" errors into SQLITE_BUSY** and a variety of "please close the file descriptor NOW" errors into ** SQLITE_IOERR** ** Errors during initialization of locks, or file system support for locks,** should handle ENOLCK, ENOTSUP, EOPNOTSUPP separately.*/static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) {  switch (posixError) {  case 0:     return SQLITE_OK;      case EAGAIN:  case ETIMEDOUT:  case EBUSY:  case EINTR:  case ENOLCK:      /* random NFS retry error, unless during file system support      * introspection, in which it actually means what it says */    return SQLITE_BUSY;      case EACCES:     /* EACCES is like EAGAIN during locking operations, but not any other time*/    if( (sqliteIOErr == SQLITE_IOERR_LOCK) || 	(sqliteIOErr == SQLITE_IOERR_UNLOCK) || 	(sqliteIOErr == SQLITE_IOERR_RDLOCK) ||	(sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ){      return SQLITE_BUSY;    }    /* else fall through */  case EPERM:     return SQLITE_PERM;      case EDEADLK:    return SQLITE_IOERR_BLOCKED;    #if EOPNOTSUPP!=ENOTSUP  case EOPNOTSUPP:     /* something went terribly awry, unless during file system support      * introspection, in which it actually means what it says */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -