-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
-C Comment\sout\ssome\scode\sin\sos_unix.c\sthat\sonly\sruns\son\sMacOSX\swith\nSQLITE_ENABLE_LOCKING_STYLE.
-D 2011-02-25T03:25:07.454
+C Log\sall\serror\sfrom\sclose()\sin\sos_unix.c\sto\ssqlite3_log()\sbut\sdo\snot\sattempt\sto\nreport\serrors\sback\sup\sto\sthe\sapplication.\s\sUpdate\sthe\sunix\serror\slogging\sto\nput\sthe\smost\simportant\sinformation\searlier\sin\sthe\smessage.
+D 2011-03-02T02:08:13.207
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9
F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
F src/os_os2.c 2e452c9f2ca507623ad351c33a8a8b27849b1863
-F src/os_unix.c 64a2e0ebbb19765f97993b3920f795e6f38fd923
+F src/os_unix.c 5e2e1187c19cc20798dd9a08bee841fab0929ccf
F src/os_win.c 9abdcdd925416d854eabb0996c96debd92abfef5
F src/pager.c 6aa906b60a59664ba58d3f746164bb010d407ce1
F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1
F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347
F test/null.test a8b09b8ed87852742343b33441a9240022108993
F test/openv2.test af02ed0a9cbc0d2a61b8f35171d4d117e588e4ec
-F test/oserror.test 5775264a41039856d211168713d916949227fedd
+F test/oserror.test 8fc832600afe2b983f2347bfb3cbb88a80aeb347
F test/pager1.test d8672fd0af5f4f9b99b06283d00f01547809bebe
F test/pager2.test 745b911dde3d1f24ae0870bd433dfa83d7c658c1
F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P af4756184a255f5d8a5cd276bf9f2fc3b38d9169
-R 86eab7753acb1a027109135cae01654a
+P 4e50b0362ab6604a4b6c9f4ad849ec1733d6ce1a
+R a9b7ad5c14ea738e4f49c429699cb565
U drh
-Z 475e4dbe6e8fc13f5f8796d1c18d588c
+Z c02292224bfb7c5f15d6a63d1b16838a
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
-iD8DBQFNZyEhoxKgR168RlERAohiAKCDC55xIULyuJJBl/uNZNCMqVF+ZgCeK05+
-18x49YRlHX+qQrvL/cMA0OY=
-=QUmN
+iD8DBQFNbaaQoxKgR168RlERAshdAJ4iJDt6I1+oeLfL9JDapg61g0RrTgCfcFyC
+s4eiT7ukCDxc6MYErF6v4VI=
+=AyES
-----END PGP SIGNATURE-----
** failed (e.g. "unlink", "open") and the the associated file-system path,
** if any.
*/
-#define unixLogError(a,b,c) unixLogError_x(a,b,c,__LINE__)
-static int unixLogError_x(
+#define unixLogError(a,b,c) unixLogErrorAtLine(a,b,c,__LINE__)
+static int unixLogErrorAtLine(
int errcode, /* SQLite error code */
const char *zFunc, /* Name of OS function that failed */
const char *zPath, /* File path associated with error */
int iLine /* Source line number where error occurred */
){
char *zErr; /* Message from strerror() or equivalent */
+ int iErrno = errno; /* Saved syscall error number */
/* If this is not a threadsafe build (SQLITE_THREADSAFE==0), then use
** the strerror() function to obtain the human-readable error message
#if defined(STRERROR_R_CHAR_P) || defined(__USE_GNU)
zErr =
# endif
- strerror_r(errno, aErr, sizeof(aErr)-1);
+ strerror_r(iErrno, aErr, sizeof(aErr)-1);
#elif SQLITE_THREADSAFE
/* This is a threadsafe build, but strerror_r() is not available. */
zErr = "";
#else
/* Non-threadsafe build, use strerror(). */
- zErr = strerror(errno);
+ zErr = strerror(iErrno);
#endif
assert( errcode!=SQLITE_OK );
+ if( zPath==0 ) zPath = "";
sqlite3_log(errcode,
- "os_unix.c: %s() at line %d - \"%s\" errno=%d path=%s",
- zFunc, iLine, zErr, errno, (zPath ? zPath : "n/a")
+ "os_unix.c:%d: (%d) %s(%s) - %s",
+ iLine, iErrno, zFunc, zPath, zErr
);
return errcode;
}
+/*
+** Close a file descriptor.
+**
+** We assume that close() almost always works, since it is only in a
+** very sick application or on a very sick platform that it might fail.
+** If it does fail, simply leak the file descriptor, but do log the
+** error.
+**
+** Note that it is not safe to retry close() after EINTR since the
+** file descriptor might have already been reused by another thread.
+** So we don't even try to recover from an EINTR. Just log the error
+** and move on.
+*/
+static void robust_close(unixFile *pFile, int h, int lineno){
+ if( close(h) ){
+ unixLogErrorAtLine(SQLITE_IOERR_CLOSE, "close",
+ pFile ? pFile->zPath : 0, lineno);
+ }
+}
/*
** Close all file descriptors accumuated in the unixInodeInfo->pUnused list.
-** If all such file descriptors are closed without error, the list is
-** cleared and SQLITE_OK returned.
-**
-** Otherwise, if an error occurs, then successfully closed file descriptor
-** entries are removed from the list, and SQLITE_IOERR_CLOSE returned.
-** not deleted and SQLITE_IOERR_CLOSE returned.
*/
-static int closePendingFds(unixFile *pFile){
- int rc = SQLITE_OK;
+static void closePendingFds(unixFile *pFile){
unixInodeInfo *pInode = pFile->pInode;
- UnixUnusedFd *pError = 0;
UnixUnusedFd *p;
UnixUnusedFd *pNext;
for(p=pInode->pUnused; p; p=pNext){
pNext = p->pNext;
- if( close(p->fd) ){
- pFile->lastErrno = errno;
- rc = unixLogError(SQLITE_IOERR_CLOSE, "close", pFile->zPath);
- p->pNext = pError;
- pError = p;
- }else{
- sqlite3_free(p);
- }
+ robust_close(pFile, p->fd, __LINE__);
+ sqlite3_free(p);
}
- pInode->pUnused = pError;
- return rc;
+ pInode->pUnused = 0;
}
/*
pInode->nLock--;
assert( pInode->nLock>=0 );
if( pInode->nLock==0 ){
- int rc2 = closePendingFds(pFile);
- if( rc==SQLITE_OK ){
- rc = rc2;
- }
+ closePendingFds(pFile);
}
}
unixFile *pFile = (unixFile*)id;
if( pFile ){
if( pFile->dirfd>=0 ){
- int err = close(pFile->dirfd);
- if( err ){
- pFile->lastErrno = errno;
- return unixLogError(SQLITE_IOERR_DIR_CLOSE, "close", pFile->zPath);
- }else{
- pFile->dirfd=-1;
- }
+ robust_close(pFile, pFile->dirfd, __LINE__);
+ pFile->dirfd=-1;
}
if( pFile->h>=0 ){
- int err = close(pFile->h);
- if( err ){
- pFile->lastErrno = errno;
- return unixLogError(SQLITE_IOERR_CLOSE, "close", pFile->zPath);
- }
+ robust_close(pFile, pFile->h, __LINE__);
+ pFile->h = -1;
}
#if OS_VXWORKS
if( pFile->pId ){
}
return rc;
}
- if( close(fd) ){
- pFile->lastErrno = errno;
- rc = SQLITE_IOERR_CLOSE;
- }
+ robust_close(pFile, fd, __LINE__);
/* got it, set the type and return ok */
pFile->eFileLock = eFileLock;
pInode->nLock--;
assert( pInode->nLock>=0 );
if( pInode->nLock==0 ){
- rc = closePendingFds(pFile);
+ closePendingFds(pFile);
}
}
}
return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath);
}
if( pFile->dirfd>=0 ){
- int err;
OSTRACE(("DIRSYNC %-3d (have_fullfsync=%d fullsync=%d)\n", pFile->dirfd,
HAVE_FULLFSYNC, isFullsync));
#ifndef SQLITE_DISABLE_DIRSYNC
/* return SQLITE_IOERR; */
}
#endif
- err = close(pFile->dirfd); /* Only need to sync once, so close the */
- if( err==0 ){ /* directory when we are done */
- pFile->dirfd = -1;
- }else{
- pFile->lastErrno = errno;
- rc = unixLogError(SQLITE_IOERR_DIR_CLOSE, "close", pFile->zPath);
- }
+ /* Only need to sync once, so close the directory when we are done */
+ robust_close(pFile, pFile->dirfd, __LINE__);
+ pFile->dirfd = -1;
}
return rc;
}
munmap(p->apRegion[i], p->szRegion);
}
sqlite3_free(p->apRegion);
- if( p->h>=0 ) close(p->h);
+ if( p->h>=0 ){
+ robust_close(pFd, p->h, __LINE__);
+ p->h = -1;
+ }
p->pInode->pShmNode = 0;
sqlite3_free(p);
}
** implicit assumption here is that if fstat() fails, things are in
** such bad shape that dropping a lock or two doesn't matter much.
*/
- close(h);
+ robust_close(pNew, h, __LINE__);
h = -1;
}
unixLeaveMutex();
rc = findInodeInfo(pNew, &pNew->pInode);
if( rc!=SQLITE_OK ){
sqlite3_free(pNew->lockingContext);
- close(h);
+ robust_close(pNew, h, __LINE__);
h = -1;
}
unixLeaveMutex();
pNew->lastErrno = 0;
#if OS_VXWORKS
if( rc!=SQLITE_OK ){
- if( h>=0 ) close(h);
+ if( h>=0 ) robust_close(pNew, h, __LINE__);
h = -1;
unlink(zFilename);
isDelete = 0;
pNew->isDelete = isDelete;
#endif
if( rc!=SQLITE_OK ){
- if( dirfd>=0 ) close(dirfd); /* silent leak if fail, already in error */
- if( h>=0 ) close(h);
+ if( dirfd>=0 ) robust_close(pNew, dirfd, __LINE__);
+ if( h>=0 ) robust_close(pNew, h, __LINE__);
}else{
pNew->pMethod = pLockingStyle;
OpenCounter(+1);
** it would not be safe to close as this would release any locks held
** on the file by this process. */
assert( eType!=SQLITE_OPEN_MAIN_DB );
- close(fd); /* silently leak if fail, already in error */
+ robust_close(p, fd, __LINE__);
goto open_finished;
}
}
struct statfs fsInfo;
if( fstatfs(fd, &fsInfo) == -1 ){
((unixFile*)pFile)->lastErrno = errno;
- if( dirfd>=0 ) close(dirfd); /* silently leak if fail, in error */
- close(fd); /* silently leak if fail, in error */
+ if( dirfd>=0 ) robust_close(p, dirfd, __LINE__);
+ robust_close(p, fd, __LINE__);
return SQLITE_IOERR_ACCESS;
}
if (0 == strncmp("msdos", fsInfo.f_fstypename, 5)) {
** the same file are working. */
p->lastErrno = errno;
if( dirfd>=0 ){
- close(dirfd); /* silently leak if fail, in error */
+ robust_close(p, dirfd, __LINE__);
}
- close(fd); /* silently leak if fail, in error */
+ robust_close(p, fd, __LINE__);
rc = SQLITE_IOERR_ACCESS;
goto open_finished;
}
{
rc = unixLogError(SQLITE_IOERR_DIR_FSYNC, "fsync", zPath);
}
- if( close(fd)&&!rc ){
- rc = unixLogError(SQLITE_IOERR_DIR_CLOSE, "close", zPath);
- }
+ robust_close(0, fd, __LINE__);
}
}
#endif
nBuf = sizeof(t) + sizeof(pid);
}else{
do{ nBuf = read(fd, zBuf, nBuf); }while( nBuf<0 && errno==EINTR );
- close(fd);
+ robust_close(0, fd, __LINE__);
}
}
#endif
return SQLITE_OK;
}
end_create_proxy:
- close(fd); /* silently leak fd if error, we're already in error */
+ robust_close(pNew, fd, __LINE__);
sqlite3_free(pNew);
sqlite3_free(pUnused);
return rc;
}
rc = 0;
fprintf(stderr, "broke stale lock on %s\n", cPath);
- close(conchFile->h);
+ robust_close(pFile, conchFile->h, __LINE__);
conchFile->h = fd;
conchFile->openFlags = O_RDWR | O_CREAT;
if( rc ){
if( fd>=0 ){
unlink(tPath);
- close(fd);
+ robust_close(pFile, fd, __LINE__);
}
fprintf(stderr, "failed to break stale lock on %s, %s\n", cPath, errmsg);
}
OSTRACE(("TRANSPROXY: CLOSE %d\n", pFile->h));
if( rc==SQLITE_OK && pFile->openFlags ){
if( pFile->h>=0 ){
-#ifdef STRICT_CLOSE_ERROR
- if( close(pFile->h) ){
- pFile->lastErrno = errno;
- return SQLITE_IOERR_CLOSE;
- }
-#else
- close(pFile->h); /* silently leak fd if fail */
-#endif
+ robust_close(pFile, pFile->h, __LINE__) ){
}
pFile->h = -1;
int fd = open(pCtx->dbPath, pFile->openFlags,