diff --git a/sh.h b/sh.h index f4f13243..f10eeb87 100644 --- a/sh.h +++ b/sh.h @@ -1083,6 +1083,7 @@ EXTERN struct Hist { Char *histline; struct Hist *Hnext, *Hprev; /* doubly linked list */ unsigned Hhash; /* hash value of command line */ + Char Hstatus[4]; /* status code 0 - 255 */ } Histlist IZERO_STRUCT; extern struct wordent paraml; /* Current lexical word list */ diff --git a/sh.hist.c b/sh.hist.c index b8553fdc..0db541aa 100644 --- a/sh.hist.c +++ b/sh.hist.c @@ -37,6 +37,7 @@ extern int histvalid; extern struct Strbuf histline; +extern Char Hstatus[4]; Char HistLit = 0; static int heq (const struct wordent *, const struct wordent *); @@ -49,6 +50,7 @@ static void hfree (struct Hist *); #define HIST_CLEAR 0x10 #define HIST_MERGE 0x20 #define HIST_TIME 0x40 +#define HIST_SCODE 0x80 /* * C shell @@ -68,6 +70,7 @@ static unsigned histCount = 0; /* number elements on history list */ static int histlen = 0; static struct Hist *histTail = NULL; /* last element on history list */ static struct Hist *histMerg = NULL; /* last element merged by Htime */ +struct Hist *current_hist; static void insertHistHashTable(struct Hist *, unsigned); @@ -980,11 +983,15 @@ enthist( /* Pick up timestamp set by lex() in Htime if reading saved history */ if (Htime != 0) { np->Htime = Htime; - Htime = 0; + Strncpy(np->Hstatus, Hstatus, 4); + Htime = 0; } - else + else { (void) time(&(np->Htime)); - + current_hist = np; + current_hist->Hstatus[0] = '0'; + current_hist->Hstatus[1] = '\0'; + } if (p == np) return np; /* reused existing entry */ @@ -1063,14 +1070,17 @@ phist(struct Hist *hp, int hflg) old_output_raw = output_raw; output_raw = 1; cleanup_push(&old_output_raw, output_raw_restore); - if (hflg & HIST_TIME) + if (hflg & HIST_TIME) { /* * Make file entry with history time in format: * "+NNNNNNNNNN" (10 digits, left padded with ascii '0') */ - xprintf("#+%010lu\n", (unsigned long)hp->Htime); - + xprintf("#+%010lu", (unsigned long)hp->Htime); + if (hp->Hstatus[0] != '\0') + xprintf(" %S", hp->Hstatus); + xprintf("\n"); + } if (HistLit && hp->histline) xprintf("%" TCSH_S "\n", hp->histline); else @@ -1078,10 +1088,18 @@ phist(struct Hist *hp, int hflg) cleanup_until(&old_output_raw); } else { - Char *cp = str2short("%h\t%T\t%R\n"); + char *fmt; + Char *cp; Char *p; struct varent *vp = adrof(STRhistory); + if (hflg & HIST_SCODE) + fmt = "%h%E\t%T\t%R\n"; + else + fmt = "%h\t%T\t%R\n"; + + cp = str2short(fmt); + if (vp && vp->vec != NULL && vp->vec[0] && vp->vec[1]) cp = vp->vec[1]; @@ -1147,6 +1165,9 @@ dohist(Char **vp, struct command *c) case 'r': hflg |= HIST_REV; break; + case 's': + hflg |= HIST_SCODE; + break; case 'S': hflg |= HIST_SAVE; break; @@ -1160,7 +1181,7 @@ dohist(Char **vp, struct command *c) hflg |= HIST_TIME; break; default: - stderror(ERR_HISTUS, "chrSLMT"); + stderror(ERR_HISTUS, "chrsSLMT"); break; } } @@ -1205,6 +1226,8 @@ fmthist(int fmt, ptr_t ptr) switch (fmt) { case 'h': return xasprintf("%6d", hp->Hnum); + case 'E': + return xasprintf("%*s", sizeof(hp->Hstatus)/sizeof(Char), hp->Hstatus); case 'R': if (HistLit && hp->histline) return xasprintf("%" TCSH_S, hp->histline); diff --git a/sh.lex.c b/sh.lex.c index bc2d07f7..9788e795 100644 --- a/sh.lex.c +++ b/sh.lex.c @@ -131,6 +131,7 @@ static Char getCtmp; * if reading saved history (sg) */ time_t Htime = (time_t)0; +Char Hstatus[4]; static time_t a2time_t (Char *); /* @@ -328,6 +329,14 @@ word(int parsehtime) c = getC(0); if (h < 11 && parsehtime) hbuf[h++] = c; + else if (h == 11 & parsehtime) { + Hstatus[0] = '\0'; + h++; + } + else if (h < 15 && parsehtime) { + Hstatus[h++ - 12] = c; + Hstatus[h - 12] = '\0'; + } } while (c != '\n'); if (parsehtime) { hbuf[11] = '\0'; diff --git a/sh.set.c b/sh.set.c index 18fcdbd8..c6857495 100644 --- a/sh.set.c +++ b/sh.set.c @@ -37,6 +37,7 @@ #include #endif +extern struct Hist *current_hist; extern int GotTermCaps; int numeof = 0; @@ -1357,12 +1358,16 @@ update_wordchars(void) void setstrstatus(Char *str) { + if (current_hist) + Strncpy(current_hist->Hstatus, str, 3); setv(STRstatus, str, VAR_READWRITE|VAR_NOERROR); } void setstatus(int n) { + if (current_hist) + Strncpy(current_hist->Hstatus, n ? STR1 : STR0, 3); setcopy(STRstatus, n ? STR1 : STR0, VAR_READWRITE|VAR_NOERROR); } diff --git a/tc.prompt.c b/tc.prompt.c index ae4211ae..a32594d6 100644 --- a/tc.prompt.c +++ b/tc.prompt.c @@ -198,6 +198,13 @@ tprintf(int what, const Char *fmt, const char *str, time_t tim, ptr_t info) if ((*cp == '%') && ! (cp[1] == '\0')) { cp++; switch (*cp) { + case 'E': + if (what == FMT_HISTORY) { + cz = fmthist('E', info); + tprintf_append_mbs(&buf, cz, attributes); + xfree(cz); + } + break; case 'R': if (what == FMT_HISTORY) { cz = fmthist('R', info); diff --git a/tcsh.man.in b/tcsh.man.in index 5e3240dd..f2d5091b 100644 --- a/tcsh.man.in +++ b/tcsh.man.in @@ -5577,7 +5577,7 @@ hash buckets. .Bl -tag -width 6n -compact . .It Ic history Xo -.Op Fl hTr +.Op Fl hTrs .Op Ar n .Xc .It Ic history Xo @@ -5612,6 +5612,10 @@ With the order of printing is most recent first rather than oldest first. .Pp +With +.Fl s , +the exit status of each command is printed as an additional column. +.Pp The second form with .Fl S saves the history list to diff --git a/win32/ntfunc.c b/win32/ntfunc.c index a7da6e07..11ead44e 100644 --- a/win32/ntfunc.c +++ b/win32/ntfunc.c @@ -1052,7 +1052,7 @@ int nt_texec(char *prog, char**args ) { if(!gui_app) { WaitForSingleObject(pi.hProcess,INFINITE); (void)GetExitCodeProcess(pi.hProcess,&exitcode); - setv(STRstatus, putn(exitcode), VAR_READWRITE);/*FIXRESET*/ + setstatus(exitcode); } retval = 0; CloseHandle(pi.hProcess);