Drop support for MAC OS9. SQLite 3 has never worked for that OS because

the developers do not have access to a machine running it and nobody from
the community has stepped forward to provide a port.  By moving the
os_mac.c file into the attic, we make the lack of support official. (CVS 2220)

FossilOrigin-Name: de9ad673d037f7bfca3a2d439259a63c9ed954db
This commit is contained in:
drh 2005-01-16 20:47:40 +00:00
parent aac0a38d1f
commit 0d477437ac
7 changed files with 18 additions and 843 deletions

View File

@ -113,7 +113,7 @@ TCC += -DSQLITE_OMIT_CURSOR
#
LIBOBJ = attach.lo auth.lo btree.lo build.lo cursor.lo date.lo \
delete.lo expr.lo func.lo hash.lo insert.lo \
main.lo opcodes.lo os_mac.lo os_unix.lo os_win.lo \
main.lo opcodes.lo os_unix.lo os_win.lo \
pager.lo parse.lo pragma.lo printf.lo random.lo \
select.lo table.lo tokenize.lo trigger.lo update.lo \
util.lo vacuum.lo vdbe.lo vdbeapi.lo vdbeaux.lo vdbemem.lo \
@ -137,7 +137,6 @@ SRC = \
$(TOP)/src/insert.c \
$(TOP)/src/legacy.c \
$(TOP)/src/main.c \
$(TOP)/src/os_mac.c \
$(TOP)/src/os_unix.c \
$(TOP)/src/os_win.c \
$(TOP)/src/pager.c \
@ -172,7 +171,6 @@ TESTSRC = \
$(TOP)/src/btree.c \
$(TOP)/src/date.c \
$(TOP)/src/func.c \
$(TOP)/src/os_mac.c \
$(TOP)/src/os_unix.c \
$(TOP)/src/os_win.c \
$(TOP)/src/pager.c \
@ -198,7 +196,6 @@ HDR = \
opcodes.h \
$(TOP)/src/os.h \
$(TOP)/src/os_common.h \
$(TOP)/src/os_mac.h \
$(TOP)/src/os_unix.h \
$(TOP)/src/os_win.h \
$(TOP)/src/sqliteInt.h \
@ -330,9 +327,6 @@ opcodes.c: opcodes.h $(TOP)/mkopcodec.awk
opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk
cat parse.h $(TOP)/src/vdbe.c | awk -f $(TOP)/mkopcodeh.awk >opcodes.h
os_mac.lo: $(TOP)/src/os_mac.c $(HDR)
$(LTCOMPILE) $(THREADSAFE) -c $(TOP)/src/os_mac.c
os_unix.lo: $(TOP)/src/os_unix.c $(HDR)
$(LTCOMPILE) $(THREADSAFE) -c $(TOP)/src/os_unix.c

View File

@ -56,7 +56,7 @@ TCCX = $(TCC) $(OPTS) $(THREADSAFE) $(USLEEP) -I. -I$(TOP)/src
#
LIBOBJ+= attach.o auth.o btree.o build.o cursor.o date.o delete.o \
expr.o func.o hash.o insert.o \
main.o opcodes.o os_mac.o os_unix.o os_win.o \
main.o opcodes.o os_unix.o os_win.o \
pager.o parse.o pragma.o printf.o random.o \
select.o table.o tclsqlite.o tokenize.o trigger.o \
update.o util.o vacuum.o \
@ -81,7 +81,6 @@ SRC = \
$(TOP)/src/insert.c \
$(TOP)/src/legacy.c \
$(TOP)/src/main.c \
$(TOP)/src/os_mac.c \
$(TOP)/src/os_unix.c \
$(TOP)/src/os_win.c \
$(TOP)/src/pager.c \
@ -116,7 +115,6 @@ TESTSRC = \
$(TOP)/src/btree.c \
$(TOP)/src/date.c \
$(TOP)/src/func.c \
$(TOP)/src/os_mac.c \
$(TOP)/src/os_unix.c \
$(TOP)/src/os_win.c \
$(TOP)/src/pager.c \
@ -142,7 +140,6 @@ HDR = \
opcodes.h \
$(TOP)/src/os.h \
$(TOP)/src/os_common.h \
$(TOP)/src/os_mac.h \
$(TOP)/src/os_unix.h \
$(TOP)/src/os_win.h \
$(TOP)/src/sqliteInt.h \
@ -266,9 +263,6 @@ opcodes.c: opcodes.h $(TOP)/mkopcodec.awk
opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk
cat parse.h $(TOP)/src/vdbe.c | awk -f $(TOP)/mkopcodeh.awk >opcodes.h
os_mac.o: $(TOP)/src/os_mac.c $(HDR)
$(TCCX) -c $(TOP)/src/os_mac.c
os_unix.o: $(TOP)/src/os_unix.c $(HDR)
$(TCCX) -c $(TOP)/src/os_unix.c

