Prevent .history file corruption
- Implement file locking using shared readers, exclusive writer to prevent any .history file data corruption - Handle pending signals before flush so that the the .history file does not get truncated Resolves: #653054
This commit is contained in:
parent
8fe060db99
commit
c8ffd86422
36
tcsh-6.17.00-handle-signals-before-flush.patch
Normal file
36
tcsh-6.17.00-handle-signals-before-flush.patch
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
From 466297a90d3520d5521c9ca6858a5b7981b3edb8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Vojtech Vitek (V-Teq)" <vvitek@redhat.com>
|
||||||
|
Date: Thu, 10 Nov 2011 17:33:01 +0100
|
||||||
|
Subject: [PATCH 1/2] Handle pending signals before flush so that the the
|
||||||
|
history file does not get truncated. (Ted Anderson)
|
||||||
|
|
||||||
|
Patch adapted from upstream patch in tcsh V6.17.01 - 20100506
|
||||||
|
http://mx.gw.com/pipermail/tcsh/2010-May/004066.html
|
||||||
|
---
|
||||||
|
sh.c | 3 +++
|
||||||
|
1 files changed, 3 insertions(+), 0 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/sh.c b/sh.c
|
||||||
|
index 73b6d7f..da818fb 100644
|
||||||
|
--- a/sh.c
|
||||||
|
+++ b/sh.c
|
||||||
|
@@ -1288,6 +1288,8 @@ main(int argc, char **argv)
|
||||||
|
*/
|
||||||
|
process(setintr);
|
||||||
|
|
||||||
|
+ /* Take care of these (especially HUP) here instead of inside flush. */
|
||||||
|
+ handle_pending_signals();
|
||||||
|
/*
|
||||||
|
* Mop-up.
|
||||||
|
*/
|
||||||
|
@@ -2018,6 +2020,7 @@ process(int catch)
|
||||||
|
cleanup_pop_mark(omark);
|
||||||
|
resexit(osetexit);
|
||||||
|
exitset--;
|
||||||
|
+ handle_pending_signals();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
--
|
||||||
|
1.7.6.2
|
||||||
|
|
478
tcsh-6.17.00-history-file-locking.patch
Normal file
478
tcsh-6.17.00-history-file-locking.patch
Normal file
@ -0,0 +1,478 @@
|
|||||||
|
From c0612dbd1c6d78668f46910c20cb801a5c67780b Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Vojtech Vitek (V-Teq)" <vvitek@redhat.com>
|
||||||
|
Date: Thu, 10 Nov 2011 18:19:57 +0100
|
||||||
|
Subject: [PATCH 2/2] Implement .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>
|
||||||
|
---
|
||||||
|
sh.c | 91 ++++++++++++++++++++++++++++++++++++++++++++----------------
|
||||||
|
sh.decls.h | 5 ++-
|
||||||
|
sh.dir.c | 2 +-
|
||||||
|
sh.dol.c | 2 +-
|
||||||
|
sh.err.c | 16 ++++++++++
|
||||||
|
sh.h | 17 +++++++++++
|
||||||
|
sh.hist.c | 83 +++++++++++++++++++++++++++++-------------------------
|
||||||
|
sh.lex.c | 8 ++--
|
||||||
|
sh.sem.c | 2 +-
|
||||||
|
9 files changed, 154 insertions(+), 72 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/sh.c b/sh.c
|
||||||
|
index da818fb..283af06 100644
|
||||||
|
--- a/sh.c
|
||||||
|
+++ b/sh.c
|
||||||
|
@@ -140,6 +140,7 @@ struct saved_state {
|
||||||
|
int cantell;
|
||||||
|
struct Bin B;
|
||||||
|
int justpr;
|
||||||
|
+ int close_unit;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int srccat (Char *, Char *);
|
||||||
|
@@ -1251,7 +1252,7 @@ main(int argc, char **argv)
|
||||||
|
/*
|
||||||
|
* Source history before .login so that it is available in .login
|
||||||
|
*/
|
||||||
|
- loadhist(NULL, 0);
|
||||||
|
+ loadhist(NULL, FD_RDLCK);
|
||||||
|
#ifndef LOGINFIRST
|
||||||
|
if (loginsh)
|
||||||
|
(void) srccat(varval(STRhome), STRsldotlogin);
|
||||||
|
@@ -1404,20 +1405,52 @@ 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, copy;
|
||||||
|
+
|
||||||
|
+ 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;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ cleanup_push(unit, open_cleanup);
|
||||||
|
+ *unit = dmove(*unit, -1);
|
||||||
|
+ (void) close_on_exec(*unit, 1);
|
||||||
|
+ copy = *unit;
|
||||||
|
+
|
||||||
|
+ if (flg & (FD_WRLCK | FD_RDLCK)) {
|
||||||
|
+ struct flock fl;
|
||||||
|
+
|
||||||
|
+ fl.l_type = (flg & FD_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);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ srcunit(copy, onlyown, (flg & (SRC_HFLAG | SRC_MFLAG)), av);
|
||||||
|
+
|
||||||
|
+ /* Close the unit, if we don't want to leave it open & locked. */
|
||||||
|
+ if ((flg & (FD_WRLCK | FD_RDLCK)) && (!(flg & FD_LEAVE_LCKD))) {
|
||||||
|
+ cleanup_until(unit); /* fcntl_cleanup */
|
||||||
|
+ if (!(flg & FD_LEAVE_OPEN)) {
|
||||||
|
+ cleanup_until(unit); /* open_cleanup */
|
||||||
|
+ cleanup_until(unit); /* xfree */
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return -1; /* Invalid file descriptor. */
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return *unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1475,10 +1508,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)
|
||||||
|
st->HIST = HIST;
|
||||||
|
else
|
||||||
|
st->HIST = '\0';
|
||||||
|
+ if (hflg && FD_LEAVE_OPEN)
|
||||||
|
+ st->close_unit = 0;
|
||||||
|
+ else
|
||||||
|
+ st->close_unit = 1;
|
||||||
|
st->cantell = cantell;
|
||||||
|
cpybin(st->B, B);
|
||||||
|
|
||||||
|
@@ -1550,7 +1587,8 @@ st_restore(void *xst)
|
||||||
|
}
|
||||||
|
cpybin(B, st->B);
|
||||||
|
|
||||||
|
- xclose(SHIN);
|
||||||
|
+ if (st->close_unit)
|
||||||
|
+ xclose(SHIN);
|
||||||
|
|
||||||
|
insource = st->insource;
|
||||||
|
SHIN = st->SHIN;
|
||||||
|
@@ -2024,24 +2062,25 @@ process(int catch)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
-void
|
||||||
|
-dosource(Char **t, struct command *c)
|
||||||
|
+int
|
||||||
|
+dosource(Char **t, struct command *c, int flg)
|
||||||
|
{
|
||||||
|
Char *f;
|
||||||
|
- int hflg = 0;
|
||||||
|
char *file;
|
||||||
|
+ int fd;
|
||||||
|
+ int hflg = 0;
|
||||||
|
|
||||||
|
USE(c);
|
||||||
|
t++;
|
||||||
|
if (*t && eq(*t, STRmh)) {
|
||||||
|
if (*++t == NULL)
|
||||||
|
stderror(ERR_NAME | ERR_HFLAG);
|
||||||
|
- hflg++;
|
||||||
|
+ hflg |= SRC_HFLAG;
|
||||||
|
}
|
||||||
|
else if (*t && eq(*t, STRmm)) {
|
||||||
|
if (*++t == NULL)
|
||||||
|
stderror(ERR_NAME | ERR_MFLAG);
|
||||||
|
- hflg = 2;
|
||||||
|
+ hflg |= SRC_MFLAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
f = globone(*t++, G_ERROR);
|
||||||
|
@@ -2049,9 +2088,13 @@ 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);
|
||||||
|
+
|
||||||
|
+ /* Postpone fd cleanup, which is on the top of cleaning stack. */
|
||||||
|
+ cleanup_ignore(file);
|
||||||
|
+ xfree(file);
|
||||||
|
+
|
||||||
|
+ return fd; /* File descriptor or -1. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
diff --git a/sh.decls.h b/sh.decls.h
|
||||||
|
index 70f76a4..806ae3a 100644
|
||||||
|
--- a/sh.decls.h
|
||||||
|
+++ b/sh.decls.h
|
||||||
|
@@ -37,7 +37,7 @@
|
||||||
|
* sh.c
|
||||||
|
*/
|
||||||
|
extern Char *gethdir (const Char *);
|
||||||
|
-extern void dosource (Char **, struct command *);
|
||||||
|
+extern int dosource (Char **, struct command *, int);
|
||||||
|
extern void exitstat (void);
|
||||||
|
extern void goodbye (Char **, struct command *);
|
||||||
|
extern void importpath (Char *);
|
||||||
|
@@ -97,6 +97,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 *);
|
||||||
|
@@ -216,7 +217,7 @@ extern struct Hist *enthist (int, struct wordent *, int, int);
|
||||||
|
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);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sh.init.c
|
||||||
|
diff --git a/sh.dir.c b/sh.dir.c
|
||||||
|
index 9f72951..b75c366 100644
|
||||||
|
--- a/sh.dir.c
|
||||||
|
+++ b/sh.dir.c
|
||||||
|
@@ -1336,7 +1336,7 @@ loaddirs(Char *fname)
|
||||||
|
loaddirs_cmd[1] = fname;
|
||||||
|
else
|
||||||
|
loaddirs_cmd[1] = STRtildotdirs;
|
||||||
|
- dosource(loaddirs_cmd, NULL);
|
||||||
|
+ dosource(loaddirs_cmd, NULL, 0);
|
||||||
|
cleanup_until(&bequiet);
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/sh.dol.c b/sh.dol.c
|
||||||
|
index bafb971..b9fe82a 100644
|
||||||
|
--- a/sh.dol.c
|
||||||
|
+++ b/sh.dol.c
|
||||||
|
@@ -1099,6 +1099,6 @@ again:
|
||||||
|
*obp = 0;
|
||||||
|
tmp = short2str(obuf);
|
||||||
|
(void) xwrite(0, tmp, strlen (tmp));
|
||||||
|
- (void) lseek(0, (off_t) 0, L_SET);
|
||||||
|
+ (void) lseek(0, 0, SEEK_SET);
|
||||||
|
cleanup_until(&inheredoc);
|
||||||
|
}
|
||||||
|
diff --git a/sh.err.c b/sh.err.c
|
||||||
|
index 279c7b8..9759d72 100644
|
||||||
|
--- a/sh.err.c
|
||||||
|
+++ b/sh.err.c
|
||||||
|
@@ -505,6 +505,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 --git a/sh.h b/sh.h
|
||||||
|
index 83a3e93..c05870f 100644
|
||||||
|
--- a/sh.h
|
||||||
|
+++ b/sh.h
|
||||||
|
@@ -50,6 +50,23 @@
|
||||||
|
# include <inttypes.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#include <unistd.h>
|
||||||
|
+#include <fcntl.h>
|
||||||
|
+/*
|
||||||
|
+ * 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.
|
||||||
|
+ */
|
||||||
|
+#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 */
|
||||||
|
+
|
||||||
|
#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 2863d5c..f0583cb 100644
|
||||||
|
--- a/sh.hist.c
|
||||||
|
+++ b/sh.hist.c
|
||||||
|
@@ -255,7 +255,7 @@ dohist(Char **vp, struct command *c)
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
rechist(*vp, 1);
|
||||||
|
else {
|
||||||
|
@@ -374,8 +374,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};
|
||||||
|
|
||||||
|
@@ -405,15 +405,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) <vvitek@redhat.com>.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* We need the didfds stuff before loadhist otherwise
|
||||||
|
* exec in a script will fail to print if merge is set.
|
||||||
|
@@ -421,41 +418,49 @@ 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)) {
|
||||||
|
- /*
|
||||||
|
- * Unset verbose while we read the history file. From:
|
||||||
|
- * jbastian@redhat.com (Jeffrey Bastian)
|
||||||
|
- */
|
||||||
|
- Char *verb = varval(STRverbose);
|
||||||
|
- if (verb != STRNULL)
|
||||||
|
- unsetv(STRverbose);
|
||||||
|
- loadhist(fname, 1);
|
||||||
|
- if (verb != STRNULL)
|
||||||
|
- setv(STRverbose, verb, VAR_READWRITE);
|
||||||
|
+ if ((shist = adrof(STRsavehist)) != NULL && shist->vec != NULL
|
||||||
|
+ && shist->vec[1] && eq(shist->vec[1], STRmerge)) {
|
||||||
|
+ /*
|
||||||
|
+ * Unset verbose while we read the history file. From:
|
||||||
|
+ * jbastian@redhat.com (Jeffrey Bastian)
|
||||||
|
+ */
|
||||||
|
+ Char *verb = varval(STRverbose);
|
||||||
|
+ if (verb != STRNULL)
|
||||||
|
+ unsetv(STRverbose);
|
||||||
|
+ /* 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) {
|
||||||
|
+ /* Truncate the .history file. */
|
||||||
|
+ (void) ftruncate(fd, 0);
|
||||||
|
+ (void) lseek(fd, 0, SEEK_SET);
|
||||||
|
}
|
||||||
|
- fp = xcreat(short2str(fname), 0600);
|
||||||
|
- if (fp == -1) {
|
||||||
|
- didfds = oldidfds;
|
||||||
|
- cleanup_until(fname);
|
||||||
|
- return;
|
||||||
|
+ if (verb != STRNULL)
|
||||||
|
+ setv(STRverbose, verb, VAR_READWRITE);
|
||||||
|
+ }
|
||||||
|
+ if (fd == -1) {
|
||||||
|
+ /* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
-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;
|
||||||
|
+ loadhist_cmd[1] = (flg & SRC_MFLAG) ? STRmm : STRmh;
|
||||||
|
|
||||||
|
if (fname != NULL)
|
||||||
|
loadhist_cmd[2] = fname;
|
||||||
|
@@ -464,5 +469,5 @@ loadhist(Char *fname, int mflg)
|
||||||
|
else
|
||||||
|
loadhist_cmd[2] = STRtildothist;
|
||||||
|
|
||||||
|
- dosource(loadhist_cmd, NULL);
|
||||||
|
+ return dosource(loadhist_cmd, NULL, flg);
|
||||||
|
}
|
||||||
|
diff --git a/sh.lex.c b/sh.lex.c
|
||||||
|
index 536097e..2543552 100644
|
||||||
|
--- a/sh.lex.c
|
||||||
|
+++ b/sh.lex.c
|
||||||
|
@@ -1589,7 +1589,7 @@ wide_read(int fildes, Char *buf, size_t nchars, int use_fclens)
|
||||||
|
/* 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, -partial, SEEK_CUR);
|
||||||
|
errno = err;
|
||||||
|
return res != 0 ? res : r;
|
||||||
|
}
|
||||||
|
@@ -1604,7 +1604,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
|
||||||
|
@@ -1808,7 +1808,7 @@ btell(struct Ain *l)
|
||||||
|
void
|
||||||
|
btoeof(void)
|
||||||
|
{
|
||||||
|
- (void) lseek(SHIN, (off_t) 0, L_XTND);
|
||||||
|
+ (void) lseek(SHIN, 0, SEEK_END);
|
||||||
|
aret = TCSH_F_SEEK;
|
||||||
|
fseekp = feobp;
|
||||||
|
alvec = NULL;
|
||||||
|
@@ -1826,7 +1826,7 @@ settell(void)
|
||||||
|
cantell = 0;
|
||||||
|
if (arginp || onelflg || intty)
|
||||||
|
return;
|
||||||
|
- if ((x = lseek(SHIN, (off_t) 0, L_INCR)) == -1)
|
||||||
|
+ if ((x = lseek(SHIN, 0, SEEK_CUR)) == -1)
|
||||||
|
return;
|
||||||
|
fbuf = xcalloc(2, sizeof(Char **));
|
||||||
|
fblocks = 1;
|
||||||
|
diff --git a/sh.sem.c b/sh.sem.c
|
||||||
|
index 7c5511a..b8eee96 100644
|
||||||
|
--- a/sh.sem.c
|
||||||
|
+++ b/sh.sem.c
|
||||||
|
@@ -879,7 +879,7 @@ doio(struct command *t, int *pipein, int *pipeout)
|
||||||
|
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, 0, SEEK_END);
|
||||||
|
#endif /* O_APPEND */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
--
|
||||||
|
1.7.6.2
|
||||||
|
|
10
tcsh.spec
10
tcsh.spec
@ -43,6 +43,8 @@ Patch26: tcsh-6.17.00-variable-names.patch
|
|||||||
Patch27: tcsh-6.17.00-status-pipeline-backquote-list-of-cmds.patch
|
Patch27: tcsh-6.17.00-status-pipeline-backquote-list-of-cmds.patch
|
||||||
# Proposed to upstream (http://bugs.gw.com/view.php?id=121)
|
# Proposed to upstream (http://bugs.gw.com/view.php?id=121)
|
||||||
Patch28: tcsh-6.17.00-manpage-spelling.patch
|
Patch28: tcsh-6.17.00-manpage-spelling.patch
|
||||||
|
Patch30: tcsh-6.17.00-handle-signals-before-flush.patch
|
||||||
|
Patch31: tcsh-6.17.00-history-file-locking.patch
|
||||||
|
|
||||||
Provides: csh = %{version}
|
Provides: csh = %{version}
|
||||||
Requires(post): grep
|
Requires(post): grep
|
||||||
@ -85,6 +87,8 @@ like syntax.
|
|||||||
%patch26 -p1 -b .variable-names
|
%patch26 -p1 -b .variable-names
|
||||||
%patch27 -p1 -b .status-pipeline-backquote-list-of-cmds
|
%patch27 -p1 -b .status-pipeline-backquote-list-of-cmds
|
||||||
%patch28 -p1 -b .manpage-spelling
|
%patch28 -p1 -b .manpage-spelling
|
||||||
|
%patch30 -p1 -b .handle-signals-before-flush
|
||||||
|
%patch31 -p1 -b .history-file-locking
|
||||||
|
|
||||||
for i in Fixes WishList; do
|
for i in Fixes WishList; do
|
||||||
iconv -f iso-8859-1 -t utf-8 "$i" > "${i}_" && \
|
iconv -f iso-8859-1 -t utf-8 "$i" > "${i}_" && \
|
||||||
@ -158,6 +162,12 @@ fi
|
|||||||
%{_mandir}/man1/*.1*
|
%{_mandir}/man1/*.1*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Feb 16 2012 Vojtech Vitek (V-Teq) <vvitek@redhat.com> - 6.17-19
|
||||||
|
- Handle pending signals before flush so that the the .history file
|
||||||
|
does not get truncated (#653054)
|
||||||
|
- Implement file locking using shared readers, exclusive writer
|
||||||
|
to prevent any .history file data corruption (#653054)
|
||||||
|
|
||||||
* Sat Jan 14 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 6.17-18
|
* Sat Jan 14 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 6.17-18
|
||||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user