SHA256
1
0
forked from pool/tcsh

Accepting request 754265 from shells

- Update to tcsh bug fix version V6.22.02 - 20191204
  * Fix version in configure.ac

- Drop patches
  * tcsh-6.21.0-history-file-locking.patch
    As upstream introduced its own history file locking
  * tcsh-6.18.03-history-merge.dif
    To respect upstream history merge handling
  * tcsh-6.19.00-history-file-locking-order.patch
    Not required due dropped tcsh-6.21.0-history-file-locking.patch
  * tcsh-6.20.00-avoid-dotlock-for-fcntl.patch
    Not required due dropped tcsh-6.21.0-history-file-locking.patch
  * tcsh-6.18.01-history-stderror-jmp.patch
    Not required due dropped tcsh-6.21.0-history-file-locking.patch

- Update to tcsh bug fix version V6.22.01 - 20191201
  * undo PR/88: Preserve empty arguments in :q, since it breaks
       $ set x=""
       $ alias test "echo "\""$x:q"\"" is working."
       $ alias test
       echo "

- Update to tcsh bug fix version V6.22.00 -  20191128
  * PR/113: Sobomax: avoid infinite loops for -c commands when stdout is
    not a tty.
  * Avoid infinite loops during history loads when merging, print a better
    error for errors during history load.
  * PR/88: Preserve empty arguments in :q
  * PR/94: Small apple issues (SAVESIGVEC, HOSTTYPE)
  * PR/81: Fix range matching issue where we were comparing with the

OBS-URL: https://build.opensuse.org/request/show/754265
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/tcsh?expand=0&rev=68
This commit is contained in:
Dominique Leuenberger 2019-12-07 14:12:18 +00:00 committed by Git OBS Bridge
commit ddc938291a
12 changed files with 63 additions and 996 deletions

View File

@ -7,7 +7,7 @@
--- sh.c
+++ sh.c 2016-11-25 08:02:39.616478025 +0000
@@ -862,9 +862,9 @@ main(int argc, char **argv)
@@ -863,9 +863,9 @@ main(int argc, char **argv)
/* PATCH IDEA FROM Issei.Suzuki VERY THANKS */
#if defined(DSPMBYTE)
#if defined(NLS) && defined(LC_CTYPE)

View File

@ -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
@@ -1563,13 +1563,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);
@@ -2225,7 +2227,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;
@@ -2248,12 +2253,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);

View File

@ -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);
}

View File

@ -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
@@ -1541,18 +1541,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;
@@ -1562,26 +1562,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). */
}

View File