View File

@ -1,6 +1,6 @@
C Changes\sto\smake\ssure\stests\swork\swhen\sSQLITE_DEFAULT_AUTOVACUUM\sis\sdefined.\s(CVS\s2219)
D 2005-01-16T11:07:07
F Makefile.in 6ce51dde6a8fe82fc12f20dec750572f6a19f56a
C Drop\ssupport\sfor\sMAC\sOS9.\s\sSQLite\s3\shas\snever\sworked\sfor\sthat\sOS\sbecause\nthe\sdevelopers\sdo\snot\shave\saccess\sto\sa\smachine\srunning\sit\sand\snobody\sfrom\nthe\scommunity\shas\sstepped\sforward\sto\sprovide\sa\sport.\s\sBy\smoving\sthe\nos_mac.c\sfile\sinto\sthe\sattic,\swe\smake\sthe\slack\sof\ssupport\sofficial.\s(CVS\s2220)
D 2005-01-16T20:47:41
F Makefile.in 78d6d0af3725aef32468ac9923444d7645d21a28
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1
F VERSION 342b6d5fde93b6d45023e2fee0163dda6464b9d6
@ -16,7 +16,7 @@ F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538
F doc/report1.txt a031aaf37b185e4fa540223cb516d3bccec7eeac
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
F ltmain.sh f6b283068efa69f06eb8aa1fe4bddfdbdeb35826
F main.mk 962ac4f3b8ab6ce00d66f085bf259f946589eead
F main.mk 839f7bc12221a02bcee10aa0fc72841d893e9b16
F mkdll.sh 468d4f41d3ea98221371df4825cfbffbaac4d7e4
F mkopcodec.awk 141aede6e58634f9cf9e96205a5316680e649987
F mkopcodeh.awk ee454cdee1da38b485c5e8cca84e5727c07158ba
@ -43,10 +43,8 @@ F src/insert.c 2a8fadfd7494881632fcae453f115d42a7a58dee
F src/legacy.c d58ea507bce885298a2c8c3cbb0f4bff5d47830b
F src/main.c cbe5a05baabad9fabb733065d0fb00c0b36f6ef1
F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
F src/os.h c92a675533c75fea0f53559f34c7b91c5afe1a9d
F src/os.h ae44064dc118b20d39450cb331409a775e8bb1c6
F src/os_common.h 0e7f428ba0a6c40a61bc56c4e96f493231301b73
F src/os_mac.c e2a35e96bdf57a113ae1c446532e3c0924d3d046
F src/os_mac.h 608fdf39eafa1ce25fc8cb223b8b0a073341d4da
F src/os_test.c 91e5f22dd89491e5e1554820e715805f43fa4ece
F src/os_test.h 6a26a4978492e4bbdbf385554958418ff02db162
F src/os_unix.c 08340c864822115bf87c6c1735780a0996278b81
@ -269,7 +267,7 @@ F www/tclsqlite.tcl e73f8f8e5f20e8277619433f7970060ab01088fc
F www/vdbe.tcl 095f106d93875c94b47367384ebc870517431618
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
F www/whentouse.tcl c3b50d3ac31c54be2a1af9b488a89d22f1e6e746
P fe548561a0e7a696fd453372f4427cf3e3f19d20
R efc29d803f831313057d41111eb84268
U danielk1977
Z 437c229bfd7b7a9b1f6b1f483648fd2d
P 6237c294d1211d5848bafb1310574e2486a43757
R ca099b3c791f0b796eb74e72a082b2c7
U drh
Z 5cc4e0ef8392da0ae950aaff44fc3d28

View File

@ -1 +1 @@
6237c294d1211d5848bafb1310574e2486a43757
de9ad673d037f7bfca3a2d439259a63c9ed954db

View File

