/ Check-in [e3b2e0a0]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:In the CLI, detect and report errors on sqlite3_close(). Clear global variables prior to exit to so that valgrind can better detect resource leaks.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: e3b2e0a078b82ac6cd3c3312e8ac0983c1375e1052f1e324476d2f8d1b227c30
User & Date: drh 2018-05-18 17:11:50
Context
2018-05-18
17:58
Add support for auxiliary columns to the rtree extension. check-in: c6071ac9 user: drh tags: trunk
17:17
Merge enhancements from trunk, especially the CLI fixes. Closed-Leaf check-in: a350040a user: drh tags: aux-data-in-rtree
17:11
In the CLI, detect and report errors on sqlite3_close(). Clear global variables prior to exit to so that valgrind can better detect resource leaks. check-in: e3b2e0a0 user: drh tags: trunk
14:24
Improvements to integer/float comparisons on architectures that lack a "long double" type. check-in: 5139ea62 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/shell.c.in.

  3651   3651         char *zSql = sqlite3_mprintf(
  3652   3652            "CREATE VIRTUAL TABLE zip USING zipfile(%Q);", p->zDbFilename);
  3653   3653         sqlite3_exec(p->db, zSql, 0, 0, 0);
  3654   3654         sqlite3_free(zSql);
  3655   3655       }
  3656   3656     }
  3657   3657   }
         3658  +
         3659  +/*
         3660  +** Attempt to close the databaes connection.  Report errors.
         3661  +*/
         3662  +void close_db(sqlite3 *db){
         3663  +  int rc = sqlite3_close(db);
         3664  +  if( rc ){
         3665  +    utf8_printf(stderr, "Error: sqlite3_close() returns %d: %s\n",
         3666  +        rc, sqlite3_errmsg(db));
         3667  +  } 
         3668  +}
  3658   3669   
  3659   3670   #if HAVE_READLINE || HAVE_EDITLINE
  3660   3671   /*
  3661   3672   ** Readline completion callbacks
  3662   3673   */
  3663   3674   static char *readline_completion_generator(const char *text, int state){
  3664   3675     static sqlite3_stmt *pStmt = 0;
................................................................................
  4232   4243       sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
  4233   4244       sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
  4234   4245       tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
  4235   4246       tryToCloneSchema(p, newDb, "type!='table'", 0);
  4236   4247       sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
  4237   4248       sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
  4238   4249     }
  4239         -  sqlite3_close(newDb);
         4250  +  close_db(newDb);
  4240   4251   }
  4241   4252   
  4242   4253   /*
  4243   4254   ** Change the output file back to stdout.
  4244   4255   **
  4245   4256   ** If the p->doXdgOpen flag is set, that means the output was being
  4246   4257   ** redirected to a temporary file named by p->zTempFile.  In that case,
................................................................................
  5549   5560           assert( cmd.eCmd==AR_CMD_UPDATE );
  5550   5561           rc = arCreateOrUpdateCommand(&cmd, 1);
  5551   5562           break;
  5552   5563       }
  5553   5564     }
  5554   5565   end_ar_command:
  5555   5566     if( cmd.db!=pState->db ){
  5556         -    sqlite3_close(cmd.db);
         5567  +    close_db(cmd.db);
  5557   5568     }
  5558   5569     sqlite3_free(cmd.zSrcTable);
  5559   5570   
  5560   5571     return rc;
  5561   5572   }
  5562   5573   /* End of the ".archive" or ".ar" command logic
  5563   5574   **********************************************************************************/
