]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Log all error from close() in os_unix.c to sqlite3_log() but do not attempt to
authordrh <drh@noemail.net>
Wed, 2 Mar 2011 02:08:13 +0000 (02:08 +0000)
committerdrh <drh@noemail.net>
Wed, 2 Mar 2011 02:08:13 +0000 (02:08 +0000)
report errors back up to the application.  Update the unix error logging to
put the most important information earlier in the message.

FossilOrigin-Name: 7b6e30e6a712311d4ef275253b085b85e6e17116

manifest
manifest.uuid
src/os_unix.c
test/oserror.test

index 1d2716b2dbcc1c828da1af4b7f549b6db2d98fe9..30c4b431b167e329f593686e6b740d0cf84e8b46 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,8 +1,8 @@
 -----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
@@ -164,7 +164,7 @@ F src/os.c 22ac61d06e72a0dac900400147333b07b13d8e1d
 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
@@ -585,7 +585,7 @@ F test/notify3.test d60923e186e0900f4812a845fcdfd8eea096e33a
 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
@@ -912,14 +912,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 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-----
index a2c2d650a211e3c405a72de5585f6e6fb0359219..0b4dc2a39e40c7d134dc08897b00c441cd01fd9a 100644 (file)
@@ -1 +1 @@
-4e50b0362ab6604a4b6c9f4ad849ec1733d6ce1a
\ No newline at end of file
+7b6e30e6a712311d4ef275253b085b85e6e17116
\ No newline at end of file
index 473432be5fec39620f104768d3db84b90c849abd..b70e2736bd63b4b86f524c50f411be3c865b9d21 100644 (file)
@@ -767,14 +767,15 @@ static unixInodeInfo *inodeList = 0;
 ** 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
@@ -800,54 +801,59 @@ static int unixLogError_x(
 #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;
 }
 
 /*
@@ -1458,10 +1464,7 @@ static int _posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
     pInode->nLock--;
     assert( pInode->nLock>=0 );
     if( pInode->nLock==0 ){
-      int rc2 = closePendingFds(pFile);
-      if( rc==SQLITE_OK ){
-        rc = rc2;
-      }
+      closePendingFds(pFile);
     }
   }
        
@@ -1496,20 +1499,12 @@ static int closeUnixFile(sqlite3_file *id){
   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 ){
@@ -1719,10 +1714,7 @@ static int dotlockLock(sqlite3_file *id, int eFileLock) {
     }
     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;
@@ -2614,7 +2606,7 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) {
       pInode->nLock--;
       assert( pInode->nLock>=0 );
       if( pInode->nLock==0 ){
-        rc = closePendingFds(pFile);
+        closePendingFds(pFile);
       }
     }
   }
@@ -3047,7 +3039,6 @@ static int unixSync(sqlite3_file *id, int flags){
     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
@@ -3066,13 +3057,9 @@ static int unixSync(sqlite3_file *id, int flags){
        /* 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;
 }
@@ -3439,7 +3426,10 @@ static void unixShmPurge(unixFile *pFd){
       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);
   }
@@ -4250,7 +4240,7 @@ static int fillInUnixFile(
       ** 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();
@@ -4276,7 +4266,7 @@ static int fillInUnixFile(
       rc = findInodeInfo(pNew, &pNew->pInode);
       if( rc!=SQLITE_OK ){
         sqlite3_free(pNew->lockingContext);
-        close(h);
+        robust_close(pNew, h, __LINE__);
         h = -1;
       }
       unixLeaveMutex();        
@@ -4327,7 +4317,7 @@ static int fillInUnixFile(
   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;
@@ -4335,8 +4325,8 @@ static int fillInUnixFile(
   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);
@@ -4748,7 +4738,7 @@ static int unixOpen(
       ** 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;
     }
   }
@@ -4764,8 +4754,8 @@ static int unixOpen(
   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)) {
@@ -4797,9 +4787,9 @@ static int unixOpen(
         ** 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;
       }
@@ -4860,9 +4850,7 @@ static int unixDelete(
       {
         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
@@ -5050,7 +5038,7 @@ static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){
       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
@@ -5493,7 +5481,7 @@ static int proxyCreateUnixFile(
     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;
@@ -5593,7 +5581,7 @@ static int proxyBreakConchLock(unixFile *pFile, uuid_t myHostID){
   }
   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;
 
@@ -5601,7 +5589,7 @@ end_breaklock:
   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);
   }
@@ -5851,14 +5839,7 @@ static int proxyTakeConch(unixFile *pFile){
       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,
index f2aa61008f7f26ea99061ec9feb4f65901f5fb04..e44a6741925d316bf93cc60d358eff8605808b26 100644 (file)
@@ -56,7 +56,7 @@ do_test 1.1.2 {
   catch { for {set i 0} {$i < 2000} {incr i} { dbh_$i close } }
 } {1}
 
-do_re_test 1.1.3 { lindex $::log 0 } {^os_unix.c: open.*test.db$}
+do_re_test 1.1.3 { lindex $::log 0 } {^os_unix.c:\d*: \(24\) open\(.*test.db\) - }
 
 
 # Test a failure in open() due to the path being a directory.
@@ -67,7 +67,7 @@ do_test 1.2.1 {
   list [catch { sqlite3 dbh dir.db } msg] $msg
 } {1 {unable to open database file}}
 
-do_re_test 1.2.2 { lindex $::log 0 } {^os_unix.c: open.*dir.db$}
+do_re_test 1.2.2 { lindex $::log 0 } {^os_unix.c:\d*: \(21\) open\(.*dir.db\) - }
 
 # Test a failure in open() due to the path not existing.
 #
@@ -76,7 +76,7 @@ do_test 1.3.1 {
   list [catch { sqlite3 dbh /x/y/z/test.db } msg] $msg
 } {1 {unable to open database file}}
 
-do_re_test 1.3.2 { lindex $::log 0 } {^os_unix.c: open.*test.db$}
+do_re_test 1.3.2 { lindex $::log 0 } {^os_unix.c:\d*: \(2\) open\(.*test.db\) - }
 
 # Test a failure in open() due to the path not existing.
 #
@@ -85,7 +85,7 @@ do_test 1.4.1 {
   list [catch { sqlite3 dbh /root/test.db } msg] $msg
 } {1 {unable to open database file}}
 
-do_re_test 1.4.2 { lindex $::log 0 } {^os_unix.c: open.*test.db$}
+do_re_test 1.4.2 { lindex $::log 0 } {^os_unix.c:\d*: \(13\) open\(.*test.db\) - }
 
 #--------------------------------------------------------------------------
 # Tests oserror-1.* test failures in the unlink() system call.
@@ -98,7 +98,7 @@ do_test 2.1.1 {
   catchsql { SELECT * FROM sqlite_master } dbh
 } {1 {disk I/O error}}
 
-do_re_test 2.1.2 { lindex $::log 0 } {^os_unix.c: unlink.*test.db-wal$}
+do_re_test 2.1.2 { lindex $::log 0 } {^os_unix.c:\d*: \(21\) unlink\(.*test.db-wal\) - }
 do_test 2.1.3 { 
   dbh close
   forcedelete test.db-wal
@@ -109,4 +109,3 @@ sqlite3_shutdown
 test_sqlite3_log 
 sqlite3_initialize
 finish_test
-