]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
In the CLI, eliminate the 2-second delay before getting the prompt back
authordrh <>
Sat, 25 Apr 2026 16:17:23 +0000 (16:17 +0000)
committerdrh <>
Sat, 25 Apr 2026 16:17:23 +0000 (16:17 +0000)
after running a ".www" or ".excel".  Instead, remember the name of the
temporary file that is to be deleted and delete it later.

FossilOrigin-Name: 4e9ee211ca661fe8978b7f676f33ef962ff5c8177bc7c5ad42b19a2fa4482d90

manifest
manifest.uuid
src/shell.c.in

index 206f1f645e716811683b6003608254209ad3ac8e..63c8de67089fbf273fe3e323a59ca7c1b53d0146 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Simplify\sthe\smodePush()/modePop()\simplementation\sin\sthe\sCLI.
-D 2026-04-25T15:05:46.435
+C In\sthe\sCLI,\seliminate\sthe\s2-second\sdelay\sbefore\sgetting\sthe\sprompt\sback\nafter\srunning\sa\s".www"\sor\s".excel".\s\sInstead,\sremember\sthe\sname\sof\sthe\ntemporary\sfile\sthat\sis\sto\sbe\sdeleted\sand\sdelete\sit\slater.
+D 2026-04-25T16:17:23.297
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -736,7 +736,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
 F src/resolve.c 928ff887f2a7c64275182060d94d06fdddbe32226c569781cf7e7edc6f58d7fd
 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
 F src/select.c 4c05cde130f26991b7411d8c6809e0630625e18078742c963a047b4b9cc01d49
-F src/shell.c.in 70879f02b889444ec68d9711d4cf62f47c02f95a9bdbfe08cf47a6493ebdc692
+F src/shell.c.in 0c22dd2c11ff87d4904d990dba632940102012d55a9d221940958ad6afe09506
 F src/sqlite.h.in 39d2e09114d2bdb7afd998f4a469c8f8cd065f8093835a7d0422f260fc78fb4f
 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
 F src/sqlite3ext.h 9788c301f95370fa30e808861f1d2e6f022a816ddbe2a4f67486784c1b31db2e
@@ -2203,8 +2203,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
 F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
 F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
-P 11cfbae735669776c967522294b1606af90b4bd5379e2e1ed722520887b57757
-R ce7f4db60dba8b68ab7b6539006ae917
+P 92cad2cd7284d3a969b713336865007da2b0b2a8eef367d4185802174cbd027a
+R d17ad9dd57a963733572b44ccb3c359d
 U drh
-Z 8bf3c788d3ebdc6dce6b0a5a48919414
+Z 936ee9dc91c7afce31c375f047aeb7da
 # Remove this line to create a well-formed Fossil manifest.