@ -1,26 +0,0 @@
---
sh.hist.c | 6 ++++++
1 file changed, 6 insertions(+)
--- sh.hist.c
+++ sh.hist.c 2017-07-19 10:01:20.795354927 +0000
@@ -1278,6 +1278,11 @@ rechist(Char *fname, int ref)
}
if (merge) {
+#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));
@@ -1287,6 +1292,7 @@ rechist(Char *fname, int ref)
cleanup_push(lockpath, dotlock_cleanup);
#endif
}
+#endif
/* 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) {

View File

@ -1,692 +0,0 @@
Based on f813180f2fc1d682dd097e4a05ef4d15000204ad Mon Sep 17 00:00:00 2001
From: Roman Kollar <rkollar@redhat.com>
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) <vvitek@redhat.com>
Additional changes reflecting:
https://bugzilla.redhat.com/show_bug.cgi?id=879371
Changes by Fridolin Pokorny <fpokorny@redhat.com>
---
sh.c | 102 ++++++++++++++++++++++++++++++++++++------------
sh.decls.h | 4 +
sh.dol.c | 2
sh.err.c | 16 +++++++
sh.h | 18 ++++++++
sh.hist.c | 127 ++++++++++++++++++++++++++++---------------------------------
sh.lex.c | 8 +--
sh.sem.c | 2
8 files changed, 178 insertions(+), 101 deletions(-)
--- sh.c
+++ sh.c 2019-08-22 13:02:31.780361102 +0000
@@ -138,6 +138,7 @@ struct saved_state {
int cantell;
struct Bin B;
int justpr;
+ int close_unit;
};
static int srccat (Char *, Char *);
@@ -1359,7 +1360,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);
@@ -1508,7 +1509,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;
@@ -1524,7 +1525,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;
}
@@ -1538,20 +1539,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). */
}
@@ -1560,7 +1590,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;
@@ -1609,10 +1639,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);
@@ -1651,7 +1685,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;
@@ -1684,7 +1718,8 @@ st_restore(void *xst)
}
cpybin(B, st->B);
- xclose(SHIN);
+ if (st->close_unit)
+ xclose(SHIN);
insource = st->insource;
SHIN = st->SHIN;
@@ -1720,7 +1755,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;
@@ -1746,7 +1781,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
@@ -2088,7 +2123,7 @@ process(int catch)
* elsewhere...
*/
if (enterhist || (catch && intty && !whyles && !tellwhat && !arun))
- savehist(&paraml, enterhist > 1);
+ savehist(&paraml, enterhist > 1 ? HIST_MERGE : 0);
if (Expand && seterr)
Expand = 0;
@@ -2175,21 +2210,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);
@@ -2198,9 +2240,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-08-22 13:02:31.780361102 +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-08-22 13:02:31.780361102 +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-08-22 13:02:31.780361102 +0000
@@ -511,6 +511,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-08-22 13:02:31.784361027 +0000
@@ -49,6 +49,24 @@
# include <inttypes.h>
#endif
+#include <unistd.h>
+#include <fcntl.h>
+
+/*
+ * 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-08-22 13:02:44.684119766 +0000
@@ -32,6 +32,8 @@
#include "sh.h"
#include <stdio.h> /* for rename(2), grr. */
#include <assert.h>
+#include <unistd.h>
+#include <sys/types.h>
#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, phup_disabled_tmp;
+ Char *snum;
+ int fd = -1, ftmp, oldidfds, phup_disabled_tmp;
struct varent *shist;
- char path[MAXPATHLEN];
struct stat st;
static Char *dumphist[] = {STRhistory, STRmhT, 0, 0};
@@ -1294,52 +1287,50 @@ rechist(Char *fname, int ref)
cleanup_push(lockpath, dotlock_cleanup);
#endif
}
- loadhist(fname, 1);
+ /* 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);
+ }
}
}
- rs = randsuf();
- xsnprintf(path, sizeof(path), "%S.%S", fname, rs);
- xfree(rs);
-
- fp = xcreat(path, 0600);
- if (fp == -1) {
- didfds = oldidfds;
- cleanup_until(fname);
- phup_disabled = phup_disabled_tmp;
- 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);
phup_disabled = phup_disabled_tmp;
}
/* 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;
@@ -1348,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-08-22 13:02:31.784361027 +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-08-22 13:02:31.784361027 +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

View File

@ -1,50 +0,0 @@
tcsh can deadlock with itself if savehist is confgured with "merge" and
"lock", and two SIGHUPs are received in rapid succession. The
mechanism of the deadlock is the first SIGHUP triggers a rechist() and
while that rechist() is executing (and after it has created the lock
file), another SIGHUP triggers a another rechist() which then waits
forever for the lock the the first rechist() created to be released
(which will never happen).
---
tcsh-6.21.00/sh.hist.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
--- tcsh-6.21.00/sh.hist.c
+++ tcsh-6.21.00/sh.hist.c 2019-08-22 12:05:25.800474245 +0000
@@ -1219,7 +1219,7 @@ void
rechist(Char *fname, int ref)
{
Char *snum, *rs;
- int fp, ftmp, oldidfds;
+ int fp, ftmp, oldidfds, phup_disabled_tmp;
struct varent *shist;
char path[MAXPATHLEN];
struct stat st;
@@ -1227,6 +1227,10 @@ rechist(Char *fname, int ref)
if (fname == NULL && !ref)
return;
+
+ phup_disabled_tmp = phup_disabled;
+ phup_disabled = 1;
+
/*
* If $savehist is just set, we use the value of $history
* else we use the value in $savehist
@@ -1301,6 +1305,7 @@ rechist(Char *fname, int ref)
if (fp == -1) {
didfds = oldidfds;
cleanup_until(fname);
+ phup_disabled = phup_disabled_tmp;
return;
}
/* Try to preserve ownership and permissions of the original history file */
@@ -1325,6 +1330,7 @@ rechist(Char *fname, int ref)
(void)ReplaceFile( short2str(fname),path,NULL,0,NULL,NULL);
#endif
cleanup_until(fname);
+ phup_disabled = phup_disabled_tmp;
}

View File

@ -14,7 +14,7 @@
--- config/linux
+++ config/linux 2019-05-09 08:41:54.237060106 +0000
@@ -92,6 +92,9 @@
@@ -99,6 +99,9 @@
#ifndef _SVID_SOURCE
# define _SVID_SOURCE
#endif
@ -24,7 +24,7 @@
#ifndef _POSIX_SOURCE
# define _POSIX_SOURCE
#endif
@@ -132,4 +135,11 @@
@@ -139,4 +142,11 @@
# define POSIX
#endif

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c438325448371f59b12a4c93bfd3f6982e6f79f8c5aef4bc83aac8f62766e972
size 1001909

3
tcsh-6.22.02.tar.gz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ed287158ca1b00ba477e8ea57bac53609838ebcfd05fcb05ca95021b7ebe885b
size 1006405

View File

