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

📄 os.c

📁 SQLite 2.8.6 源代码,用来在Linux/Unix/Windows上编译安装.它是一个小型的数据库,但是非常好用,速度也快,一般的数据库查询之类的操作据统计比MySQL,PostgreSQL
💻 C
📖 第 1 页 / 共 3 页
字号:
    return SQLITE_CANTOPEN;  }  sqliteOsEnterMutex();  id->pLock = findLockInfo(id->fd);  sqliteOsLeaveMutex();  if( id->pLock==0 ){    close(id->fd);    return SQLITE_NOMEM;  }  id->locked = 0;  TRACE3("OPEN-RO %-3d %s\n", id->fd, zFilename);  OpenCounter(+1);  return SQLITE_OK;#endif#if OS_WIN  HANDLE h = CreateFile(zFilename,     GENERIC_READ,     0,     NULL,     OPEN_EXISTING,     FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,     NULL  );  if( h==INVALID_HANDLE_VALUE ){    return SQLITE_CANTOPEN;  }  id->h = h;  id->locked = 0;  OpenCounter(+1);  return SQLITE_OK;#endif#if OS_MAC  FSSpec fsSpec;# ifdef _LARGE_FILE  HFSUniStr255 dfName;  FSRef fsRef;  if( __path2fss(zFilename, &fsSpec) != noErr )    return SQLITE_CANTOPEN;  if( FSpMakeFSRef(&fsSpec, &fsRef) != noErr )    return SQLITE_CANTOPEN;  FSGetDataForkName(&dfName);  if( FSOpenFork(&fsRef, dfName.length, dfName.unicode,                 fsRdPerm, &(id->refNum)) != noErr )    return SQLITE_CANTOPEN;# else  __path2fss(zFilename, &fsSpec);  if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdPerm, &(id->refNum)) != noErr )    return SQLITE_CANTOPEN;# endif  if( HOpenRF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrShPerm, &(id->refNumRF)) != noErr){    id->refNumRF = -1;  }  id->locked = 0;  id->delOnClose = 0;  OpenCounter(+1);  return SQLITE_OK;#endif}/*** Attempt to open a file descriptor for the directory that contains a** file.  This file descriptor can be used to fsync() the directory** in order to make sure the creation of a new file is actually written** to disk.**** This routine is only meaningful for Unix.  It is a no-op under** windows since windows does not support hard links.**** On success, a handle for a previously open file is at *id is** updated with the new directory file descriptor and SQLITE_OK is** returned.**** On failure, the function returns SQLITE_CANTOPEN and leaves** *id unchanged.*/int sqliteOsOpenDirectory(  const char *zDirname,  OsFile *id){#if OS_UNIX  if( id->fd<0 ){    /* Do not open the directory if the corresponding file is not already    ** open. */    return SQLITE_CANTOPEN;  }  assert( id->dirfd<0 );  id->dirfd = open(zDirname, O_RDONLY|O_BINARY, 0644);  if( id->dirfd<0 ){    return SQLITE_CANTOPEN;   }  TRACE3("OPENDIR %-3d %s\n", id->dirfd, zDirname);#endif  return SQLITE_OK;}/*** Create a temporary file name in zBuf.  zBuf must be big enough to** hold at least SQLITE_TEMPNAME_SIZE characters.*/int sqliteOsTempFileName(char *zBuf){#if OS_UNIX  static const char *azDirs[] = {     "/var/tmp",     "/usr/tmp",     "/tmp",     ".",  };  static char zChars[] =    "abcdefghijklmnopqrstuvwxyz"    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"    "0123456789";  int i, j;  struct stat buf;  const char *zDir = ".";  for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){    if( stat(azDirs[i], &buf) ) continue;    if( !S_ISDIR(buf.st_mode) ) continue;    if( access(azDirs[i], 07) ) continue;    zDir = azDirs[i];    break;  }  do{    sprintf(zBuf, "%s/"TEMP_FILE_PREFIX, zDir);    j = strlen(zBuf);    for(i=0; i<15; i++){      int n = sqliteRandomByte() % (sizeof(zChars)-1);      zBuf[j++] = zChars[n];    }    zBuf[j] = 0;  }while( access(zBuf,0)==0 );#endif#if OS_WIN  static char zChars[] =    "abcdefghijklmnopqrstuvwxyz"    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"    "0123456789";  int i, j;  char zTempPath[SQLITE_TEMPNAME_SIZE];  GetTempPath(SQLITE_TEMPNAME_SIZE-30, zTempPath);  for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}  zTempPath[i] = 0;  for(;;){    sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zTempPath);    j = strlen(zBuf);    for(i=0; i<15; i++){      int n = sqliteRandomByte() % (sizeof(zChars) - 1);      zBuf[j++] = zChars[n];    }    zBuf[j] = 0;    if( !sqliteOsFileExists(zBuf) ) break;  }#endif#if OS_MAC  static char zChars[] =    "abcdefghijklmnopqrstuvwxyz"    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"    "0123456789";  int i, j;  char zTempPath[SQLITE_TEMPNAME_SIZE];  char zdirName[32];  CInfoPBRec infoRec;  Str31 dirName;  memset(&infoRec, 0, sizeof(infoRec));  memset(zTempPath, 0, SQLITE_TEMPNAME_SIZE);  if( FindFolder(kOnSystemDisk, kTemporaryFolderType,  kCreateFolder,       &(infoRec.dirInfo.ioVRefNum), &(infoRec.dirInfo.ioDrParID)) == noErr ){    infoRec.dirInfo.ioNamePtr = dirName;    do{      infoRec.dirInfo.ioFDirIndex = -1;      infoRec.dirInfo.ioDrDirID = infoRec.dirInfo.ioDrParID;      if( PBGetCatInfoSync(&infoRec) == noErr ){        CopyPascalStringToC(dirName, zdirName);        i = strlen(zdirName);        memmove(&(zTempPath[i+1]), zTempPath, strlen(zTempPath));        strcpy(zTempPath, zdirName);        zTempPath[i] = ':';      }else{        *zTempPath = 0;        break;      }    } while( infoRec.dirInfo.ioDrDirID != fsRtDirID );  }  if( *zTempPath == 0 )    getcwd(zTempPath, SQLITE_TEMPNAME_SIZE-24);  for(;;){    sprintf(zBuf, "%s"TEMP_FILE_PREFIX, zTempPath);    j = strlen(zBuf);    for(i=0; i<15; i++){      int n = sqliteRandomByte() % sizeof(zChars);      zBuf[j++] = zChars[n];    }    zBuf[j] = 0;    if( !sqliteOsFileExists(zBuf) ) break;  }#endif  return SQLITE_OK; }/*** Close a file*/int sqliteOsClose(OsFile *id){#if OS_UNIX  close(id->fd);  if( id->dirfd>=0 ) close(id->dirfd);  id->dirfd = -1;  sqliteOsEnterMutex();  releaseLockInfo(id->pLock);  sqliteOsLeaveMutex();  TRACE2("CLOSE   %-3d\n", id->fd);  OpenCounter(-1);  return SQLITE_OK;#endif#if OS_WIN  CloseHandle(id->h);  OpenCounter(-1);  return SQLITE_OK;#endif#if OS_MAC  if( id->refNumRF!=-1 )    FSClose(id->refNumRF);# ifdef _LARGE_FILE  FSCloseFork(id->refNum);# else  FSClose(id->refNum);# endif  if( id->delOnClose ){    unlink(id->pathToDel);    sqliteFree(id->pathToDel);  }  OpenCounter(-1);  return SQLITE_OK;#endif}/*** Read data from a file into a buffer.  Return SQLITE_OK if all** bytes were read successfully and SQLITE_IOERR if anything goes** wrong.*/int sqliteOsRead(OsFile *id, void *pBuf, int amt){#if OS_UNIX  int got;  SimulateIOError(SQLITE_IOERR);  TIMER_START;  got = read(id->fd, pBuf, amt);  TIMER_END;  TRACE4("READ    %-3d %7d %d\n", id->fd, last_page, elapse);  SEEK(0);  /* if( got<0 ) got = 0; */  if( got==amt ){    return SQLITE_OK;  }else{    return SQLITE_IOERR;  }#endif#if OS_WIN  DWORD got;  SimulateIOError(SQLITE_IOERR);  TRACE2("READ %d\n", last_page);  if( !ReadFile(id->h, pBuf, amt, &got, 0) ){    got = 0;  }  if( got==(DWORD)amt ){    return SQLITE_OK;  }else{    return SQLITE_IOERR;  }#endif#if OS_MAC  int got;  SimulateIOError(SQLITE_IOERR);  TRACE2("READ %d\n", last_page);# ifdef _LARGE_FILE  FSReadFork(id->refNum, fsAtMark, 0, (ByteCount)amt, pBuf, (ByteCount*)&got);# else  got = amt;  FSRead(id->refNum, &got, pBuf);# endif  if( got==amt ){    return SQLITE_OK;  }else{    return SQLITE_IOERR;  }#endif}/*** Write data from a buffer into a file.  Return SQLITE_OK on success** or some other error code on failure.*/int sqliteOsWrite(OsFile *id, const void *pBuf, int amt){#if OS_UNIX  int wrote = 0;  SimulateIOError(SQLITE_IOERR);  TIMER_START;  while( amt>0 && (wrote = write(id->fd, pBuf, amt))>0 ){    amt -= wrote;    pBuf = &((char*)pBuf)[wrote];  }  TIMER_END;  TRACE4("WRITE   %-3d %7d %d\n", id->fd, last_page, elapse);  SEEK(0);  if( amt>0 ){    return SQLITE_FULL;  }  return SQLITE_OK;#endif#if OS_WIN  int rc;  DWORD wrote;  SimulateIOError(SQLITE_IOERR);  TRACE2("WRITE %d\n", last_page);  while( amt>0 && (rc = WriteFile(id->h, pBuf, amt, &wrote, 0))!=0 && wrote>0 ){    amt -= wrote;    pBuf = &((char*)pBuf)[wrote];  }  if( !rc || amt>(int)wrote ){    return SQLITE_FULL;  }  return SQLITE_OK;#endif#if OS_MAC  OSErr oserr;  int wrote = 0;  SimulateIOError(SQLITE_IOERR);  TRACE2("WRITE %d\n", last_page);  while( amt>0 ){# ifdef _LARGE_FILE    oserr = FSWriteFork(id->refNum, fsAtMark, 0,                        (ByteCount)amt, pBuf, (ByteCount*)&wrote);# else    wrote = amt;    oserr = FSWrite(id->refNum, &wrote, pBuf);# endif    if( wrote == 0 || oserr != noErr)      break;    amt -= wrote;    pBuf = &((char*)pBuf)[wrote];  }  if( oserr != noErr || amt>wrote ){    return SQLITE_FULL;  }  return SQLITE_OK;#endif}/*** Move the read/write pointer in a file.*/int sqliteOsSeek(OsFile *id, off_t offset){  SEEK(offset/1024 + 1);#if OS_UNIX  lseek(id->fd, offset, SEEK_SET);  return SQLITE_OK;#endif#if OS_WIN  {    LONG upperBits = offset>>32;    LONG lowerBits = offset & 0xffffffff;    DWORD rc;    rc = SetFilePointer(id->h, lowerBits, &upperBits, FILE_BEGIN);    /* TRACE3("SEEK rc=0x%x upper=0x%x\n", rc, upperBits); */  }  return SQLITE_OK;#endif#if OS_MAC  {    off_t curSize;    if( sqliteOsFileSize(id, &curSize) != SQLITE_OK ){      return SQLITE_IOERR;    }    if( offset >= curSize ){      if( sqliteOsTruncate(id, offset+1) != SQLITE_OK ){        return SQLITE_IOERR;      }    }# ifdef _LARGE_FILE    if( FSSetForkPosition(id->refNum, fsFromStart, offset) != noErr ){# else    if( SetFPos(id->refNum, fsFromStart, offset) != noErr ){# endif      return SQLITE_IOERR;    }else{      return SQLITE_OK;    }  }#endif}/*** Make sure all writes to a particular file are committed to disk.**** Under Unix, also make sure that the directory entry for the file** has been created by fsync-ing the directory that contains the file.** If we do not do this and we encounter a power failure, the directory** entry for the journal might not exist after we reboot.  The next** SQLite to access the file will not know that the journal exists (because** the directory entry for the journal was never created) and the transaction** will not roll back - possibly leading to database corruption.*/int sqliteOsSync(OsFile *id){#if OS_UNIX  SimulateIOError(SQLITE_IOERR);  TRACE2("SYNC    %-3d\n", id->fd);  if( fsync(id->fd) ){    return SQLITE_IOERR;  }else{    if( id->dirfd>=0 ){      TRACE2("DIRSYNC %-3d\n", id->dirfd);      fsync(id->dirfd);      close(id->dirfd);  /* Only need to sync once, so close the directory */      id->dirfd = -1;    /* when we are done. */    }    return SQLITE_OK;  }#endif#if OS_WIN  if( FlushFileBuffers(id->h) ){    return SQLITE_OK;  }else{    return SQLITE_IOERR;  }#endif#if OS_MAC# ifdef _LARGE_FILE  if( FSFlushFork(id->refNum) != noErr ){# else  ParamBlockRec params;  memset(&params, 0, sizeof(ParamBlockRec));  params.ioParam.ioRefNum = id->refNum;  if( PBFlushFileSync(&params) != noErr ){# endif    return SQLITE_IOERR;  }else{    return SQLITE_OK;  }#endif}/*** Truncate an open file to a specified size*/int sqliteOsTruncate(OsFile *id, off_t nByte){  SimulateIOError(SQLITE_IOERR);#if OS_UNIX  return ftruncate(id->fd, nByte)==0 ? SQLITE_OK : SQLITE_IOERR;#endif#if OS_WIN  {    LONG upperBits = nByte>>32;    SetFilePointer(id->h, nByte, &upperBits, FILE_BEGIN);    SetEndOfFile(id->h);  }  return SQLITE_OK;#endif#if OS_MAC# ifdef _LARGE_FILE  if( FSSetForkSize(id->refNum, fsFromStart, nByte) != noErr){# else  if( SetEOF(id->refNum, nByte) != noErr ){# endif    return SQLITE_IOERR;  }else{    return SQLITE_OK;  }#endif}/*** Determine the current size of a file in bytes*/int sqliteOsFileSize(OsFile *id, off_t *pSize){#if OS_UNIX  struct stat buf;  SimulateIOError(SQLITE_IOERR);  if( fstat(id->fd, &buf)!=0 ){    return SQLITE_IOERR;  }  *pSize = buf.st_size;  return SQLITE_OK;#endif#if OS_WIN  DWORD upperBits, lowerBits;  SimulateIOError(SQLITE_IOERR);  lowerBits = GetFileSize(id->h, &upperBits);  *pSize = (((off_t)upperBits)<<32) + lowerBits;  return SQLITE_OK;#endif#if OS_MAC# ifdef _LARGE_FILE  if( FSGetForkSize(id->refNum, pSize) != noErr){# else  if( GetEOF(id->refNum, pSize) != noErr ){# endif    return SQLITE_IOERR;  }else{    return SQLITE_OK;  }#endif}#if OS_WIN/*** Return true (non-zero) if we are running under WinNT, Win2K or WinXP.** Return false (zero) for Win95, Win98, or WinME.**** Here is an interesting observation:  Win95, Win98, and WinME lack** the LockFileEx() API.  But we can still statically link against that** API as long as we don't call it win running Win95/98/ME.  A call to** this routine is used to determine if the host is Win95/98/ME or** WinNT/2K/XP so that we will know whether or not we can safely call** the LockFileEx() API.*/int isNT(void){  static osType = 0;   /* 0=unknown 1=win95 2=winNT */  if( osType==0 ){    OSVERSIONINFO sInfo;    sInfo.dwOSVersionInfoSize = sizeof(sInfo);    GetVersionEx(&sInfo);    osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;  }  return osType==2;}#endif/*** Windows file locking notes:  [similar issues apply to MacOS]**** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because** those functions are not available.  So we use only LockFile() and** UnlockFile().**** LockFile() prevents not just writing but also reading by other processes.** (This is a design error on the part of Windows, but there is nothing** we can do about that.)  So the region used for locking is at the** end of the file where it is unlikely to ever interfere with an** actual read attempt.**** A database read lock is obtained by locking a single randomly-chosen ** byte out of a specific range of bytes. The lock byte is obtained at ** random so two separate readers can probably access the file at the ** same time, unless they are unlucky and choose the same lock byte.

⌨️ 快捷键说明

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