index 7e9bdffb9887ed63ddcc920bb7d762f08dd7199a..b2e522f26496669e92c1f45a365ad70a222701a2 100644 (file)
@@ -1 +1 @@
-92cad2cd7284d3a969b713336865007da2b0b2a8eef367d4185802174cbd027a
+4e9ee211ca661fe8978b7f676f33ef962ff5c8177bc7c5ad42b19a2fa4482d90
index 6c08093a400afa7fdbaf57ff28f3fd5a3afc3494..38e556bcbad8188470f404a28e5b822a22c5808e 100644 (file)
@@ -356,6 +356,13 @@ typedef struct Mode {
 #define MFLG_CRLF  0x02  /* Use CR/LF output line endings */
 #define MFLG_HDR   0x04  /* .header used to change headers on/off */
 
+/* A file that needs to be deleted, but only after a delay.
+*/
+typedef struct Unlink {
+  sqlite3_int64 tm;      /* Unlink after this time */
+  char *zFN;             /* Name of file.  Space from sqlite3_malloc() */
+} Unlink;
+
 /*
 ** State information about the database connection is contained in an
 ** instance of the following structure.
@@ -403,6 +410,8 @@ struct ShellState {
   Mode mode;             /* Current display mode */
   Mode *aModeStack;      /* Backups */
   unsigned nModeStack;   /* Number of entries in aModeStack[] */
+  unsigned nUnlink;      /* Number of entries in aDelayUnlink[] */
+  Unlink *aUnlink;       /* Temp files to unlink after a delay */
   struct SavedMode {     /* Ability to define custom mode configurations */
     char *zTag;            /* Name of this saved mode */
     Mode mode;              /* The saved mode */
@@ -5828,7 +5837,12 @@ static void output_reset(ShellState *p){
         /* Give the start/open/xdg-open command some time to get
         ** going before we continue and potentially delete the
         ** p->zTempFile data file out from under it */
-        sqlite3_sleep(2000);
+        p->aUnlink = realloc(p->aUnlink, sizeof(Unlink)*(1+p->nUnlink));
+        shell_check_oom(p->aUnlink);
+        p->aUnlink[p->nUnlink].tm = timeOfDay()+10000;
+        p->aUnlink[p->nUnlink].zFN = p->zTempFile;
+        p->nUnlink++;
+        p->zTempFile = 0;
       }
       sqlite3_free(zCmd);
       modePop(p);
@@ -6241,29 +6255,84 @@ static char *shellFilenameFromUri(const char *zFN){
 
 /*
 ** Delete a file.
+**
+** If unsuccessful on the first attempt and if pRetry!=NULL and pRetry[0]
+** is positive, then delay for pRetry[0] milliseconds and try again.  On
+** a retry, pRetry[0] is set to zero.
+**
+** Return 0 on success and non-zero if unable.
 */
-int shellDeleteFile(const char *zFilename){
+int shellDeleteFile(const char *zFilename, int *pRetry){
   int rc;
+  for(;;){
 #ifdef _WIN32
-  wchar_t *z = sqlite3_win32_utf8_to_unicode(zFilename);
-  rc = _wunlink(z);
-  sqlite3_free(z);
+    wchar_t *z = sqlite3_win32_utf8_to_unicode(zFilename);
+    rc = _wunlink(z);
+    sqlite3_free(z);
 #else
-  rc = unlink(zFilename);
+    rc = unlink(zFilename);
 #endif
+    if( rc && pRetry && pRetry[0] ){
+      sqlite3_sleep(pRetry[0]);
+      pRetry[0] = 0;
+      continue;
+    }
+    break;
+  }
   return rc;
 }
 
 /*
-** Try to delete the temporary file (if there is one) and free the
-** memory used to hold the name of the temp file.
+** Try to delete the temporary file (if there is one) with the name
+** p->zTempFile and free the memory used to hold the name of the temp file.
+** If there are any entries in p->aUnlink[] that are old enough, then
+** delete those too, also reclaiming memory.
+**
+** If retry is non-zero and a deletion attempt is not successful,
+** wait for retry milliseconds and try again before giving up.
+** When retry is non-zero, memory is always reclaimed even if the
+** file deletion attempt fails.
+**
+** If bForce is true, deletion is attempted on p->aUnlink[] files
+** even time has not expired.
+**
+** When retry is zero and the deletion attempt fails,
+** memory is not reclaimed.
 */
-static void clearTempFile(ShellState *p){
-  if( p->zTempFile==0 ) return;
-  if( p->doXdgOpen ) return;
-  if( shellDeleteFile(p->zTempFile) ) return;
-  sqlite3_free(p->zTempFile);
-  p->zTempFile = 0;
+static void clearTempFile(ShellState *p, int retry, int bForce){
+  int alwaysFree = retry>0;
+  int rc = 0;
+  if( p->zTempFile && !p->doXdgOpen ){
+    rc = shellDeleteFile(p->zTempFile, &retry);
+    if( rc==0 || alwaysFree ){
+      sqlite3_free(p->zTempFile);
+      p->zTempFile = 0;
+    }
+  }
+  if( p->nUnlink ){
+    unsigned int i;
+    for(i=0; i<p->nUnlink; i++){
+      if( p->aUnlink[i].tm<timeOfDay()
+       || (bForce && alwaysFree && sqlite3_sleep(retry)>=0)
+      ){
+        char *zFN = p->aUnlink[i].zFN;
+        rc = shellDeleteFile(zFN, &retry);
+        if( rc==0 || alwaysFree ){
+          sqlite3_free(p->aUnlink[i].zFN);
+          p->nUnlink--;
+          if( i<p->nUnlink ){
+            p->aUnlink[i] = p->aUnlink[p->nUnlink];
+            memset(&p->aUnlink[p->nUnlink], 0, sizeof(Unlink));
+          }
+          i--;
+        }
+      }
+    }
+    if( p->nUnlink==0 ){
+      free(p->aUnlink);
+      p->aUnlink = 0;
+    }
+  }  
 }
 
 /* Forward reference */
@@ -6293,7 +6362,7 @@ static void newTempFile(ShellState *p, const char *zSuffix){
     r /= 36;
   }
   zRand[i] = 0;
-  clearTempFile(p);
+  clearTempFile(p,1000,0);
   sqlite3_free(p->zTempFile);
   p->zTempFile = 0;
   zHome = find_home_dir(0);
@@ -9405,7 +9474,7 @@ static int do_meta_command(const char *zLine, ShellState *p){
   if( nArg==0 ) return 0; /* no tokens, no error */
   n = strlen30(azArg[0]);
   c = azArg[0][0];
-  clearTempFile(p);
+  clearTempFile(p,0,0);
 
 #ifndef SQLITE_OMIT_AUTHORIZATION
   if( c=='a' && cli_strncmp(azArg[0], "auth", n)==0 ){
@@ -10641,10 +10710,10 @@ static int do_meta_command(const char *zLine, ShellState *p){
         if( cli_strncmp(zFN,"file:",5)==0 ){
           char *zDel = shellFilenameFromUri(zFN);
           shell_check_oom(zDel);
-          shellDeleteFile(zDel);
+          shellDeleteFile(zDel, 0);
           sqlite3_free(zDel);
         }else{
-          shellDeleteFile(zFN);
+          shellDeleteFile(zFN, 0);
         }
       }
 #ifndef SQLITE_SHELL_FIDDLE
@@ -12913,7 +12982,7 @@ static int process_input(ShellState *p, const char *zSrc){
         output_reset(p);
         p->nPopOutput = 0;
       }else{
-        clearTempFile(p);
+        clearTempFile(p,0,0);
       }
       if( p->nPopMode ){
         modePop(p);
@@ -13963,7 +14032,7 @@ int SQLITE_CDECL main(int argc, char **argv){
         output_reset(&data);
         data.nPopOutput = 0;
       }else{
-        clearTempFile(&data);
+        clearTempFile(&data,0,0);
       }
     }
   }else{
@@ -14042,7 +14111,7 @@ int SQLITE_CDECL main(int argc, char **argv){
   find_home_dir(1);
   output_reset(&data);
   data.doXdgOpen = 0;
-  clearTempFile(&data);
+  clearTempFile(&data,1000,1);
   while( data.nModeStack ) modePop(&data);
   free(data.aModeStack);
   modeFree(&data.mode);