................................................................................
  5672   5683         return 1;
  5673   5684       }
  5674   5685       if( zDb==0 ) zDb = "main";
  5675   5686       rc = sqlite3_open_v2(zDestFile, &pDest, 
  5676   5687                     SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, zVfs);
  5677   5688       if( rc!=SQLITE_OK ){
  5678   5689         utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
  5679         -      sqlite3_close(pDest);
         5690  +      close_db(pDest);
  5680   5691         return 1;
  5681   5692       }
  5682   5693       open_db(p, 0);
  5683   5694       pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
  5684   5695       if( pBackup==0 ){
  5685   5696         utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
  5686         -      sqlite3_close(pDest);
         5697  +      close_db(pDest);
  5687   5698         return 1;
  5688   5699       }
  5689   5700       while(  (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
  5690   5701       sqlite3_backup_finish(pBackup);
  5691   5702       if( rc==SQLITE_DONE ){
  5692   5703         rc = 0;
  5693   5704       }else{
  5694   5705         utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
  5695   5706         rc = 1;
  5696   5707       }
  5697         -    sqlite3_close(pDest);
         5708  +    close_db(pDest);
  5698   5709     }else
  5699   5710   
  5700   5711     if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
  5701   5712       if( nArg==2 ){
  5702   5713         bail_on_error = booleanValue(azArg[1]);
  5703   5714       }else{
  5704   5715         raw_printf(stderr, "Usage: .bail on|off\n");
................................................................................
  6506   6517   
  6507   6518     if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
  6508   6519       char *zNewFilename;  /* Name of the database file to open */
  6509   6520       int iName = 1;       /* Index in azArg[] of the filename */
  6510   6521       int newFlag = 0;     /* True to delete file before opening */
  6511   6522       /* Close the existing database */
  6512   6523       session_close_all(p);
  6513         -    sqlite3_close(p->db);
         6524  +    close_db(p->db);
  6514   6525       p->db = 0;
  6515   6526       p->zDbFilename = 0;
  6516   6527       sqlite3_free(p->zFreeOnClose);
  6517   6528       p->zFreeOnClose = 0;
  6518   6529       p->openMode = SHELL_OPEN_UNSPEC;
  6519   6530       /* Check for command-line arguments */
  6520   6531       for(iName=1; iName<nArg && azArg[iName][0]=='-'; iName++){
................................................................................
  6686   6697         raw_printf(stderr, "Usage: .restore ?DB? FILE\n");
  6687   6698         rc = 1;
  6688   6699         goto meta_command_exit;
  6689   6700       }
  6690   6701       rc = sqlite3_open(zSrcFile, &pSrc);
  6691   6702       if( rc!=SQLITE_OK ){
  6692   6703         utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
  6693         -      sqlite3_close(pSrc);
         6704  +      close_db(pSrc);
  6694   6705         return 1;
  6695   6706       }
  6696   6707       open_db(p, 0);
  6697   6708       pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
  6698   6709       if( pBackup==0 ){
  6699   6710         utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
  6700         -      sqlite3_close(pSrc);
         6711  +      close_db(pSrc);
  6701   6712         return 1;
  6702   6713       }
  6703   6714       while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
  6704   6715             || rc==SQLITE_BUSY  ){
  6705   6716         if( rc==SQLITE_BUSY ){
  6706   6717           if( nTimeout++ >= 3 ) break;
  6707   6718           sqlite3_sleep(100);
................................................................................
  6713   6724       }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
  6714   6725         raw_printf(stderr, "Error: source database is busy\n");
  6715   6726         rc = 1;
  6716   6727       }else{
  6717   6728         utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
  6718   6729         rc = 1;
  6719   6730       }
  6720         -    sqlite3_close(pSrc);
         6731  +    close_db(pSrc);
  6721   6732     }else
  6722   6733   
  6723   6734     if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
  6724   6735       if( nArg==2 ){
  6725   6736         p->scanstatsOn = (u8)booleanValue(azArg[1]);
  6726   6737   #ifndef SQLITE_ENABLE_STMT_SCANSTATUS
  6727   6738         raw_printf(stderr, "Warning: .scanstats not available in this build.\n");
................................................................................
  7397   7408       char **azResult;
  7398   7409       int nRow, nAlloc;
  7399   7410       int ii;
  7400   7411       ShellText s;
  7401   7412       initText(&s);
  7402   7413       open_db(p, 0);
  7403   7414       rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
  7404         -    if( rc ) return shellDatabaseError(p->db);
         7415  +    if( rc ){
         7416  +      sqlite3_finalize(pStmt);
         7417  +      return shellDatabaseError(p->db);
         7418  +    }
  7405   7419   
  7406   7420       if( nArg>2 && c=='i' ){
  7407   7421         /* It is an historical accident that the .indexes command shows an error
  7408   7422         ** when called with the wrong number of arguments whereas the .tables
  7409   7423         ** command does not. */
  7410   7424         raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
  7411   7425         rc = 1;
         7426  +      sqlite3_finalize(pStmt);
  7412   7427         goto meta_command_exit;
  7413   7428       }
  7414   7429       for(ii=0; sqlite3_step(pStmt)==SQLITE_ROW; ii++){
  7415   7430         const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
  7416   7431         if( zDbName==0 ) continue;
  7417   7432         if( s.z && s.z[0] ) appendText(&s, " UNION ALL ", 0);
  7418   7433         if( sqlite3_stricmp(zDbName, "main")==0 ){
................................................................................
  8750   8765       }else{
  8751   8766         rc = process_input(&data, stdin);
  8752   8767       }
  8753   8768     }
  8754   8769     set_table_name(&data, 0);
  8755   8770     if( data.db ){
  8756   8771       session_close_all(&data);
  8757         -    sqlite3_close(data.db);
         8772  +    close_db(data.db);
  8758   8773     }
  8759   8774     sqlite3_free(data.zFreeOnClose);
  8760   8775     find_home_dir(1);
  8761   8776     output_reset(&data);
  8762   8777     data.doXdgOpen = 0;
  8763   8778     clearTempFile(&data);
  8764   8779   #if !SQLITE_SHELL_IS_UTF8
  8765   8780     for(i=0; i<argcToFree; i++) free(argvToFree[i]);
  8766   8781     free(argvToFree);
  8767   8782   #endif
         8783  +  /* Clear the global data structure so that valgrind will detect memory
         8784  +  ** leaks */
         8785  +  memset(&data, 0, sizeof(data));
  8768   8786     return rc;
  8769   8787   }