@ -1,3 +1,56 @@
-------------------------------------------------------------------
Thu Dec 5 06:46:37 UTC 2019 - Dr. Werner Fink <werner@suse.de>
- Update to tcsh bug fix version V6.22.02 - 20191204
* Fix version in configure.ac
-------------------------------------------------------------------
Mon Dec 2 09:47:03 UTC 2019 - Dr. Werner Fink <werner@suse.de>
- Drop patches
* tcsh-6.21.0-history-file-locking.patch
As upstream introduced its own history file locking
* tcsh-6.18.03-history-merge.dif
To respect upstream history merge handling
* tcsh-6.19.00-history-file-locking-order.patch
Not required due dropped tcsh-6.21.0-history-file-locking.patch
* tcsh-6.20.00-avoid-dotlock-for-fcntl.patch
Not required due dropped tcsh-6.21.0-history-file-locking.patch
* tcsh-6.18.01-history-stderror-jmp.patch
Not required due dropped tcsh-6.21.0-history-file-locking.patch
-------------------------------------------------------------------
Mon Dec 2 08:26:48 UTC 2019 - Dr. Werner Fink <werner@suse.de>
- Update to tcsh bug fix version V6.22.01 - 20191201
* undo PR/88: Preserve empty arguments in :q, since it breaks
$ set x=""
$ alias test "echo "\""$x:q"\"" is working."
$ alias test
echo "
-------------------------------------------------------------------
Fri Nov 29 14:44:02 UTC 2019 - Dr. Werner Fink <werner@suse.de>
- Update to tcsh bug fix version V6.22.00 - 20191128
* PR/113: Sobomax: avoid infinite loops for -c commands when stdout is
not a tty.
* Avoid infinite loops during history loads when merging, print a better
error for errors during history load.
* PR/88: Preserve empty arguments in :q
* PR/94: Small apple issues (SAVESIGVEC, HOSTTYPE)
* PR/81: Fix range matching issue where we were comparing with the
range character instead of the start of range. [l-z]* would match foo
- Drop patch tcsh-6.21.00-sighup-deadlock.patch as now superfluous
- Port patches
* tcsh-6.17.06-dspmbyte.dif
* tcsh-6.18.01-history-stderror-jmp.patch
* tcsh-6.19.00-history-file-locking-order.patch
* tcsh-6.20.00-avoid-dotlock-for-fcntl.patch
* tcsh-6.21.0-history-file-locking.patch
* tcsh-6.21.00-sighup-deadlock.patch
* tcsh-6.21.00.dif
-------------------------------------------------------------------
Thu Oct 17 10:35:23 UTC 2019 - Dr. Werner Fink <werner@suse.de>

View File

@ -1,7 +1,7 @@
#
# spec file for package tcsh
#
# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
# Copyright (c) 2019 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@ -17,13 +17,13 @@
Name: tcsh
Version: 6.21.00
Version: 6.22.02
Release: 0
Summary: The C SHell
License: BSD-3-Clause
Group: System/Shells
Url: http://www.tcsh.org/
Source: ftp.astron.com:/pub/tcsh/tcsh-6.21.00.tar.gz
URL: http://www.tcsh.org/
Source: ftp.astron.com:/pub/%{name}/%{name}-%{version}.tar.gz
Source2: bindkey.tcsh
Source3: complete.tcsh
Patch0: tcsh-6.21.00.dif
@ -32,17 +32,6 @@ Patch2: tcsh-6.16.00-norm-cmd.dif
Patch4: tcsh-6.18.03-colorls.dif
Patch5: tcsh-6.17.06-dspmbyte.dif
Patch6: tcsh-6.18.03-catalogs.dif
# PATCH-FIX-UPSTREAM Do not (re)run SIGHUP handler during rewrite history
Patch7: tcsh-6.21.00-sighup-deadlock.patch
# PATCH-FIX-SUSE add history file locking (bsc#901076)
Patch9: tcsh-6.21.0-history-file-locking.patch
Patch10: tcsh-6.18.03-history-merge.dif
# PATCH-FIX-SUSE fix history file locking: first unlock then close
Patch11: tcsh-6.19.00-history-file-locking-order.patch
# PATCH-FIX-SUSE Aoid dot locking as patch 9 and 11 do the job better
Patch12: tcsh-6.20.00-avoid-dotlock-for-fcntl.patch
# PATCH-FIX-SUSE Restore cleaning routines in case of an error (bsc#1151630)
Patch13: tcsh-6.18.01-history-stderror-jmp.patch
BuildRequires: autoconf
BuildRequires: fdupes
BuildRequires: ncurses-devel
@ -68,12 +57,6 @@ correction, a history mechanism, job control, and a C-like syntax.
%patch4 -b .colorls
%patch5 -b .dspmbyte
%patch6 -b .catalogs
%patch7 -p1 -b .sighup
%patch9 -b .histlock
%patch10 -b .histmerg
%patch11 -b .histlckord
%patch12 -p0 -b .nodtlck
%patch13 -p0 -b .histerrjmp
%patch0 -b .0
%build