From c6c5f0dcfe7ba392b99a799c5aefbdc3a3d88ef6 Mon Sep 17 00:00:00 2001 From: Vojtech Vitek (V-Teq) Date: Jun 06 2012 12:08:07 +0000 Subject: Update to tcsh-6.18.00 - adapt tcsh-6.18.00-history-file-locking.patch Update the patch from http://github.com/VojtechVitek/tcsh/commit/e59f1ed7c4a23b7b72eb45b57909266e7c20a780 --- diff --git a/tcsh-6.18.00-history-file-locking.patch b/tcsh-6.18.00-history-file-locking.patch index 1df5f78..01b6102 100644 --- a/tcsh-6.18.00-history-file-locking.patch +++ b/tcsh-6.18.00-history-file-locking.patch @@ -1,27 +1,26 @@ -From d73747f08a9576f360e0e0b6c5f537547c30c5fa Mon Sep 17 00:00:00 2001 +From e59f1ed7c4a23b7b72eb45b57909266e7c20a780 Mon Sep 17 00:00:00 2001 From: "Vojtech Vitek (V-Teq)" -Date: Thu, 15 Mar 2012 03:13:01 +0100 -Subject: [PATCH] Implement .history file locking - shared readers, exclusive - writer +Date: Wed, 16 May 2012 19:07:09 +0200 +Subject: [PATCH] Add .history file locking - shared readers, exclusive writer Originally reported at Red Hat Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=648592 Patch by Vojtech Vitek (V-Teq) --- - sh.c | 91 ++++++++++++++++++++++++++++++++++++++++++++---------------- - sh.decls.h | 5 ++- + sh.c | 103 +++++++++++++++++++++++++++++++++-------------- + sh.decls.h | 5 +- sh.dir.c | 2 +- sh.dol.c | 2 +- - sh.err.c | 16 ++++++++++ - sh.h | 17 +++++++++++ - sh.hist.c | 62 +++++++++++++++++++++++------------------ + sh.err.c | 16 +++++++ + sh.h | 18 ++++++++ + sh.hist.c | 131 ++++++++++++++++++++++++++++++------------------------------ sh.lex.c | 8 ++-- sh.sem.c | 2 +- - 9 files changed, 145 insertions(+), 60 deletions(-) + 9 files changed, 183 insertions(+), 104 deletions(-) diff --git a/sh.c b/sh.c -index dcd9116..aaf32bc 100644 +index 77e75cb..febcad9 100644 --- a/sh.c +++ b/sh.c @@ -140,6 +140,7 @@ struct saved_state { @@ -37,11 +36,29 @@ index dcd9116..aaf32bc 100644 * Source history before .login so that it is available in .login */ - loadhist(NULL, 0); -+ loadhist(NULL, FD_RDLCK); ++ loadhist(NULL, HIST_FILE_RDLCK); #ifndef LOGINFIRST if (loginsh) (void) srccat(varval(STRhome), STRsldotlogin); -@@ -1522,20 +1523,52 @@ static int +@@ -1492,7 +1493,7 @@ static int + srccat(Char *cp, Char *dp) + { + if (cp[0] == '/' && cp[1] == '\0') +- return srcfile(short2str(dp), (mflag ? 0 : 1), 0, NULL); ++ return srcfile(short2str(dp), (mflag ? 0 : HIST_ONLY), 0, NULL); + else { + Char *ep; + char *ptr; +@@ -1508,7 +1509,7 @@ srccat(Char *cp, Char *dp) + cleanup_push(ep, xfree); + ptr = short2str(ep); + +- rv = srcfile(ptr, (mflag ? 0 : 1), 0, NULL); ++ rv = srcfile(ptr, (mflag ? 0 : HIST_ONLY), 0, NULL); + cleanup_until(ep); + return rv; + } +@@ -1522,20 +1523,49 @@ static int #else int #endif /*WINNT_NATIVE*/ @@ -60,70 +77,85 @@ index dcd9116..aaf32bc 100644 - (void) close_on_exec(unit, 1); - srcunit(unit, onlyown, flag, av); - return 1; -+ int *unit, copy; ++ int *unit; + + unit = xmalloc(sizeof(*unit)); + cleanup_push(unit, xfree); + *unit = xopen(f, O_LARGEFILE | -+ ((flg & FD_WRLCK) ? (O_CREAT|O_RDWR) : O_RDONLY), 0600); -+ -+ if (*unit == -1) { -+ if (!bequiet) -+ stderror(ERR_SYSTEM, f, strerror(errno)); -+ return -1; -+ } ++ ((flg & HIST_FILE_WRLCK) ? (O_CREAT|O_RDWR) : O_RDONLY), 0600); ++ if (*unit == -1) ++ return 0; /* Error. */ + + cleanup_push(unit, open_cleanup); + *unit = dmove(*unit, -1); + (void) close_on_exec(*unit, 1); -+ copy = *unit; + -+ if (flg & (FD_WRLCK | FD_RDLCK)) { ++ if (flg & (HIST_FILE_WRLCK | HIST_FILE_RDLCK)) { + struct flock fl; + -+ fl.l_type = (flg & FD_WRLCK) ? F_WRLCK : F_RDLCK; ++ fl.l_type = (flg & HIST_FILE_WRLCK) ? F_WRLCK : F_RDLCK; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + -+ if (fcntl(*unit, F_SETLKW, &fl) != -1) -+ cleanup_push(unit, fcntl_cleanup); ++ cleanup_push(unit, fcntl_cleanup); ++ if (fcntl(*unit, F_SETLKW, &fl) == -1) ++ cleanup_ignore(unit); + } + -+ srcunit(copy, onlyown, (flg & (SRC_HFLAG | SRC_MFLAG)), av); ++ srcunit(*unit, onlyown, flg, av); + -+ /* Close the unit, if we don't want to leave it open & locked. */ -+ if ((flg & (FD_WRLCK | FD_RDLCK)) && (!(flg & FD_LEAVE_LCKD))) { ++ /* Unlock the unit, if we don't want to leave it locked (or open). */ ++ if ((flg & (HIST_FILE_WRLCK | HIST_FILE_RDLCK)) && ++ (!(flg & HIST_FILE_LOCK) || !(flg & HIST_FILE_OPEN))) + cleanup_until(unit); /* fcntl_cleanup */ -+ if (!(flg & FD_LEAVE_OPEN)) { -+ cleanup_until(unit); /* open_cleanup */ -+ cleanup_until(unit); /* xfree */ -+ } + -+ return -1; /* Invalid file descriptor. */ ++ /* Close the unit, if we don't want to leave it open. */ ++ if (!(flg & HIST_FILE_OPEN)) { ++ cleanup_until(unit); /* open_cleanup */ ++ cleanup_until(unit); /* xfree */ ++ return -1; /* Not error but invalid file descriptor. */ + } + -+ return *unit; ++ return *unit; /* File descriptor (fd > FSAFE). */ } -@@ -1593,10 +1626,14 @@ st_save(struct saved_state *st, int unit, int hflg, Char **al, Char **av) +@@ -1544,7 +1574,7 @@ srcfile(const char *f, int onlyown, int flag, Char **av) + * fd. + */ + static void +-st_save(struct saved_state *st, int unit, int hflg, Char **al, Char **av) ++st_save(struct saved_state *st, int unit, int flg, Char **al, Char **av) + { + st->insource = insource; + st->SHIN = SHIN; +@@ -1593,10 +1623,14 @@ st_save(struct saved_state *st, int unit, int hflg, Char **al, Char **av) st->onelflg = onelflg; st->enterhist = enterhist; st->justpr = justpr; - if (hflg) -+ if (hflg && SRC_HFLAG) ++ if (flg & (HIST_ONLY | HIST_MERGE)) st->HIST = HIST; else st->HIST = '\0'; -+ if (hflg && FD_LEAVE_OPEN) ++ if (flg & HIST_FILE_OPEN) + st->close_unit = 0; + else + st->close_unit = 1; st->cantell = cantell; cpybin(st->B, B); -@@ -1668,7 +1705,8 @@ st_restore(void *xst) +@@ -1635,7 +1669,7 @@ st_save(struct saved_state *st, int unit, int hflg, Char **al, Char **av) + evalp = 0; + alvec = al; + alvecp = 0; +- enterhist = hflg; ++ enterhist = flg & (HIST_ONLY | HIST_MERGE); + if (enterhist) + HIST = '\0'; + insource = 1; +@@ -1668,7 +1702,8 @@ st_restore(void *xst) } cpybin(B, st->B); @@ -133,7 +165,25 @@ index dcd9116..aaf32bc 100644 insource = st->insource; SHIN = st->SHIN; -@@ -2153,24 +2191,25 @@ process(int catch) +@@ -1704,7 +1739,7 @@ st_restore(void *xst) + * we don't chance it. This occurs on ".cshrc"s and the like. + */ + static void +-srcunit(int unit, int onlyown, int hflg, Char **av) ++srcunit(int unit, int onlyown, int flg, Char **av) + { + struct saved_state st; + +@@ -1730,7 +1765,7 @@ srcunit(int unit, int onlyown, int hflg, Char **av) + } + + /* Save the current state and move us to a new state */ +- st_save(&st, unit, hflg, NULL, av); ++ st_save(&st, unit, flg, NULL, av); + + /* + * Now if we are allowing commands to be interrupted, we let ourselves be +@@ -2153,24 +2188,25 @@ process(int catch) } /*ARGSUSED*/ @@ -146,7 +196,7 @@ index dcd9116..aaf32bc 100644 - int hflg = 0; char *file; + int fd; -+ int hflg = 0; ++ int newflg = 0; USE(c); t++; @@ -154,35 +204,38 @@ index dcd9116..aaf32bc 100644 if (*++t == NULL) stderror(ERR_NAME | ERR_HFLAG); - hflg++; -+ hflg |= SRC_HFLAG; ++ newflg |= HIST_ONLY; } else if (*t && eq(*t, STRmm)) { if (*++t == NULL) stderror(ERR_NAME | ERR_MFLAG); - hflg = 2; -+ hflg |= SRC_MFLAG; ++ newflg |= HIST_MERGE; } f = globone(*t++, G_ERROR); -@@ -2178,9 +2217,13 @@ dosource(Char **t, struct command *c) +@@ -2178,9 +2214,16 @@ dosource(Char **t, struct command *c) cleanup_push(file, xfree); xfree(f); t = glob_all_or_error(t); - if ((!srcfile(file, 0, hflg, t)) && (!hflg) && (!bequiet)) - stderror(ERR_SYSTEM, file, strerror(errno)); - cleanup_until(file); -+ fd = srcfile(file, 0, (hflg | flg), t); ++ fd = srcfile(file, 0, (flg | newflg), t); ++ if ((!fd) && (!newflg) && (!bequiet)) ++ stderror(ERR_SYSTEM, f, strerror(errno)); + -+ /* Postpone fd cleanup, which is on the top of cleaning stack. */ ++ /* We need to preserve fd and it's cleaning routines on the top of the ++ * cleaning stack. Don't call cleanup_until() but clean it manually. */ + cleanup_ignore(file); + xfree(file); + -+ return fd; /* File descriptor or -1. */ ++ return fd; /* Valid/invalid file descriptor (>FSAVE, -1). Zero on error. */ } /* diff --git a/sh.decls.h b/sh.decls.h -index db90288..d4332f3 100644 +index cd13288..d45c599 100644 --- a/sh.decls.h +++ b/sh.decls.h @@ -37,7 +37,7 @@ @@ -212,7 +265,7 @@ index db90288..d4332f3 100644 /* diff --git a/sh.dir.c b/sh.dir.c -index ab89855..4bfe430 100644 +index 058bc27..cf3b349 100644 --- a/sh.dir.c +++ b/sh.dir.c @@ -1342,7 +1342,7 @@ loaddirs(Char *fname) @@ -225,7 +278,7 @@ index ab89855..4bfe430 100644 } diff --git a/sh.dol.c b/sh.dol.c -index 45b10e0..02dfe98 100644 +index 5df8c60..7db7b60 100644 --- a/sh.dol.c +++ b/sh.dol.c @@ -1110,6 +1110,6 @@ again: @@ -237,7 +290,7 @@ index 45b10e0..02dfe98 100644 cleanup_until(&inheredoc); } diff --git a/sh.err.c b/sh.err.c -index e157d6a..29d41c3 100644 +index d8574cd..85093fa 100644 --- a/sh.err.c +++ b/sh.err.c @@ -514,6 +514,22 @@ open_cleanup(void *xptr) @@ -264,47 +317,221 @@ index e157d6a..29d41c3 100644 { DIR *dir; diff --git a/sh.h b/sh.h -index 691add3..558b093 100644 +index 88f7e90..1d13322 100644 --- a/sh.h +++ b/sh.h -@@ -50,6 +50,23 @@ +@@ -50,6 +50,24 @@ # include #endif +#include +#include ++ +/* -+ * Source flags (representing -h or -m). -+ * -+ * File locking flags. -+ * - shared and exclusive (read and write) access to a file -+ * - currently used in sh.c and sh.hist.c files while acessing -+ * ~/.history file only. ++ * History flags. + */ -+#define SRC_HFLAG 0x01 /* History flag */ -+#define SRC_MFLAG 0x02 /* Merge flag */ -+#define FD_WRLCK 0x04 /* Write lock */ -+#define FD_RDLCK 0x08 /* Read lock */ -+#define FD_LEAVE_OPEN 0x10 /* Leave file open */ -+#define FD_LEAVE_LCKD 0x20 /* Leave file locked */ ++#define HIST_ONLY 0x001 ++#define HIST_SAVE 0x002 ++#define HIST_LOAD 0x004 ++#define HIST_REV 0x008 ++#define HIST_CLEAR 0x010 ++#define HIST_MERGE 0x020 ++#define HIST_TIME 0x040 ++#define HIST_FILE_WRLCK 0x080 /* Write lock */ ++#define HIST_FILE_RDLCK 0x100 /* Read lock */ ++#define HIST_FILE_OPEN 0x200 /* Leave file open */ ++#define HIST_FILE_LOCK 0x400 /* Leave file locked */ + #if !defined(HAVE_STDINT_H) && !defined(HAVE_INTTYPES_H) && !defined(WINNT_NATIVE) typedef unsigned long intptr_t; #endif diff --git a/sh.hist.c b/sh.hist.c -index 6a12737..7df84e5 100644 +index 2482a13..4b4aa10 100644 --- a/sh.hist.c +++ b/sh.hist.c -@@ -1173,7 +1173,7 @@ dohist(Char **vp, struct command *c) +@@ -44,14 +44,6 @@ Char HistLit = 0; + static int heq (const struct wordent *, const struct wordent *); + static void hfree (struct Hist *); + +-#define HIST_ONLY 0x01 +-#define HIST_SAVE 0x02 +-#define HIST_LOAD 0x04 +-#define HIST_REV 0x08 +-#define HIST_CLEAR 0x10 +-#define HIST_MERGE 0x20 +-#define HIST_TIME 0x40 +- + /* + * C shell + */ +@@ -143,7 +135,7 @@ discardExcess(int histlen) + void + savehist( + struct wordent *sp, +- int mflg) /* true if -m (merge) specified */ ++ int flg) + { + int histlen = 0; + Char *cp; +@@ -160,7 +152,7 @@ savehist( + histlen = histlen * 10 + *cp++ - '0'; + } + if (sp) +- (void) enthist(++eventno, sp, 1, mflg, histlen); ++ (void) enthist(++eventno, sp, 1, flg, histlen); + discardExcess(histlen); + } + +@@ -933,7 +925,7 @@ enthist( + int event, /* newly incremented global eventno */ + struct wordent *lp, + int docopy, +- int mflg, /* true if merge requested */ ++ int flg, + int histlen) /* -1 if unknown */ + { + struct Hist *p = NULL, *pp = &Histlist, *pTime = NULL; +@@ -953,7 +945,7 @@ enthist( + Htime = p->Htime; + /* If we are merging, and the old entry is at the place we want + * to insert the new entry, then remember the place. */ +- if (mflg && Htime != 0 && p->Hprev->Htime >= Htime) ++ if ((flg & HIST_MERGE) && Htime != 0 && p->Hprev->Htime >= Htime) + pTime = p->Hprev; + if (!fastMergeErase) + renumberHist(p); /* Reset Href of subsequent entries */ +@@ -1012,7 +1004,7 @@ enthist( + /* The head of history list is the default insertion point. + If merging, advance insertion point, in pp, according to Htime. */ + /* XXX -- In histdup=all, Htime values can be non-monotonic. */ +- if (mflg) { /* merge according to np->Htime */ ++ if (flg & HIST_MERGE) { /* merge according to np->Htime */ + pp = mergeInsertionPoint(np, pTime); + for (p = pp->Hnext; p && p->Htime == np->Htime; pp = p, p = p->Hnext) { + if (heq(&p->Hlex, &np->Hlex)) { +@@ -1051,9 +1043,9 @@ hfree(struct Hist *hp) + } + + PG_STATIC void +-phist(struct Hist *hp, int hflg) ++phist(struct Hist *hp, int flg) + { +- if (hflg & HIST_ONLY) { ++ if (flg & HIST_ONLY) { + int old_output_raw; + + /* +@@ -1065,7 +1057,7 @@ 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 (flg & HIST_TIME) + /* + * Make file entry with history time in format: + * "+NNNNNNNNNN" (10 digits, left padded with ascii '0') +@@ -1096,7 +1088,7 @@ phist(struct Hist *hp, int hflg) + } + + PG_STATIC void +-dophist(int n, int hflg) ++dophist(int n, int flg) + { + struct Hist *hp; + if (setintr) { +@@ -1105,7 +1097,7 @@ dophist(int n, int hflg) + pintr_push_enable(&old_pintr_disabled); + cleanup_until(&old_pintr_disabled); + } +- if ((hflg & HIST_REV) == 0) { ++ if (!(flg & HIST_REV)) { + /* Since the history list is stored most recent first, non-reversing + * print needs to print (backwards) up the list. */ + if ((unsigned)n >= histCount) +@@ -1119,10 +1111,10 @@ dophist(int n, int hflg) + if (hp == NULL) + return; /* nothing to print */ + for (; hp != &Histlist; hp = hp->Hprev) +- phist(hp, hflg); ++ phist(hp, flg); + } else { + for (hp = Histlist.Hnext; n-- > 0 && hp != NULL; hp = hp->Hnext) +- phist(hp, hflg); ++ phist(hp, flg); + } + } + +@@ -1130,7 +1122,7 @@ dophist(int n, int hflg) + void + dohist(Char **vp, struct command *c) + { +- int n, hflg = 0; ++ int n, flg = 0; + + USE(c); + if (getn(varval(STRhistory)) == 0) +@@ -1141,40 +1133,40 @@ dohist(Char **vp, struct command *c) + while (*++vp2) + switch (*vp2) { + case 'c': +- hflg |= HIST_CLEAR; ++ flg |= HIST_CLEAR; + break; + case 'h': +- hflg |= HIST_ONLY; ++ flg |= HIST_ONLY; + break; + case 'r': +- hflg |= HIST_REV; ++ flg |= HIST_REV; + break; + case 'S': +- hflg |= HIST_SAVE; ++ flg |= HIST_SAVE; + break; + case 'L': +- hflg |= HIST_LOAD; ++ flg |= HIST_LOAD; + break; + case 'M': +- hflg |= HIST_MERGE; ++ flg |= HIST_MERGE; + break; + case 'T': +- hflg |= HIST_TIME; ++ flg |= HIST_TIME; + break; + default: + stderror(ERR_HISTUS, "chrSLMT"); + break; + } + } +- if (hflg & HIST_CLEAR) { ++ if (flg & HIST_CLEAR) { + struct Hist *np, *hp; + for (hp = &Histlist; (np = hp->Hnext) != NULL;) + hremove(np), hfree(np); } - if (hflg & (HIST_LOAD | HIST_MERGE)) +- if (hflg & (HIST_LOAD | HIST_MERGE)) - loadhist(*vp, (hflg & HIST_MERGE) ? 1 : 0); -+ loadhist(*vp, ((hflg & HIST_MERGE) ? SRC_MFLAG : 0) | FD_RDLCK); - else if (hflg & HIST_SAVE) +- else if (hflg & HIST_SAVE) ++ if (flg & (HIST_LOAD | HIST_MERGE)) ++ loadhist(*vp, (flg | HIST_FILE_RDLCK)); ++ else if (flg & HIST_SAVE) rechist(*vp, 1); else { -@@ -1224,8 +1224,8 @@ fmthist(int fmt, ptr_t ptr) + if (*vp) +@@ -1182,7 +1174,7 @@ dohist(Char **vp, struct command *c) + else { + n = getn(varval(STRhistory)); + } +- dophist(n, hflg); ++ dophist(n, flg); + } + } + +@@ -1224,8 +1216,8 @@ fmthist(int fmt, ptr_t ptr) void rechist(Char *fname, int ref) { @@ -315,15 +542,7 @@ index 6a12737..7df84e5 100644 struct varent *shist; static Char *dumphist[] = {STRhistory, STRmhT, 0, 0}; -@@ -1239,7 +1239,6 @@ rechist(Char *fname, int ref) - ((snum = varval(STRhistory)) == STRNULL)) - snum = STRmaxint; - -- - if (fname == NULL) { - if ((fname = varval(STRhistfile)) == STRNULL) - fname = Strspl(varval(STRhome), &STRtildothist[1]); -@@ -1255,15 +1254,12 @@ rechist(Char *fname, int ref) +@@ -1255,15 +1247,12 @@ rechist(Char *fname, int ref) * with numerous shells being in simultaneous use. Imagine * any kind of window system. All these shells 'share' the same * ~/.history file for recording their command line history. @@ -344,7 +563,7 @@ index 6a12737..7df84e5 100644 /* * We need the didfds stuff before loadhist otherwise * exec in a script will fail to print if merge is set. -@@ -1271,22 +1267,34 @@ rechist(Char *fname, int ref) +@@ -1271,32 +1260,42 @@ rechist(Char *fname, int ref) */ oldidfds = didfds; didfds = 0; @@ -357,31 +576,22 @@ index 6a12737..7df84e5 100644 - if (fp == -1) { - didfds = oldidfds; - return; -+ if ((shist = adrof(STRsavehist)) != NULL && shist->vec != NULL -+ && shist->vec[1] && eq(shist->vec[1], STRmerge)) { ++ if (((shist = adrof(STRsavehist)) != NULL && shist->vec != NULL) && ++ (shist->vec[1] && eq(shist->vec[1], STRmerge))) { + /* Read .history file, leave it's fd open for writing. */ -+ fd = loadhist(fname, SRC_MFLAG|FD_WRLCK|FD_LEAVE_OPEN|FD_LEAVE_LCKD); -+ if (fd != -1) { ++ fd = loadhist(fname, HIST_MERGE|HIST_FILE_WRLCK|HIST_FILE_OPEN|HIST_FILE_LOCK); ++ if (fd > 0) { + /* Truncate the .history file. */ + (void) ftruncate(fd, 0); + (void) lseek(fd, 0, SEEK_SET); + } - } -- ftmp = SHOUT; -- SHOUT = fp; -- dumphist[2] = snum; -- dohist(dumphist, NULL); -- xclose(fp); -- SHOUT = ftmp; -+ -+ /* Open .history file for writing (if not open yet). */ -+ if (fd == -1) { ++ } ++ if (fd <= 0) { ++ /* Open .history file for writing (if not open yet). */ + fd = xopen(short2str(fname), O_LARGEFILE|O_CREAT|O_WRONLY|O_TRUNC, 0600); -+ cleanup_until(fname); + if (fd != -1) + cleanup_push(&fd, open_cleanup); + } -+ + if (fd != -1) { + ftmp = SHOUT; + SHOUT = fd; @@ -389,13 +599,55 @@ index 6a12737..7df84e5 100644 + /* Write history to the .history file. */ + dohist(dumphist, NULL); + SHOUT = ftmp; -+ } -+ + } +- ftmp = SHOUT; +- SHOUT = fp; +- dumphist[2] = snum; +- dohist(dumphist, NULL); +- xclose(fp); +- SHOUT = ftmp; didfds = oldidfds; ++ cleanup_until(fname); } + + /* This is the entry point for loading history data from a file. */ +-void +-loadhist(Char *fname, int mflg) ++int ++loadhist(Char *fname, int flg) + { + static Char *loadhist_cmd[] = {STRsource, NULL, NULL, NULL}; +- loadhist_cmd[1] = mflg ? STRmm : STRmh; ++ int fd; ++ loadhist_cmd[1] = (flg & HIST_MERGE) ? STRmm : STRmh; + + if (fname != NULL) + loadhist_cmd[2] = fname; +@@ -1305,15 +1304,17 @@ loadhist(Char *fname, int mflg) + else + loadhist_cmd[2] = STRtildothist; + +- dosource(loadhist_cmd, NULL); ++ fd = dosource(loadhist_cmd, NULL, flg); + +- /* During history merging (enthist sees mflg set), we disable management of +- * Hnum and Href (because fastMergeErase is true). So now reset all the ++ /* During history merging (enthist sees merge flag), we disable management ++ * of Hnum and Href (because fastMergeErase is true). So now reset all the + * values based on the final ordering of the history list. */ +- if (mflg) { ++ if (flg & HIST_MERGE) { + int n = eventno; + struct Hist *hp = &Histlist; + while ((hp = hp->Hnext)) + hp->Hnum = hp->Href = n--; + } ++ ++ return fd; /* Valid/invalid file descriptor (>FSAVE, -1). Zero on error. */ + } diff --git a/sh.lex.c b/sh.lex.c -index 80643f7..e128789 100644 +index 08520dd..a87559d 100644 --- a/sh.lex.c +++ b/sh.lex.c @@ -1595,7 +1595,7 @@ wide_read(int fildes, Char *buf, size_t nchars, int use_fclens) @@ -435,7 +687,7 @@ index 80643f7..e128789 100644 fbuf = xcalloc(2, sizeof(Char **)); fblocks = 1; diff --git a/sh.sem.c b/sh.sem.c -index c880974..765bf50 100644 +index 99cd83c..92bef5d 100644 --- a/sh.sem.c +++ b/sh.sem.c @@ -892,7 +892,7 @@ doio(struct command *t, int *pipein, int *pipeout) @@ -448,5 +700,5 @@ index c880974..765bf50 100644 } else -- -1.7.6.5 +1.7.7.6 diff --git a/tcsh.spec b/tcsh.spec index 04a13e3..2dfeede 100644 --- a/tcsh.spec +++ b/tcsh.spec @@ -14,9 +14,10 @@ Patch4: tcsh-6.15.00-hist-sub.patch Patch8: tcsh-6.14.00-syntax.patch Patch9: tcsh-6.13.00-memoryuse.patch Patch11: tcsh-6.14.00-order.patch -# Proposed to upstream (http://bugs.gw.com/view.php?id=121) +# Proposed upstream - http://github.com/tcsh-org/tcsh/pull/1 Patch28: tcsh-6.17.00-manpage-spelling.patch -Patch31: tcsh-6.17.00-history-file-locking.patch +# Proposed upstream - http://github.com/tcsh-org/tcsh/pull/2 +Patch31: tcsh-6.18.00-history-file-locking.patch Provides: csh = %{version} Requires(post): grep @@ -132,6 +133,7 @@ fi tcsh-6.17.00-status-pipeline-backquote-list-of-cmds.patch (reverted!) - Modify and adapt the existing patches to the new source code: tcsh-6.13.00-memoryuse.patch, tcsh-6.14.00-tinfo.patch, + tcsh-6.18.00-history-file-locking.patch * Thu Feb 16 2012 Vojtech Vitek (V-Teq) - 6.17-19 - Handle pending signals before flush so that the the .history file