@ -25,30 +25,17 @@
*/
#if !defined(OS_UNIX) && !defined(OS_TEST)
# ifndef OS_WIN
# ifndef OS_MAC
# if defined(__MACOS__)
# define OS_MAC 1
# define OS_WIN 0
# define OS_UNIX 0
# elif defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
# define OS_MAC 0
# define OS_WIN 1
# define OS_UNIX 0
# else
# define OS_MAC 0
# define OS_WIN 0
# define OS_UNIX 1
# endif
# else
# define OS_WIN 0
# define OS_UNIX 0
# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
# define OS_WIN 1
# define OS_UNIX 0
# else
# define OS_WIN 0
# define OS_UNIX 1
# endif
# else
# define OS_MAC 0
# define OS_UNIX 0
# endif
#else
# define OS_MAC 0
# ifndef OS_WIN
# define OS_WIN 0
# endif
@ -66,9 +53,6 @@
#if OS_WIN
# include "os_win.h"
#endif
#if OS_MAC
# include "os_mac.h"
#endif
/*
** Temporary files are named starting with this prefix followed by 16 random

View File

@ -1,754 +0,0 @@
/*
** 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 code that is specific classic mac. Mac OS X
** uses the os_unix.c file, not this one.
*/
#include "sqliteInt.h"
#include "os.h"
#if OS_MAC /* This file used on classic mac only */
#include <extras.h>
#include <path2fss.h>
#include <TextUtils.h>
#include <FinderRegistry.h>
#include <Folders.h>
#include <Timer.h>
#include <OSUtils.h>
/*
** Macros used to determine whether or not to use threads.
*/
#if defined(THREADSAFE) && THREADSAFE
# include <Multiprocessing.h>
# define SQLITE_MACOS_MULTITASKING 1
#endif
/*
** Include code that is common to all os_*.c files
*/
#include "os_common.h"
/*
** Delete the named file
*/
int sqlite3OsDelete(const char *zFilename){
unlink(zFilename);
return SQLITE_OK;
}
/*
** Return TRUE if the named file exists.
*/
int sqlite3OsFileExists(const char *zFilename){
return access(zFilename, 0)==0;
}
/*
** Attempt to open a file for both reading and writing. If that
** fails, try opening it read-only. If the file does not exist,
** try to create it.
**
** On success, a handle for the open file is written to *id
** and *pReadonly is set to 0 if the file was opened for reading and
** writing or 1 if the file was opened read-only. The function returns
** SQLITE_OK.
**
** On failure, the function returns SQLITE_CANTOPEN and leaves
** *id and *pReadonly unchanged.
*/
int sqlite3OsOpenReadWrite(
const char *zFilename,
OsFile *id,
int *pReadonly
){
FSSpec fsSpec;
# ifdef _LARGE_FILE
HFSUniStr255 dfName;
FSRef fsRef;
if( __path2fss(zFilename, &fsSpec) != noErr ){
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,
fsRdWrShPerm, &(id->refNum)) != noErr ){
if( FSOpenFork(&fsRef, dfName.length, dfName.unicode,
fsRdWrPerm, &(id->refNum)) != noErr ){
if (FSOpenFork(&fsRef, dfName.length, dfName.unicode,
fsRdPerm, &(id->refNum)) != noErr )
return SQLITE_CANTOPEN;
else
*pReadonly = 1;
} else
*pReadonly = 0;
} else
*pReadonly = 0;
# else
__path2fss(zFilename, &fsSpec);
if( !sqlite3OsFileExists(zFilename) ){
if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr )
return SQLITE_CANTOPEN;
}
if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrShPerm, &(id->refNum)) != noErr ){
if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrPerm, &(id->refNum)) != noErr ){
if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdPerm, &(id->refNum)) != noErr )
return SQLITE_CANTOPEN;
else
*pReadonly = 1;
} else
*pReadonly = 0;
} else
*pReadonly = 0;
# 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;
}
/*
** Attempt to open a new file for exclusive access by this process.
** The file will be opened for both reading and writing. To avoid
** a potential security problem, we do not allow the file to have
** previously existed. Nor do we allow the file to be a symbolic
** link.
**
** If delFlag is true, then make arrangements to automatically delete
** the file when it is closed.
**
** On success, write the file handle into *id and return SQLITE_OK.
**
** On failure, return SQLITE_CANTOPEN.
*/
int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
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 = sqlite3OsFullPathname(zFilename);
OpenCounter(+1);
return SQLITE_OK;
}
/*
** 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 sqlite3OsOpenReadOnly(const char *zFilename, OsFile *id){
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;
}
/*
** 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 sqlite3OsOpenDirectory(
const char *zDirname,
OsFile *id
){
return SQLITE_OK;
}
/*
** Create a temporary file name in zBuf. zBuf must be big enough to
** hold at least SQLITE_TEMPNAME_SIZE characters.
*/
int sqlite3OsTempFileName(char *zBuf){
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);
sqlite3Randomness(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( !sqlite3OsFileExists(zBuf) ) break;
}
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.
*/
char *sqlite3_temp_directory = 0;
/*
** Check that a given pathname is a directory and is writable
** Just return false, as module is deprecated.
*/
int sqlite3OsIsDirWritable(char *zBuf){
return 0;
}
/*
** Close a file.
*/
int sqlite3OsClose(OsFile *id){
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;
}
/*
** 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 sqlite3OsRead(OsFile *id, void *pBuf, int amt){
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;
}
}
/*
** Write data from a buffer into a file. Return SQLITE_OK on success
** or some other error code on failure.
*/
int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){
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;
}
/*
** Move the read/write pointer in a file.
*/
int sqlite3OsSeek(OsFile *id, off_t offset){
off_t curSize;
SEEK(offset/1024 + 1);
if( sqlite3OsFileSize(id, &curSize) != SQLITE_OK ){
return SQLITE_IOERR;
}
if( offset >= curSize ){
if( sqlite3OsTruncate(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;
}
}
/*
** 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 sqlite3OsSync(OsFile *id){
# 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;
}
}
/*
** Sync the directory zDirname. This is a no-op on operating systems other
** than UNIX.
*/
int sqlite3OsSyncDirectory(const char *zDirname){
SimulateIOError(SQLITE_IOERR);
return SQLITE_OK;
}
/*
** Truncate an open file to a specified size
*/
int sqlite3OsTruncate(OsFile *id, off_t nByte){
SimulateIOError(SQLITE_IOERR);
# 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;
}
}
/*
** Determine the current size of a file in bytes
*/
int sqlite3OsFileSize(OsFile *id, off_t *pSize){
# ifdef _LARGE_FILE
if( FSGetForkSize(id->refNum, pSize) != noErr){
# else
if( GetEOF(id->refNum, pSize) != noErr ){
# endif
return SQLITE_IOERR;
}else{
return SQLITE_OK;
}
}
/*
** 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.
** A database write lock is obtained by locking all bytes in the range.
** There can only be one writer.
**
** A lock is obtained on the first byte of the lock range before acquiring
** either a read lock or a write lock. This prevents two processes from
** attempting to get a lock at a same time. The semantics of
** sqlite3OsReadLock() require that if there is already a write lock, that
** lock is converted into a read lock atomically. The lock on the first
** byte allows us to drop the old write lock and get the read lock without
** another process jumping into the middle and messing us up. The same
** argument applies to sqlite3OsWriteLock().
**
** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available,
** which means we can use reader/writer locks. When reader writer locks
** are used, the lock is placed on the same range of bytes that is used
** for probabilistic locking in Win95/98/ME. Hence, the locking scheme
** will support two or more Win95 readers or two or more WinNT readers.
** But a single Win95 reader will lock out all WinNT readers and a single
** WinNT reader will lock out all other Win95 readers.
**
** Note: On MacOS we use the resource fork for locking.
**
** The following #defines specify the range of bytes used for locking.
** N_LOCKBYTE is the number of bytes available for doing the locking.
** The first byte used to hold the lock while the lock is changing does
** not count toward this number. FIRST_LOCKBYTE is the address of
** the first byte in the range of bytes used for locking.
*/
#define N_LOCKBYTE 10239
#define FIRST_LOCKBYTE (0x000fffff - N_LOCKBYTE)
/*
** Change the status of the lock on the file "id" to be a readlock.
** If the file was write locked, then this reduces the lock to a read.
** If the file was read locked, then this acquires a new read lock.
**
** Return SQLITE_OK on success and SQLITE_BUSY on failure. If this
** library was compiled with large file support (LFS) but LFS is not
** available on the host, then an SQLITE_NOLFS is returned.
*/
int sqlite3OsReadLock(OsFile *id){
int rc;
if( id->locked>0 || id->refNumRF == -1 ){
rc = SQLITE_OK;
}else{
int lk;
OSErr res;
int cnt = 5;
ParamBlockRec params;
sqlite3Randomness(sizeof(lk), &lk);
lk = (lk & 0x7fffffff)%N_LOCKBYTE + 1;
memset(&params, 0, sizeof(params));
params.ioParam.ioRefNum = id->refNumRF;
params.ioParam.ioPosMode = fsFromStart;
params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
params.ioParam.ioReqCount = 1;
while( cnt-->0 && (res = PBLockRangeSync(&params))!=noErr ){
UInt32 finalTicks;
Delay(1, &finalTicks); /* 1/60 sec */
}
if( res == noErr ){
params.ioParam.ioPosOffset = FIRST_LOCKBYTE+1;
params.ioParam.ioReqCount = N_LOCKBYTE;
PBUnlockRangeSync(&params);
params.ioParam.ioPosOffset = FIRST_LOCKBYTE+lk;
params.ioParam.ioReqCount = 1;
res = PBLockRangeSync(&params);
params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
params.ioParam.ioReqCount = 1;
PBUnlockRangeSync(&params);
}
if( res == noErr ){
id->locked = lk;
rc = SQLITE_OK;
}else{
rc = SQLITE_BUSY;
}
}
return rc;
}
/*
** Change the lock status to be an exclusive or write lock. Return
** SQLITE_OK on success and SQLITE_BUSY on a failure. If this
** library was compiled with large file support (LFS) but LFS is not
** available on the host, then an SQLITE_NOLFS is returned.
*/
int sqlite3OsWriteLock(OsFile *id){
int rc;
if( id->locked<0 || id->refNumRF == -1 ){
rc = SQLITE_OK;
}else{
OSErr res;
int cnt = 5;
ParamBlockRec params;
memset(&params, 0, sizeof(params));
params.ioParam.ioRefNum = id->refNumRF;
params.ioParam.ioPosMode = fsFromStart;
params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
params.ioParam.ioReqCount = 1;
while( cnt-->0 && (res = PBLockRangeSync(&params))!=noErr ){
UInt32 finalTicks;
Delay(1, &finalTicks); /* 1/60 sec */
}
if( res == noErr ){
params.ioParam.ioPosOffset = FIRST_LOCKBYTE + id->locked;
params.ioParam.ioReqCount = 1;
if( id->locked==0
|| PBUnlockRangeSync(&params)==noErr ){
params.ioParam.ioPosOffset = FIRST_LOCKBYTE+1;
params.ioParam.ioReqCount = N_LOCKBYTE;
res = PBLockRangeSync(&params);
}else{
res = afpRangeNotLocked;
}
params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
params.ioParam.ioReqCount = 1;
PBUnlockRangeSync(&params);
}
if( res == noErr ){
id->locked = -1;
rc = SQLITE_OK;
}else{
rc = SQLITE_BUSY;
}
}
return rc;
}
/*
** Unlock the given file descriptor. If the file descriptor was
** not previously locked, then this routine is a no-op. If this
** library was compiled with large file support (LFS) but LFS is not
** available on the host, then an SQLITE_NOLFS is returned.
*/
int sqlite3OsUnlock(OsFile *id){
int rc;
ParamBlockRec params;
memset(&params, 0, sizeof(params));
params.ioParam.ioRefNum = id->refNumRF;
params.ioParam.ioPosMode = fsFromStart;
if( id->locked==0 || id->refNumRF == -1 ){
rc = SQLITE_OK;
}else if( id->locked<0 ){
params.ioParam.ioPosOffset = FIRST_LOCKBYTE+1;
params.ioParam.ioReqCount = N_LOCKBYTE;
PBUnlockRangeSync(&params);
rc = SQLITE_OK;
id->locked = 0;
}else{
params.ioParam.ioPosOffset = FIRST_LOCKBYTE+id->locked;
params.ioParam.ioReqCount = 1;
PBUnlockRangeSync(&params);
rc = SQLITE_OK;
id->locked = 0;
}
return rc;
}
/*
** Get information to seed the random number generator. The seed
** is written into the buffer zBuf[256]. The calling function must
** supply a sufficiently large buffer.
*/
int sqlite3OsRandomSeed(char *zBuf){
/* We have to initialize zBuf to prevent valgrind from reporting
** errors. The reports issued by valgrind are incorrect - we would
** prefer that the randomness be increased by making use of the
** uninitialized space in zBuf - but valgrind errors tend to worry
** some users. Rather than argue, it seems easier just to initialize
** the whole array and silence valgrind, even if that means less randomness
** in the random seed.
**
** When testing, initializing zBuf[] to zero is all we do. That means
** that we always use the same random number sequence.* This makes the
** tests repeatable.
*/
memset(zBuf, 0, 256);
#if !defined(SQLITE_TEST)
{
int pid;
Microseconds((UnsignedWide*)zBuf);
pid = getpid();
memcpy(&zBuf[sizeof(UnsignedWide)], &pid, sizeof(pid));
}
#endif
return SQLITE_OK;
}
/*
** Sleep for a little while. Return the amount of time slept.
*/
int sqlite3OsSleep(int ms){
UInt32 finalTicks;
UInt32 ticks = (((UInt32)ms+16)*3)/50; /* 1/60 sec per tick */
Delay(ticks, &finalTicks);
return (int)((ticks*50)/3);
}
/*
** Static variables used for thread synchronization
*/
static int inMutex = 0;
#ifdef SQLITE_MACOS_MULTITASKING
static MPCriticalRegionID criticalRegion;
#endif
/*
** The following pair of routine implement mutual exclusion for
** multi-threaded processes. Only a single thread is allowed to
** executed code that is surrounded by EnterMutex() and LeaveMutex().
**
** SQLite uses only a single Mutex. There is not much critical
** code and what little there is executes quickly and without blocking.
*/
void sqlite3OsEnterMutex(){
#ifdef SQLITE_MACOS_MULTITASKING
static volatile int notInit = 1;
if( notInit ){
if( notInit == 2 ) /* as close as you can get to thread safe init */
MPYield();
else{
notInit = 2;
MPCreateCriticalRegion(&criticalRegion);
notInit = 0;
}
}
MPEnterCriticalRegion(criticalRegion, kDurationForever);
#endif
assert( !inMutex );
inMutex = 1;
}
void sqlite3OsLeaveMutex(){
assert( inMutex );
inMutex = 0;
#ifdef SQLITE_MACOS_MULTITASKING
MPExitCriticalRegion(criticalRegion);
#endif
}
/*
** Turn a relative pathname into a full pathname. Return a pointer
** to the full pathname stored in space obtained from sqliteMalloc().
** The calling function is responsible for freeing this space once it
** is no longer needed.
*/
char *sqlite3OsFullPathname(const char *zRelative){
char *zFull = 0;
if( zRelative[0]==':' ){
char zBuf[_MAX_PATH+1];
sqlite3SetString(&zFull, getcwd(zBuf, sizeof(zBuf)), &(zRelative[1]),
(char*)0);
}else{
if( strchr(zRelative, ':') ){
sqlite3SetString(&zFull, zRelative, (char*)0);
}else{
char zBuf[_MAX_PATH+1];
sqlite3SetString(&zFull, getcwd(zBuf, sizeof(zBuf)), zRelative, (char*)0);
}
}
return zFull;
}
/*
** The following variable, if set to a non-zero value, becomes the result
** returned from sqlite3OsCurrentTime(). This is used for testing.
*/
#ifdef SQLITE_TEST
int sqlite3_current_time = 0;
#endif
/*
** Find the current time (in Universal Coordinated Time). Write the
** current time and date as a Julian Day number into *prNow and
** return 0. Return 1 if the time and date cannot be found.
*/
int sqlite3OsCurrentTime(double *prNow){
*prNow = 0.0; /**** FIX ME *****/
#ifdef SQLITE_TEST
if( sqlite3_current_time ){
*prNow = sqlite3_current_time/86400.0 + 2440587.5;
}
#endif
return 0;
}
#endif /* OS_MAC */

View File

@ -1,41 +0,0 @@
/*
** 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 header file defines OS-specific features of classic Mac.
** OS X uses the os_unix.h file, not this one.
*/
#ifndef _SQLITE_OS_MAC_H_
#define _SQLITE_OS_MAC_H_
#include <unistd.h>
#include <Files.h>
#define SQLITE_TEMPNAME_SIZE _MAX_PATH
#define SQLITE_MIN_SLEEP_MS 17
/*
** The OsFile structure is a operating-system independing representation
** of an open file handle. It is defined differently for each architecture.
**
** This is the definition for class Mac.
*/
typedef struct OsFile OsFile;
struct OsFile {
SInt16 refNum; /* Data fork/file reference number */
SInt16 refNumRF; /* Resource fork reference number (for locking) */
int locked; /* 0: unlocked, <0: write lock, >0: read lock */
int delOnClose; /* True if file is to be deleted on close */
char *pathToDel; /* Name of file to delete on close */
};
#endif /* _SQLITE_OS_MAC_H_ */