From 0bfdc5aa3e7740f3f3cffd25e12093865ee6842be21c3ce2f2a96a24ae6de92a Mon Sep 17 00:00:00 2001 From: "Dr. Werner Fink" Date: Tue, 13 Jan 2015 17:16:42 +0000 Subject: [PATCH] . OBS-URL: https://build.opensuse.org/package/show/shells/tcsh?expand=0&rev=48 --- tcsh-6.18.00-history-file-locking.patch | 684 ++++++++++++++++++++++++ tcsh-6.18.01-history-merge.dif | 10 +- tcsh.changes | 7 + tcsh.spec | 9 +- 4 files changed, 702 insertions(+), 8 deletions(-) create mode 100644 tcsh-6.18.00-history-file-locking.patch diff --git a/tcsh-6.18.00-history-file-locking.patch b/tcsh-6.18.00-history-file-locking.patch new file mode 100644 index 0000000..02a9b27 --- /dev/null +++ b/tcsh-6.18.00-history-file-locking.patch @@ -0,0 +1,684 @@ +From 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 + +--- + +diff -upr tcsh-6.18.00_orig/sh.c tcsh-6.18.00_work/sh.c +--- tcsh-6.18.00_orig/sh.c 2013-03-28 10:06:17.969859477 +0100 ++++ tcsh-6.18.00_work/sh.c 2013-03-28 10:07:21.155082032 +0100 +@@ -140,6 +140,7 @@ struct saved_state { + int cantell; + struct Bin B; + int justpr; ++ int close_unit; + }; + + static int srccat (Char *, Char *); +@@ -1369,7 +1370,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); +@@ -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*/ +-srcfile(const char *f, int onlyown, int flag, Char **av) ++srcfile(const char *f, int onlyown, int flg, Char **av) + { +- 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; ++ int *unit; ++ ++ 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). */ + } + + +@@ -1544,7 +1574,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; +@@ -1593,10 +1623,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); + +@@ -1635,7 +1669,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; +@@ -1668,7 +1702,8 @@ st_restore(void *xst) + } + cpybin(B, st->B); + +- xclose(SHIN); ++ if (st->close_unit) ++ xclose(SHIN); + + insource = st->insource; + SHIN = st->SHIN; +@@ -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, + } + + /* 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 +@@ -2069,7 +2104,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; +@@ -2156,21 +2191,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); +@@ -2178,9 +2220,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)) ++ 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. */ + } + + /* +diff -upr tcsh-6.18.00_orig/sh.decls.h tcsh-6.18.00_work/sh.decls.h +--- tcsh-6.18.00_orig/sh.decls.h 2013-03-28 10:06:17.988859538 +0100 ++++ tcsh-6.18.00_work/sh.decls.h 2013-03-28 10:06:42.897948590 +0100 +@@ -38,6 +38,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 *); +@@ -219,7 +221,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 *); + + /* +diff -upr tcsh-6.18.00_orig/sh.dol.c tcsh-6.18.00_work/sh.dol.c +--- tcsh-6.18.00_orig/sh.dol.c 2013-03-28 10:06:17.988859538 +0100 ++++ tcsh-6.18.00_work/sh.dol.c 2013-03-28 10:06:42.898948594 +0100 +@@ -1110,6 +1110,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); + } +diff -upr tcsh-6.18.00_orig/sh.err.c tcsh-6.18.00_work/sh.err.c +--- tcsh-6.18.00_orig/sh.err.c 2013-03-28 10:06:17.972859480 +0100 ++++ tcsh-6.18.00_work/sh.err.c 2013-03-28 10:06:42.824948331 +0100 +@@ -514,6 +514,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; +diff -upr tcsh-6.18.00_orig/sh.h tcsh-6.18.00_work/sh.h +--- tcsh-6.18.00_orig/sh.h 2013-03-28 10:06:17.988859538 +0100 ++++ tcsh-6.18.00_work/sh.h 2013-03-28 10:06:42.899948597 +0100 +@@ -50,6 +50,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 +diff -upr tcsh-6.18.00_orig/sh.hist.c tcsh-6.18.00_work/sh.hist.c +--- tcsh-6.18.00_orig/sh.hist.c 2013-03-28 10:06:17.967859465 +0100 ++++ tcsh-6.18.00_work/sh.hist.c 2013-03-28 10:06:42.815948309 +0100 +@@ -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)) +- 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) +@@ -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) + { +- Char *snum; +- int fp, ftmp, oldidfds; ++ Char *snum; ++ int fd = -1, ftmp, oldidfds; + struct varent *shist; + static Char *dumphist[] = {STRhistory, STRmhT, 0, 0}; + +@@ -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. +- * Currently the automatic merge can only succeed when the shells +- * nicely quit one after another. +- * +- * Users that like to nuke their environment require here an atomic +- * loadhist-creat-dohist(dumphist)-close +- * sequence. + * +- * jw. +- */ ++ * Atomic merge loadhist-creat/ftrunc-dohist(dumphist)-close ++ * implemented using fcntl (shared readers, exclusive writer) ++ * by Vojtech Vitek (V-Teq) . ++ */ ++ + /* + * We need the didfds stuff before loadhist otherwise + * exec in a script will fail to print if merge is set. +@@ -1271,32 +1260,42 @@ rechist(Char *fname, int ref) + */ + oldidfds = didfds; + didfds = 0; +- if ((shist = adrof(STRsavehist)) != NULL && shist->vec != NULL) +- if (shist->vec[1] && eq(shist->vec[1], STRmerge)) +- loadhist(fname, 1); +- +- fp = xcreat(short2str(fname), 0600); +- cleanup_until(fname); +- if (fp == -1) { +- didfds = oldidfds; +- return; ++ 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, 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); ++ } ++ } ++ 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); ++ } ++ if (fd != -1) { ++ ftmp = SHOUT; ++ SHOUT = fd; ++ dumphist[2] = snum; ++ /* 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_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. */ + } +diff -upr tcsh-6.18.00_orig/sh.lex.c tcsh-6.18.00_work/sh.lex.c +--- tcsh-6.18.00_orig/sh.lex.c 2013-03-28 10:06:17.971859478 +0100 ++++ tcsh-6.18.00_work/sh.lex.c 2013-03-28 10:06:42.820948316 +0100 +@@ -1595,7 +1595,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; + } +@@ -1610,7 +1610,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 +@@ -1814,7 +1814,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; +@@ -1832,7 +1832,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; +diff -upr tcsh-6.18.00_orig/sh.sem.c tcsh-6.18.00_work/sh.sem.c +--- tcsh-6.18.00_orig/sh.sem.c 2013-03-28 10:06:17.970859477 +0100 ++++ tcsh-6.18.00_work/sh.sem.c 2013-03-28 10:06:42.819948308 +0100 +@@ -892,7 +892,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 diff --git a/tcsh-6.18.01-history-merge.dif b/tcsh-6.18.01-history-merge.dif index 00528e3..554143b 100644 --- a/tcsh-6.18.01-history-merge.dif +++ b/tcsh-6.18.01-history-merge.dif @@ -5,7 +5,7 @@ /* Prune length of history list to specified size by history variable. */ PG_STATIC void -discardExcess(int histlen) -+discardExcess(int histlen, int mflg) ++discardExcess(int histlen, int flg) { struct Hist *hp, *np; if (histTail == NULL) { @@ -14,7 +14,7 @@ } while (histCount > (unsigned)histlen && (np = histTail) != &Histlist) { - if (eventno - np->Href >= histlen || histlen == 0) -+ if ((eventno - np->Href >= histlen || histlen == 0) && !mflg) ++ if ((eventno - np->Href >= histlen || histlen == 0) && ! (flg & HIST_MERGE)) hremove(np), hfree(np); else break; @@ -23,16 +23,16 @@ for (hp = &Histlist; histCount > (unsigned)histlen && (np = hp->Hnext) != NULL;) - if (eventno - np->Href >= histlen || histlen == 0) -+ if (eventno - np->Href >= histlen || histlen == 0 || mflg) ++ if ((eventno - np->Href >= histlen || histlen == 0) || flg & HIST_MERGE) hremove(np), hfree(np); else hp = np; @@ -161,7 +161,7 @@ savehist( } if (sp) - (void) enthist(++eventno, sp, 1, mflg, histlen); + (void) enthist(++eventno, sp, 1, flg, histlen); - discardExcess(histlen); -+ discardExcess(histlen, mflg); ++ discardExcess(histlen, flg); } #define USE_JENKINS_HASH 1 diff --git a/tcsh.changes b/tcsh.changes index 77091b5..346fbe5 100644 --- a/tcsh.changes +++ b/tcsh.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Tue Jan 13 17:03:12 UTC 2015 - werner@suse.de + +- Add patch tcsh-6.18.00-history-file-locking.patch for bsc#901076 + Cluster switch does not started completely packages on other node +- Modified patch tcsh-6.18.01-history-merge.dif to fit with former + ------------------------------------------------------------------- Tue Oct 15 17:05:54 UTC 2013 - werner@suse.de diff --git a/tcsh.spec b/tcsh.spec index 92b057d..3cd43a2 100644 --- a/tcsh.spec +++ b/tcsh.spec @@ -1,7 +1,7 @@ # # spec file for package tcsh # -# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -41,7 +41,9 @@ Patch5: tcsh-6.17.06-dspmbyte.dif Patch6: tcsh-6.17.10-catalogs.dif Patch7: tcsh-6.18.01-blk_buf.patch Patch8: tcsh-6.18.01-metakey.patch -Patch9: tcsh-6.18.01-history-merge.dif +# PATCH-FIX-SUSE add history file locking (bsc#901076) +Patch9: tcsh-6.18.00-history-file-locking.patch +Patch10: tcsh-6.18.01-history-merge.dif BuildRoot: %{_tmppath}/%{name}-%{version}-build %description @@ -78,7 +80,8 @@ Provides translations to the package tcsh %patch6 -p0 -b .catalogs %patch7 -p0 -b .blk_buf %patch8 -p0 -b .metakey -%patch9 -p0 -b .history +%patch9 -p1 -b .histlock +%patch10 -p0 -b .histmerg %patch -b .0 %build