From f543eb3c68835193e13aed973018556d604a87738a92bb0830d21e10e916251c Mon Sep 17 00:00:00 2001 From: "Dr. Werner Fink" Date: Mon, 2 Dec 2019 09:57:28 +0000 Subject: [PATCH] Drop superfluously history locking patches OBS-URL: https://build.opensuse.org/package/show/shells/tcsh?expand=0&rev=91 --- tcsh-6.18.01-history-stderror-jmp.patch | 56 -- tcsh-6.18.03-history-merge.dif | 60 -- tcsh-6.19.00-history-file-locking-order.patch | 85 --- tcsh-6.20.00-avoid-dotlock-for-fcntl.patch | 26 - tcsh-6.21.0-history-file-locking.patch | 694 ------------------ 5 files changed, 921 deletions(-) delete mode 100644 tcsh-6.18.01-history-stderror-jmp.patch delete mode 100644 tcsh-6.18.03-history-merge.dif delete mode 100644 tcsh-6.19.00-history-file-locking-order.patch delete mode 100644 tcsh-6.20.00-avoid-dotlock-for-fcntl.patch delete mode 100644 tcsh-6.21.0-history-file-locking.patch diff --git a/tcsh-6.18.01-history-stderror-jmp.patch b/tcsh-6.18.01-history-stderror-jmp.patch deleted file mode 100644 index 6b8901f..0000000 --- a/tcsh-6.18.01-history-stderror-jmp.patch +++ /dev/null @@ -1,56 +0,0 @@ ---- - sh.c | 18 ++++++++++++------ - 1 file changed, 12 insertions(+), 6 deletions(-) - ---- sh.c -+++ sh.c 2019-09-26 07:54:47.733054241 +0000 -@@ -1571,13 +1571,15 @@ srcfile(const char *f, int onlyown, int - fl.l_len = 0; - - hd = xmalloc(sizeof(*hd)); -- cleanup_push(hd, xfree); -+ if (hd) { -+ cleanup_push(hd, xfree); - -- *hd = fcntl(unit, F_DUPFD_CLOEXEC, FSAFE+1); -- cleanup_push(hd, open_cleanup); -+ *hd = fcntl(unit, F_DUPFD_CLOEXEC, FSAFE+1); -+ cleanup_push(hd, open_cleanup); - -- fcntl(*hd, F_SETLKW, &fl); -- cleanup_push(hd, fcntl_cleanup); -+ fcntl(*hd, F_SETLKW, &fl); -+ cleanup_push(hd, fcntl_cleanup); -+ } - } - - cleanup_push(&unit, open_cleanup); -@@ -2233,7 +2235,7 @@ dosource(Char **t, struct command *c) - int - dosource_flg(Char **t, struct command *c, int flg) - { -- Char *f; -+ Char *f, **globbed; - char *file; - int fd; - int newflg = 0; -@@ -2256,12 +2258,17 @@ dosource_flg(Char **t, struct command *c - cleanup_push(file, xfree); - xfree(f); - t = glob_all_or_error(t); -- cleanup_push(t, blk_cleanup); -+ globbed = t; -+ cleanup_push(globbed, blk_cleanup); - fd = srcfile(file, 0, (flg | newflg), t); -- if ((!fd) && (!newflg) && (!bequiet)) -+ if ((!fd) && (!newflg) && (!bequiet)) { -+ (void)cleanup_push_mark(); - stderror(ERR_SYSTEM, file, strerror(errno)); -+ } - /* 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(globbed); -+ blk_cleanup(globbed); - cleanup_ignore(file); - xfree(file); - diff --git a/tcsh-6.18.03-history-merge.dif b/tcsh-6.18.03-history-merge.dif deleted file mode 100644 index 35737e3..0000000 --- a/tcsh-6.18.03-history-merge.dif +++ /dev/null @@ -1,60 +0,0 @@ ---- - sh.hist.c | 21 ++++++++++++++++----- - 1 file changed, 16 insertions(+), 5 deletions(-) - ---- sh.hist.c -+++ sh.hist.c 2015-05-05 07:16:26.382084939 +0000 -@@ -99,7 +99,7 @@ hremove(struct Hist *hp) - - /* Prune length of history list to specified size by history variable. */ - PG_STATIC void --discardExcess(int hlen) -+discardExcess(int hlen, int flg) - { - struct Hist *hp, *np; - if (histTail == NULL) { -@@ -110,7 +110,7 @@ discardExcess(int hlen) - * the list is still too long scan the whole list as before. But only do a - * full scan if the list is more than 6% (1/16th) too long. */ - while (histCount > (unsigned)hlen && (np = Histlist.Hnext)) { -- if (eventno - np->Href >= hlen || hlen == 0) -+ if ((eventno - np->Href >= hlen || hlen == 0) && ! (flg & HIST_MERGE)) - hremove(np), hfree(np); - else - break; -@@ -125,7 +125,7 @@ discardExcess(int hlen) - return; /* don't bother doing the full scan */ - for (hp = &Histlist; histCount > (unsigned)hlen && - (np = hp->Hnext) != NULL;) -- if (eventno - np->Href >= hlen || hlen == 0) -+ if ((eventno - np->Href >= hlen || hlen == 0) || flg & HIST_MERGE) - hremove(np), hfree(np); - else - hp = np; -@@ -142,7 +142,7 @@ savehist( - return; - if (sp) - (void) enthist(++eventno, sp, 1, flg, histlen); -- discardExcess(histlen); -+ discardExcess(histlen, flg); - } - - #define USE_JENKINS_HASH 1 -@@ -1358,5 +1358,16 @@ void - sethistory(int n) - { - histlen = n; -- discardExcess(histlen); -+ int merge = 0; -+ struct varent *shist; -+ if ((shist = adrof(STRsavehist)) != NULL && shist->vec != NULL) { -+ size_t i; -+ for (i = 1; shist->vec[i]; i++) { -+ if (eq(shist->vec[i], STRmerge)) { -+ merge = HIST_MERGE; -+ break; -+ } -+ } -+ } -+ discardExcess(histlen, merge); - } diff --git a/tcsh-6.19.00-history-file-locking-order.patch b/tcsh-6.19.00-history-file-locking-order.patch deleted file mode 100644 index b7e9abd..0000000 --- a/tcsh-6.19.00-history-file-locking-order.patch +++ /dev/null @@ -1,85 +0,0 @@ ---- - sh.c | 57 +++++++++++++++++++++++++++++++++------------------------ - 1 file changed, 33 insertions(+), 24 deletions(-) - ---- sh.c -+++ sh.c 2016-11-25 08:05:00.501610199 +0000 -@@ -1549,18 +1549,18 @@ int - #endif /*WINNT_NATIVE*/ - srcfile(const char *f, int onlyown, int flg, Char **av) - { -- int *unit; -+ int unit, *hd = NULL; - -- unit = xmalloc(sizeof(*unit)); -- cleanup_push(unit, xfree); -- *unit = xopen(f, O_LARGEFILE | -+ unit = xopen(f, O_LARGEFILE | - ((flg & HIST_FILE_WRLCK) ? (O_CREAT|O_RDWR) : O_RDONLY), 0600); -- if (*unit == -1) -+ if (unit < 0) - return 0; /* Error. */ - -- cleanup_push(unit, open_cleanup); -- *unit = dmove(*unit, -1); -- (void) close_on_exec(*unit, 1); -+ cleanup_push(&unit, open_cleanup); -+ unit = dmove(unit, -1); -+ cleanup_ignore(&unit); -+ cleanup_until(&unit); -+ (void) close_on_exec(unit, 1); - - if (flg & (HIST_FILE_WRLCK | HIST_FILE_RDLCK)) { - struct flock fl; -@@ -1570,26 +1570,35 @@ srcfile(const char *f, int onlyown, int - fl.l_start = 0; - fl.l_len = 0; - -- cleanup_push(unit, fcntl_cleanup); -- if (fcntl(*unit, F_SETLKW, &fl) == -1) -- cleanup_ignore(unit); -- } -+ hd = xmalloc(sizeof(*hd)); -+ cleanup_push(hd, xfree); - -- srcunit(*unit, onlyown, flg, av); -+ *hd = fcntl(unit, F_DUPFD_CLOEXEC, FSAFE+1); -+ cleanup_push(hd, open_cleanup); - -- /* 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 */ -- -- /* 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. */ -+ fcntl(*hd, F_SETLKW, &fl); -+ cleanup_push(hd, fcntl_cleanup); - } - -- return *unit; /* File descriptor (fd > FSAFE). */ -+ cleanup_push(&unit, open_cleanup); -+ /* -+ * This one *does* do a cleanup_until() hence a open_cleanup() -+ * therefore use a duplicated fd to lock/unlock the history file -+ */ -+ srcunit(unit, onlyown, flg, av); -+ cleanup_until(&unit); /* Close the official unit. */ -+ -+ if (!hd) -+ return -1; /* Not error but invalid file descriptor. */ -+ -+ if ((flg & HIST_FILE_OPEN) && (flg & HIST_FILE_LOCK)) -+ return -1; -+ -+ cleanup_until(hd); /* fcntl_cleanup */ -+ cleanup_until(hd); /* open_cleanup */ -+ cleanup_until(hd); /* xfree */ -+ -+ return unit; /* File descriptor (fd > FSAFE). */ - } - - diff --git a/tcsh-6.20.00-avoid-dotlock-for-fcntl.patch b/tcsh-6.20.00-avoid-dotlock-for-fcntl.patch deleted file mode 100644 index e875a8c..0000000 --- a/tcsh-6.20.00-avoid-dotlock-for-fcntl.patch +++ /dev/null @@ -1,26 +0,0 @@ ---- - sh.hist.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- sh.hist.c -+++ sh.hist.c 2019-11-29 14:28:04.960116108 +0000 -@@ -1275,6 +1275,11 @@ rechist(Char *fname, int ref) - - if (merge) { - jmp_buf_t osetexit; -+#if 0 /* We are using fcntl's F_SETLKW patch for locking -+ * therefore avoid dot file locking without holding -+ * a file descriptor as otherwise we migth not be -+ * able to open the history file after a crash or -+ * if a killall had been used during reboot. */ - if (lock) { - #ifndef WINNT_NATIVE - char *lockpath = strsave(short2str(fname)); -@@ -1284,6 +1289,7 @@ rechist(Char *fname, int ref) - cleanup_push(lockpath, dotlock_cleanup); - #endif - } -+#endif - getexit(osetexit); - if (setexit()) { - /* Read .history file, leave it's fd open for writing. */ diff --git a/tcsh-6.21.0-history-file-locking.patch b/tcsh-6.21.0-history-file-locking.patch deleted file mode 100644 index dd1d966..0000000 --- a/tcsh-6.21.0-history-file-locking.patch +++ /dev/null @@ -1,694 +0,0 @@ -Based on f813180f2fc1d682dd097e4a05ef4d15000204ad Mon Sep 17 00:00:00 2001 -From: Roman Kollar -Date: Mon, 29 Oct 2012 17:52:52 +0100 -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) - -Additional changes reflecting: -https://bugzilla.redhat.com/show_bug.cgi?id=879371 - -Changes by Fridolin Pokorny - ---- - sh.c | 102 +++++++++++++++++++++++++++++++++++------------- - sh.decls.h | 4 + - sh.dol.c | 2 - sh.err.c | 16 +++++++ - sh.h | 18 ++++++++ - sh.hist.c | 129 +++++++++++++++++++++++++++++-------------------------------- - sh.lex.c | 8 +-- - sh.sem.c | 2 - 8 files changed, 180 insertions(+), 101 deletions(-) - ---- sh.c -+++ sh.c 2019-11-29 14:09:30.432768187 +0000 -@@ -138,6 +138,7 @@ struct saved_state { - int cantell; - struct Bin B; - int justpr; -+ int close_unit; - }; - - static int srccat (Char *, Char *); -@@ -1360,7 +1361,7 @@ main(int argc, char **argv) - /* - * Source history before .login so that it is available in .login - */ -- loadhist(NULL, 0); -+ loadhist(NULL, HIST_FILE_RDLCK); - #ifndef LOGINFIRST - if (loginsh) - (void) srccat(varval(STRhome), STRsldotlogin); -@@ -1516,7 +1517,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; -@@ -1532,7 +1533,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; - } -@@ -1546,20 +1547,49 @@ static int - #else - int - #endif /*WINNT_NATIVE*/ --srcfile(const char *f, int onlyown, int flag, Char **av) -+srcfile(const char *f, int onlyown, int flg, Char **av) - { -- int unit; -+ int *unit; - -- if ((unit = xopen(f, O_RDONLY|O_LARGEFILE)) == -1) -- return 0; -- cleanup_push(&unit, open_cleanup); -- unit = dmove(unit, -1); -- cleanup_ignore(&unit); -- cleanup_until(&unit); -- -- (void) close_on_exec(unit, 1); -- srcunit(unit, onlyown, flag, av); -- return 1; -+ unit = xmalloc(sizeof(*unit)); -+ cleanup_push(unit, xfree); -+ *unit = xopen(f, O_LARGEFILE | -+ ((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); -+ -+ if (flg & (HIST_FILE_WRLCK | HIST_FILE_RDLCK)) { -+ struct flock fl; -+ -+ fl.l_type = (flg & HIST_FILE_WRLCK) ? F_WRLCK : F_RDLCK; -+ fl.l_whence = SEEK_SET; -+ fl.l_start = 0; -+ fl.l_len = 0; -+ -+ cleanup_push(unit, fcntl_cleanup); -+ if (fcntl(*unit, F_SETLKW, &fl) == -1) -+ cleanup_ignore(unit); -+ } -+ -+ srcunit(*unit, onlyown, flg, av); -+ -+ /* 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 */ -+ -+ /* 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; /* File descriptor (fd > FSAFE). */ - } - - -@@ -1568,7 +1598,7 @@ srcfile(const char *f, int onlyown, int - * 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; -@@ -1617,10 +1647,14 @@ st_save(struct saved_state *st, int unit - st->onelflg = onelflg; - st->enterhist = enterhist; - st->justpr = justpr; -- if (hflg) -+ if (flg & (HIST_ONLY | HIST_MERGE)) - st->HIST = HIST; - else - st->HIST = '\0'; -+ if (flg & HIST_FILE_OPEN) -+ st->close_unit = 0; -+ else -+ st->close_unit = 1; - st->cantell = cantell; - cpybin(st->B, B); - -@@ -1659,7 +1693,7 @@ st_save(struct saved_state *st, int unit - evalp = 0; - alvec = al; - alvecp = 0; -- enterhist = hflg; -+ enterhist = flg & (HIST_ONLY | HIST_MERGE); - if (enterhist) - HIST = '\0'; - insource = 1; -@@ -1692,7 +1726,8 @@ st_restore(void *xst) - } - cpybin(B, st->B); - -- xclose(SHIN); -+ if (st->close_unit) -+ xclose(SHIN); - - insource = st->insource; - SHIN = st->SHIN; -@@ -1728,7 +1763,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; - -@@ -1754,7 +1789,7 @@ srcunit(int unit, int onlyown, int hflg, - } - - /* 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 -@@ -2096,7 +2131,7 @@ process(int catch) - * elsewhere... - */ - if (enterhist || (catch && intty && !whyles && !tellwhat && !arun)) -- savehist(¶ml, enterhist > 1); -+ savehist(¶ml, enterhist > 1 ? HIST_MERGE : 0); - - if (Expand && seterr) - Expand = 0; -@@ -2183,21 +2218,28 @@ process(int catch) - void - dosource(Char **t, struct command *c) - { -+ (void) dosource_flg(t, c, 0); -+} -+ -+int -+dosource_flg(Char **t, struct command *c, int flg) -+{ - Char *f; -- int hflg = 0; - char *file; -+ int fd; -+ int newflg = 0; - - USE(c); - t++; - if (*t && eq(*t, STRmh)) { - if (*++t == NULL) - stderror(ERR_NAME | ERR_HFLAG); -- hflg++; -+ newflg |= HIST_ONLY; - } - else if (*t && eq(*t, STRmm)) { - if (*++t == NULL) - stderror(ERR_NAME | ERR_MFLAG); -- hflg = 2; -+ newflg |= HIST_MERGE; - } - - f = globone(*t++, G_ERROR); -@@ -2206,9 +2248,15 @@ dosource(Char **t, struct command *c) - xfree(f); - t = glob_all_or_error(t); - cleanup_push(t, blk_cleanup); -- if ((!srcfile(file, 0, hflg, t)) && (!hflg) && (!bequiet)) -+ fd = srcfile(file, 0, (flg | newflg), t); -+ if ((!fd) && (!newflg) && (!bequiet)) - stderror(ERR_SYSTEM, file, strerror(errno)); -- cleanup_until(file); -+ /* 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; /* Valid/invalid file descriptor (>FSAVE, -1). Zero on error. */ - } - - /* ---- sh.decls.h -+++ sh.decls.h 2019-11-29 14:09:30.432768187 +0000 -@@ -37,6 +37,7 @@ - */ - extern Char *gethdir (const Char *); - extern void dosource (Char **, struct command *); -+extern int dosource_flg (Char **, struct command *, int); - extern void exitstat (void); - extern void goodbye (Char **, struct command *); - extern void importpath (Char *); -@@ -98,6 +99,7 @@ extern void cleanup_until_mark(void); - extern size_t cleanup_push_mark(void); - extern void cleanup_pop_mark(size_t); - extern void open_cleanup(void *); -+extern void fcntl_cleanup(void *); - extern void opendir_cleanup(void *); - extern void sigint_cleanup(void *); - extern void sigprocmask_cleanup(void *); -@@ -220,7 +222,7 @@ extern struct Hist *enthist (int, str - extern void savehist (struct wordent *, int); - extern char *fmthist (int, ptr_t); - extern void rechist (Char *, int); --extern void loadhist (Char *, int); -+extern int loadhist (Char *, int); - extern void displayHistStats(const char *); - extern void sethistory (int); - ---- sh.dol.c -+++ sh.dol.c 2019-11-29 14:09:30.432768187 +0000 -@@ -1117,6 +1117,6 @@ again: - *obp = 0; - tmp = short2str(obuf); - (void) xwrite(0, tmp, strlen (tmp)); -- (void) lseek(0, (off_t) 0, L_SET); -+ (void) lseek(0, (off_t) 0, SEEK_SET); - cleanup_until(&inheredoc); - } ---- sh.err.c -+++ sh.err.c 2019-11-29 14:09:30.432768187 +0000 -@@ -512,6 +512,22 @@ open_cleanup(void *xptr) - } - - void -+fcntl_cleanup(void *xptr) -+{ -+ int *ptr; -+ struct flock fl; -+ -+ ptr = xptr; -+ -+ fl.l_type = F_UNLCK; -+ fl.l_whence = SEEK_SET; -+ fl.l_start = 0; -+ fl.l_len = 0; -+ -+ fcntl(*ptr, F_SETLK, &fl); -+} -+ -+void - opendir_cleanup(void *xdir) - { - DIR *dir; ---- sh.h -+++ sh.h 2019-11-29 14:09:30.432768187 +0000 -@@ -49,6 +49,24 @@ - # include - #endif - -+#include -+#include -+ -+/* -+ * History flags. -+ */ -+#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 ---- sh.hist.c -+++ sh.hist.c 2019-11-29 14:22:17.850548114 +0000 -@@ -32,6 +32,8 @@ - #include "sh.h" - #include /* for rename(2), grr. */ - #include -+#include -+#include - #include "tc.h" - #include "dotlock.h" - -@@ -42,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 - */ -@@ -141,13 +135,13 @@ discardExcess(int hlen) - void - savehist( - struct wordent *sp, -- int mflg) /* true if -m (merge) specified */ -+ int flg) /* true if -m (merge) specified */ - { - /* throw away null lines */ - if (sp && sp->next->word[0] == '\n') - return; - if (sp) -- (void) enthist(++eventno, sp, 1, mflg, histlen); -+ (void) enthist(++eventno, sp, 1, flg, histlen); - discardExcess(histlen); - } - -@@ -919,7 +913,7 @@ enthist( - int event, /* newly incremented global eventno */ - struct wordent *lp, - int docopy, -- int mflg, /* true if merge requested */ -+ int flg, /* true if merge requested */ - int hlen) /* -1 if unknown */ - { - struct Hist *p = NULL, *pp = &Histlist, *pTime = NULL; -@@ -939,7 +933,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 */ -@@ -998,7 +992,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)) { -@@ -1037,11 +1031,11 @@ hfree(struct Hist *hp) - } - - PG_STATIC void --phist(struct Hist *hp, int hflg) -+phist(struct Hist *hp, int flg) - { - if (hp->Href < 0) - return; -- if (hflg & HIST_ONLY) { -+ if (flg & HIST_ONLY) { - int old_output_raw; - - /* -@@ -1053,7 +1047,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') -@@ -1084,7 +1078,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) { -@@ -1093,7 +1087,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) -@@ -1107,10 +1101,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); - } - } - -@@ -1118,7 +1112,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) -@@ -1129,40 +1123,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)) -- loadhist(*vp, (hflg & HIST_MERGE) ? 1 : 0); -- 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 { - if (*vp) -@@ -1170,7 +1164,7 @@ dohist(Char **vp, struct command *c) - else { - n = getn(varval(STRhistory)); - } -- dophist(n, hflg); -+ dophist(n, flg); - } - } - -@@ -1218,10 +1212,9 @@ dotlock_cleanup(void* lockpath) - void - rechist(Char *fname, int ref) - { -- Char *snum, *rs; -- int fp, ftmp, oldidfds; -+ Char *snum; -+ int fd = -1, ftmp, oldidfds; - struct varent *shist; -- char path[MAXPATHLEN]; - struct stat st; - static Char *dumphist[] = {STRhistory, STRmhT, 0, 0}; - -@@ -1292,52 +1285,52 @@ rechist(Char *fname, int ref) - #endif - } - getexit(osetexit); -- if (setexit()) -- loadhist(fname, 1); -+ if (setexit()) { -+ /* Read .history file, leave it's fd open for writing. */ -+ 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, (off_t) 0, SEEK_SET); -+ } -+ } - resexit(osetexit); - } - } -- rs = randsuf(); -- xsnprintf(path, sizeof(path), "%S.%S", fname, rs); -- xfree(rs); -- -- fp = xcreat(path, 0600); -- if (fp == -1) { -- didfds = oldidfds; -- cleanup_until(fname); -- return; -+ 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); -+ if (fd != -1) -+ cleanup_push(&fd, open_cleanup); - } - /* Try to preserve ownership and permissions of the original history file */ - #ifndef WINNT_NATIVE - if (stat(short2str(fname), &st) != -1) { -- TCSH_IGNORE(fchown(fp, st.st_uid, st.st_gid)); -- TCSH_IGNORE(fchmod(fp, st.st_mode)); -+ TCSH_IGNORE(fchown(fd, st.st_uid, st.st_gid)); -+ TCSH_IGNORE(fchmod(fd, st.st_mode)); - } - #else - UNREFERENCED_PARAMETER(st); - #endif -- ftmp = SHOUT; -- SHOUT = fp; -- dumphist[2] = snum; -- dohist(dumphist, NULL); -- xclose(fp); -- SHOUT = ftmp; -+ if (fd != -1) { -+ ftmp = SHOUT; -+ SHOUT = fd; -+ dumphist[2] = snum; -+ dohist(dumphist, NULL); -+ SHOUT = ftmp; -+ } - didfds = oldidfds; --#ifndef WINNT_NATIVE -- (void)rename(path, short2str(fname)); --#else -- (void)ReplaceFile( short2str(fname),path,NULL,0,NULL,NULL); --#endif - 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; -@@ -1346,17 +1339,19 @@ loadhist(Char *fname, int mflg) - else - loadhist_cmd[2] = STRtildothist; - -- dosource(loadhist_cmd, NULL); -+ fd = dosource_flg(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. */ - } - - void ---- sh.lex.c -+++ sh.lex.c 2019-11-29 14:09:30.432768187 +0000 -@@ -1608,7 +1608,7 @@ wide_read(int fildes, Char *buf, size_t - /* Throwing away possible partial multibyte characters on error if the - stream is not seekable */ - err = errno; -- lseek(fildes, -(off_t)partial, L_INCR); -+ lseek(fildes, -(off_t)partial, SEEK_CUR); - errno = err; - return res != 0 ? res : r; - } -@@ -1623,7 +1623,7 @@ bgetc(void) - if (cantell) { - if (fseekp < fbobp || fseekp > feobp) { - fbobp = feobp = fseekp; -- (void) lseek(SHIN, fseekp, L_SET); -+ (void) lseek(SHIN, fseekp, SEEK_SET); - } - if (fseekp == feobp) { - #ifdef WIDE_STRINGS -@@ -1827,7 +1827,7 @@ btell(struct Ain *l) - void - btoeof(void) - { -- (void) lseek(SHIN, (off_t) 0, L_XTND); -+ (void) lseek(SHIN, (off_t) 0, SEEK_END); - aret = TCSH_F_SEEK; - fseekp = feobp; - alvec = NULL; -@@ -1845,7 +1845,7 @@ settell(void) - cantell = 0; - if (arginp || onelflg || intty) - return; -- if ((x = lseek(SHIN, (off_t) 0, L_INCR)) == -1) -+ if ((x = lseek(SHIN, (off_t) 0, SEEK_CUR)) == -1) - return; - fbuf = xcalloc(2, sizeof(Char **)); - fblocks = 1; ---- sh.sem.c -+++ sh.sem.c 2019-11-29 14:09:30.432768187 +0000 -@@ -905,7 +905,7 @@ doio(struct command *t, int *pipein, int - fd = xopen(tmp, O_WRONLY|O_APPEND|O_LARGEFILE); - #else /* !O_APPEND */ - fd = xopen(tmp, O_WRONLY|O_LARGEFILE); -- (void) lseek(fd, (off_t) 0, L_XTND); -+ (void) lseek(fd, (off_t) 0, SEEK_END); - #endif /* O_APPEND */ - } - else