-C Enhance\sthe\s".timer"\scommand\sin\sthe\sCLI\sto\saccept\sthe\s"once"\sargument,\sand\nso\sthat\sit\sleaves\sits\slast\sreal-time\sresult\sin\sthe\s$TIMER\svariable.\s\sAlso\nfix\sa\sharmless\swarning\sfrom\san\searlier\scheck-in.
-D 2026-02-01T15:58:37.050
+C Add\sthe\s"--timeout\sSECONDS"\soption\sto\sthe\s".progress"\scommand\sin\sthe\sCLI.
+D 2026-02-01T21:10:04.562
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F src/resolve.c 47aa7fdc9ec4c19b103ac5e79d7887d30119b5675309facf5eed1118391c868b
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c 098caf322d17cd480a5ebd81b9252b9ad90c72be7d5cdc5875e4a0a43e0ba965
-F src/shell.c.in 4dfd1ff15cdfac8778a5dcd6c0f3db1789d0919e79c9725cc7255d1d9bb1e273
+F src/shell.c.in fe1ad71964401a1bd1fc396aa524634096bcbe6cb20b0091a19490e1789431fb
F src/sqlite.h.in 8bcbaecfe2cbecf8c5c1381354fcdd7d307443e88b4953fccb222456c1267b61
F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
F src/sqlite3ext.h 1b7a0ee438bb5c2896d0609c537e917d8057b3340f6ad004d2de44f03e3d3cca
F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
-P 3a4f9a323da90611d7eda51b90cb058175ddde0a128e1ff00ce58cc83af0f376
-R af9796fbe8093a32969c1859761a2b45
+P 8ad7dffc261cbb3f7c9b4d38b04282c805c1c047fb431076f85e577c81f21574
+R 2d766d3f9106b9758f2dee16c9d48a97
U drh
-Z 7d607b0d09ce1651ab8b2dc2f7cb7118
+Z 9b3d450c8e9b37984aed24bcaa27a771
# Remove this line to create a well-formed Fossil manifest.
u8 enableTimer; /* Enable the timer. 2: permanently 1: only once */
int inputNesting; /* Track nesting level of .read and other redirects */
double prevTimer; /* Last reported timer value */
+ double tmProgress; /* --timeout option for .progress */
i64 lineno; /* Line number of last line read from in */
const char *zInFile; /* Name of the input file */
int openFlags; /* Additional flags to open. (SQLITE_OPEN_NOFOLLOW) */
** callback limit is reached, and for each
** top-level SQL statement */
#define SHELL_PROGRESS_ONCE 0x04 /* Cancel the --limit after firing once */
+#define SHELL_PROGRESS_TMOUT 0x08 /* Stop after tmProgress seconds */
/* Names of values for Mode.spec.eEsc and Mode.spec.eText
*/
** Begin timing an operation
*/
static void beginTimer(ShellState *p){
- if( p->enableTimer ){
+ if( p->enableTimer || (p->flgProgress & SHELL_PROGRESS_TMOUT)!=0 ){
getrusage(RUSAGE_SELF, &sBegin);
iBegin = timeOfDay();
}
(double)(pEnd->tv_sec - pStart->tv_sec);
}
+/* Return the time since the start of the timer in
+** seconds. */
+static double elapseTime(ShellState *NotUsed){
+ (void)NotUsed;
+ if( iBegin==0 ) return 0.0;
+ return (timeOfDay() - iBegin)*0.000001;
+}
+
/*
** Print the timing results.
*/
timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
if( p->enableTimer==1 ) p->enableTimer = 0;
+ iBegin = 0;
}
}
#define BEGIN_TIMER(X) beginTimer(X)
#define END_TIMER(X) endTimer(X)
+#define ELAPSE_TIME(X) elapseTime(X)
#define HAS_TIMER 1
#elif (defined(_WIN32) || defined(WIN32))
** Begin timing an operation
*/
static void beginTimer(ShellState *p){
- if( p->enableTimer && getProcessTimesAddr ){
+ if( (p->enableTimer || (p->flgProgress & SHELL_PROGRESS_TMOUT)!=0)
+ && getProcessTimesAddr
+ ){
FILETIME ftCreation, ftExit;
getProcessTimesAddr(hProcess,&ftCreation,&ftExit,
&ftKernelBegin,&ftUserBegin);
return (double) ((i64End - i64Start) / 10000000.0);
}
+/* Return the time since the start of the timer in
+** seconds. */
+static double elapseTime(ShellState *NotUsed){
+ (void)NotUsed;
+ if( ftWallBegin==0 ) return 0.0;
+ return (timeOfDay() - ftWallBegin)*0.000001;
+}
+
/*
** Print the timing results.
*/
timeDiff(&ftKernelBegin, &ftKernelEnd));
#endif
if( p->enableTimer==1 ) p->enableTimer = 0;
+ ftWallBegin = 0;
}
}
#define BEGIN_TIMER(X) beginTimer(X)
+#define ELAPSE_TIME(X) elapseTime(X)
#define END_TIMER(X) endTimer(X)
#define HAS_TIMER hasTimer()
#else
#define BEGIN_TIMER(X) /* no-op */
+#define ELAPSE_TIME(X) 0.0
#define END_TIMER(X) /*no-op*/
#define HAS_TIMER 0
#endif
static int progress_handler(void *pClientData) {
ShellState *p = (ShellState*)pClientData;
p->nProgress++;
+ if( (p->flgProgress & SHELL_PROGRESS_TMOUT)!=0
+ && ELAPSE_TIME(p)>=p->tmProgress
+ ){
+ cli_printf(p->out, "Progress timeout after %.6f seconds\n",
+ ELAPSE_TIME(p));
+ return 1;
+ }
if( p->nProgress>=p->mxProgress && p->mxProgress>0 ){
cli_printf(p->out, "Progress limit reached (%u)\n", p->nProgress);
if( p->flgProgress & SHELL_PROGRESS_RESET ) p->nProgress = 0;
" --once Do no more than one progress interrupt",
" --quiet|-q No output except at interrupts",
" --reset Reset the count for each input and interrupt",
+ " --timeout S Halt after running for S seconds",
#endif
".prompt MAIN CONTINUE Replace the standard prompts",
#ifndef SQLITE_SHELL_FIDDLE
p->flgProgress |= SHELL_PROGRESS_ONCE;
continue;
}
+ if( cli_strcmp(z,"timeout")==0 ){
+ if( i==nArg-1 ){
+ dotCmdError(p, i, "missing argument", 0);
+ return 1;
+ }
+ i++;
+ p->tmProgress = atof(azArg[i]);
+ if( p->tmProgress>0.0 ){
+ p->flgProgress = SHELL_PROGRESS_QUIET|SHELL_PROGRESS_TMOUT;
+ if( nn==0 ) nn = 100;
+ }
+ continue;
+ }
if( cli_strcmp(z,"limit")==0 ){
if( i+1>=nArg ){
eputz("Error: missing argument on --limit\n");