Closed naksyl closed 1 year ago
OMG my formula duration = (stop.tv_sec - start.tv_sec)*1000000 - (stop.tv_usec - start.tv_usec);
is wrong, should be:
duration = (stop.tv_sec - start.tv_sec)*1000000 + (stop.tv_usec - start.tv_usec);
The shell features required by starship
are also lacking in upstream BusyBox. This isn't a Windows-specific problem.
In such cases I prefer to try to get support upstream first:
The problem then becomes "What will upstream accept?".
bash
support in starship
uses trap DEBUG
and PROMPT_COMMAND
. Getting both of these upstream is likely to be challenging.bash
compatible features would be pre- and post-execution hooks, as supported by other shells, such as zsh
. But upstream has no history of accepting shell features from anywhere other than bash
.Upstream is unlikely to see support for starship
as a priority (and I have a similar view relative to busybox-w32) so there would need to be other benefits to sell the proposition.
Ok, thanks for reply and Your work on windows port.
I would like to make posible to put command duration and job count on PS1. Bash for this purpose using
trap DEBUG
but busybox lacks such functionality. After couple of hours digging in ash source code jungle I manage to code quick and dirty solution (which suprisingly works - mostly). The main idea is to expose three variables to shell:CMDREALTIME
(this may stay hidden - but its nicely paired withEPOCHREALTIME
)- command start time,CMDDURATION
integral value in usec andJOBSNUM
. I admit that I have no expierience in C (doing stuff in Java and C++/Qt) so don't be rude.ash.diff
```diff diff --git a/shell/ash.c b/shell/ash.c index d0ecd501a..f1a6b376a 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -2413,8 +2413,11 @@ static void change_random(const char *) FAST_FUNC; #if BASH_EPOCH_VARS static void change_seconds(const char *) FAST_FUNC; static void change_realtime(const char *) FAST_FUNC; +static void change_duration(void) FAST_FUNC; +#endif +#if JOBS_WIN32 +static void change_jobs(void) FAST_FUNC; #endif - #if ENABLE_PLATFORM_MINGW32 static void FAST_FUNC change_terminal_mode(const char *newval UNUSED_PARAM) @@ -2462,6 +2465,11 @@ static const struct { #if BASH_EPOCH_VARS { VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "EPOCHSECONDS", change_seconds }, { VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "EPOCHREALTIME", change_realtime }, + { VSTRFIXED|VTEXTFIXED|VUNSET, "CMDDURATION", NULL }, + { VSTRFIXED|VTEXTFIXED|VUNSET, "CMDREALTIME", NULL }, +#endif +#if JOBS_WIN32 + { VSTRFIXED|VTEXTFIXED|VUNSET, "JOBSNUM", NULL }, #endif #if ENABLE_LOCALE_SUPPORT { VSTRFIXED|VTEXTFIXED|VUNSET, "LC_ALL" , change_lc_all }, @@ -2528,6 +2536,12 @@ extern struct globals_var *BB_GLOBAL_CONST ash_ptr_to_globals_var; #if BASH_EPOCH_VARS # define vepochs varinit[VAR_OFFSET3 + 7] # define vepochr varinit[VAR_OFFSET3 + 8] +# define vduration varinit[VAR_OFFSET3 + 9] +# define vcmdr varinit[VAR_OFFSET3 + 10] +#endif +#define VAR_OFFSET4 (VAR_OFFSET3 + (BASH_EPOCH_VARS*4)) +#if JOBS_WIN32 +# define vjobs varinit[VAR_OFFSET4 + 7] #endif #define INIT_G_var() do { \ unsigned i; \ @@ -2562,7 +2576,9 @@ extern struct globals_var *BB_GLOBAL_CONST ash_ptr_to_globals_var; #if ENABLE_ASH_GETOPTS # define optindval() (voptind.var_text + 7) #endif - +#if BASH_EPOCH_VARS +# define cmdrval() (vcmdr.var_text + 12) +#endif #if ENABLE_ASH_GETOPTS static void FAST_FUNC getoptsreset(const char *value) @@ -12831,7 +12847,7 @@ change_random(const char *value) #endif #if BASH_EPOCH_VARS -static void FAST_FUNC +static struct timeval FAST_FUNC change_epoch(struct var *vepoch, const char *fmt) { struct timeval tv; @@ -12841,6 +12857,7 @@ change_epoch(struct var *vepoch, const char *fmt) sprintf(buffer, fmt, (unsigned long long)tv.tv_sec, (unsigned)tv.tv_usec); setvar(vepoch->var_text, buffer, VNOFUNC); vepoch->flags &= ~VNOFUNC; + return tv; } static void FAST_FUNC @@ -12854,8 +12871,40 @@ change_realtime(const char *value UNUSED_PARAM) { change_epoch(&vepochr, "%llu.%06u"); } -#endif +static void FAST_FUNC +change_duration(void) +{ + struct timeval start; + struct timeval stop; + char buff[32]; + char *ptr = strchr(cmdrval(), '.'); + unsigned long long duration = 0; + + start.tv_sec = strtoul(cmdrval(), NULL, 10); + start.tv_usec = strtoul(++ptr, NULL, 10); + stop = change_epoch(&vepochr, "%llu.%06u"); + + // calculate duration as integer microsecs + duration = (stop.tv_sec - start.tv_sec)*1000000 - (stop.tv_usec - start.tv_usec); + sprintf(buff, "%llu", duration); + setvar(vduration.var_text, buff, VNOFUNC); + vduration.flags &= ~VNOFUNC; +} +#endif +#if JOBS_WIN32 +static void FAST_FUNC +change_jobs(void) +{ + unsigned count = 0; + struct job *jp = curjob; + while (jp) { + count++; + jp = jp->prev_job; + } + setvar(vjobs.var_text, utoa(count), VNOFUNC); +} +#endif #if ENABLE_ASH_GETOPTS static int getopts(char *optstr, char *optvar, char **optfirst) @@ -14799,6 +14848,7 @@ cmdloop(int top) #if JOBS || JOBS_WIN32 if (doing_jobctl) showjobs(SHOW_CHANGED|SHOW_STDERR); + change_jobs(); #endif inter = 0; if (iflag && top) { @@ -14829,13 +14879,18 @@ cmdloop(int top) numeof++; } else { int i; - #if !ENABLE_PLATFORM_MINGW32 /* job_warning can only be 2,1,0. Here 2->1, 1/0->0 */ job_warning >>= 1; #endif numeof = 0; +#if BASH_EPOCH_VARS + change_epoch(&vcmdr, "%llu.%.06u"); +#endif i = evaltree(n, 0); +#if BASH_EPOCH_VARS + change_duration(); +#endif if (n) status = i; } ```Problems encountered:
CTRL+D
with background jobs CMDDURATION is not reset (growing).Just notice warnings from Windows defender - after frequently killing jobs - maybe this has something to do with negative
CMDDURATION
.It seem that best place for my
change_epoch
andchange_duration
is right around call toevaltree
atash.c:14890
Can somebody help me find the right spot to update those variables?Screenshots
![Zrzut ekranu 2023-08-10 224641](https://github.com/rmyorston/busybox-w32/assets/17428477/04ec588c-e035-4d0a-afdf-340b1f3fe7e0) ![Zrzut ekranu 2023-08-11 002010](https://github.com/rmyorston/busybox-w32/assets/17428477/312dda09-095f-4b81-9188-28689e2b3a50)