?? os.c
字號:
#endif#if OS_MAC FSSpec fsSpec;# ifdef _LARGE_FILE HFSUniStr255 dfName; FSRef fsRef; __path2fss(zFilename, &fsSpec); if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr ) return SQLITE_CANTOPEN; if( FSpMakeFSRef(&fsSpec, &fsRef) != noErr ) return SQLITE_CANTOPEN; FSGetDataForkName(&dfName); if( FSOpenFork(&fsRef, dfName.length, dfName.unicode, fsRdWrPerm, &(id->refNum)) != noErr ) return SQLITE_CANTOPEN;# else __path2fss(zFilename, &fsSpec); if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr ) return SQLITE_CANTOPEN; if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrPerm, &(id->refNum)) != noErr ) return SQLITE_CANTOPEN;# endif id->refNumRF = -1; id->locked = 0; id->delOnClose = delFlag; if (delFlag) id->pathToDel = sqliteOsFullPathname(zFilename); OpenCounter(+1); return SQLITE_OK;#endif}/*** Attempt to open a new file for read-only access.**** On success, write the file handle into *id and return SQLITE_OK.**** On failure, return SQLITE_CANTOPEN.*/int sqliteOsOpenReadOnly(const char *zFilename, OsFile *id){#if OS_UNIX int rc; id->dirfd = -1; id->fd = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY); if( id->fd<0 ){ return SQLITE_CANTOPEN; } sqliteOsEnterMutex(); rc = findLockInfo(id->fd, &id->pLock, &id->pOpen); sqliteOsLeaveMutex(); if( rc ){ 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# ifndef _WIN32_WCE 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;# else WCHAR * wFilename = wStrDup( zFilename ); HANDLE h = CreateFileW( wFilename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL ); if ( h == INVALID_HANDLE_VALUE ) { free( wFilename ); return SQLITE_CANTOPEN; } id->h = h; id->delOnClose = 0; id->filePath = wFilename; id->hMux = 0; // Not shared, so no need to lock file id->hSem = 0; id->locked = 0;# endif 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;}/*** If the following global variable points to a string which is the** name of a directory, then that directory will be used to store** temporary files.*/const char *sqlite_temp_directory = 0;/*** 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[] = { 0, "/var/tmp", "/usr/tmp", "/tmp", ".", }; static unsigned char zChars[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789"; int i, j; struct stat buf; const char *zDir = "."; azDirs[0] = sqlite_temp_directory; for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){ if( azDirs[i]==0 ) continue; 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); sqliteRandomness(15, &zBuf[j]); for(i=0; i<15; i++, j++){ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; } zBuf[j] = 0; }while( access(zBuf,0)==0 );#endif#if OS_WIN static char zChars[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789"; int i, j; const char *zDir; char zTempPath[SQLITE_TEMPNAME_SIZE]; if( sqlite_temp_directory==0 ){# ifndef _WIN32_WCE GetTempPath(SQLITE_TEMPNAME_SIZE-30, zTempPath);# else { wchar_t wcs[SQLITE_TEMPNAME_SIZE - 30]; GetTempPathW( SQLITE_TEMPNAME_SIZE - 30, wcs ); wcstombs( zTempPath, wcs, SQLITE_TEMPNAME_SIZE - 30 ); }# endif for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){} zTempPath[i] = 0; zDir = zTempPath; }else{ zDir = sqlite_temp_directory; } for(;;){ sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zDir); j = strlen(zBuf); sqliteRandomness(15, &zBuf[j]); for(i=0; i<15; i++, j++){ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; } zBuf[j] = 0; if( !sqliteOsFileExists(zBuf) ) break; }#endif#if OS_MAC static char zChars[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789"; int i, j; char *zDir; char zTempPath[SQLITE_TEMPNAME_SIZE]; char zdirName[32]; CInfoPBRec infoRec; Str31 dirName; memset(&infoRec, 0, sizeof(infoRec)); memset(zTempPath, 0, SQLITE_TEMPNAME_SIZE); if( sqlite_temp_directory!=0 ){ zDir = sqlite_temp_directory; }else 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 ); zDir = zTempPath; } if( zDir[0]==0 ){ getcwd(zTempPath, SQLITE_TEMPNAME_SIZE-24); zDir = zTempPath; } for(;;){ sprintf(zBuf, "%s"TEMP_FILE_PREFIX, zDir); j = strlen(zBuf); sqliteRandomness(15, &zBuf[j]); for(i=0; i<15; i++, j++){ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; } zBuf[j] = 0; if( !sqliteOsFileExists(zBuf) ) break; }#endif return SQLITE_OK; }/*** Close a file.*/int sqliteOsClose(OsFile *id){#if OS_UNIX sqliteOsUnlock(id); if( id->dirfd>=0 ) close(id->dirfd); id->dirfd = -1; sqliteOsEnterMutex(); if( id->pOpen->nLock ){ /* If there are outstanding locks, do not actually close the file just ** yet because that would clear those locks. Instead, add the file ** descriptor to pOpen->aPending. It will be automatically closed when ** the last lock is cleared. */ int *aNew; struct openCnt *pOpen = id->pOpen; pOpen->nPending++; aNew = sqliteRealloc( pOpen->aPending, pOpen->nPending*sizeof(int) ); if( aNew==0 ){ /* If a malloc fails, just leak the file descriptor */ }else{ pOpen->aPending = aNew; pOpen->aPending[pOpen->nPending-1] = id->fd; } }else{ /* There are no outstanding locks so we can close the file immediately */ close(id->fd); } releaseLockInfo(id->pLock); releaseOpenCnt(id->pOpen); sqliteOsLeaveMutex(); TRACE2("CLOSE %-3d\n", id->fd); OpenCounter(-1); return SQLITE_OK;#endif#if OS_WIN# ifndef _WIN32_WCE CloseHandle(id->h);# else sqliteOsUnlock( id ); CloseHandle( id->h );# ifndef SQLITE_WCE_OMIT_FILELOCK wceport_CloseFileLock( id );# endif // SQLITE_OMIT_FILELOCK if ( id->delOnClose ) { DeleteFileW( id->filePath ); } free( id->filePath );# endif 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);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -