Roman Kollar 2acb8bf
From f813180f2fc1d682dd097e4a05ef4d15000204ad Mon Sep 17 00:00:00 2001
Roman Kollar 5b57aa6
From: Roman Kollar <rkollar@redhat.com>
Roman Kollar 2acb8bf
Date: Mon, 29 Oct 2012 17:52:52 +0100
Vojtech Vitek (V-Teq) c6c5f0d
Subject: [PATCH] Add .history file locking - shared readers, exclusive writer
Vojtech Vitek (V-Teq) c8ffd86
Vojtech Vitek (V-Teq) c8ffd86
Originally reported at Red Hat Bugzilla:
Vojtech Vitek (V-Teq) c8ffd86
https://bugzilla.redhat.com/show_bug.cgi?id=648592
Vojtech Vitek (V-Teq) c8ffd86
Vojtech Vitek (V-Teq) c8ffd86
Patch by Vojtech Vitek (V-Teq) <vvitek@redhat.com>
bed5d53
bed5d53
Additional changes reflecting:
bed5d53
https://bugzilla.redhat.com/show_bug.cgi?id=879371
bed5d53
bed5d53
Changes by Fridolin Pokorny <fpokorny@redhat.com>
bed5d53
Vojtech Vitek (V-Teq) c8ffd86
---
Vojtech Vitek (V-Teq) c8ffd86
bed5d53
diff -upr tcsh-6.18.00_orig/sh.c tcsh-6.18.00_work/sh.c
bed5d53
--- tcsh-6.18.00_orig/sh.c	2013-03-28 10:06:17.969859477 +0100
bed5d53
+++ tcsh-6.18.00_work/sh.c	2013-03-28 10:07:21.155082032 +0100
Vojtech Vitek (V-Teq) c8ffd86
@@ -140,6 +140,7 @@ struct saved_state {
Vojtech Vitek (V-Teq) c8ffd86
     int	  cantell;
Vojtech Vitek (V-Teq) c8ffd86
     struct Bin	  B;
Vojtech Vitek (V-Teq) c8ffd86
     int		  justpr;
Vojtech Vitek (V-Teq) c8ffd86
+    int		  close_unit;
Vojtech Vitek (V-Teq) c8ffd86
 };
Vojtech Vitek (V-Teq) c8ffd86
 
Vojtech Vitek (V-Teq) c8ffd86
 static	int		  srccat	(Char *, Char *);
Vojtech Vitek (V-Teq) 66fbce9
@@ -1369,7 +1370,7 @@ main(int argc, char **argv)
Vojtech Vitek (V-Teq) c8ffd86
 	/*
Vojtech Vitek (V-Teq) c8ffd86
 	 * Source history before .login so that it is available in .login
Vojtech Vitek (V-Teq) c8ffd86
 	 */
Vojtech Vitek (V-Teq) c8ffd86
-	loadhist(NULL, 0);
Vojtech Vitek (V-Teq) c6c5f0d
+	loadhist(NULL, HIST_FILE_RDLCK);
Vojtech Vitek (V-Teq) c8ffd86
 #ifndef LOGINFIRST
Vojtech Vitek (V-Teq) c8ffd86
 	if (loginsh)
Vojtech Vitek (V-Teq) c8ffd86
 	    (void) srccat(varval(STRhome), STRsldotlogin);
Vojtech Vitek (V-Teq) c6c5f0d
@@ -1492,7 +1493,7 @@ static int
Vojtech Vitek (V-Teq) c6c5f0d
 srccat(Char *cp, Char *dp)
Vojtech Vitek (V-Teq) c6c5f0d
 {
Vojtech Vitek (V-Teq) c6c5f0d
     if (cp[0] == '/' && cp[1] == '\0') 
Vojtech Vitek (V-Teq) c6c5f0d
-	return srcfile(short2str(dp), (mflag ? 0 : 1), 0, NULL);
Vojtech Vitek (V-Teq) c6c5f0d
+	return srcfile(short2str(dp), (mflag ? 0 : HIST_ONLY), 0, NULL);
Vojtech Vitek (V-Teq) c6c5f0d
     else {
Vojtech Vitek (V-Teq) c6c5f0d
 	Char *ep;
Vojtech Vitek (V-Teq) c6c5f0d
 	char   *ptr;
Vojtech Vitek (V-Teq) c6c5f0d
@@ -1508,7 +1509,7 @@ srccat(Char *cp, Char *dp)
Vojtech Vitek (V-Teq) c6c5f0d
 	cleanup_push(ep, xfree);
Vojtech Vitek (V-Teq) c6c5f0d
 	ptr = short2str(ep);
Vojtech Vitek (V-Teq) c6c5f0d
 
Vojtech Vitek (V-Teq) c6c5f0d
-	rv = srcfile(ptr, (mflag ? 0 : 1), 0, NULL);
Vojtech Vitek (V-Teq) c6c5f0d
+	rv = srcfile(ptr, (mflag ? 0 : HIST_ONLY), 0, NULL);
Vojtech Vitek (V-Teq) c6c5f0d
 	cleanup_until(ep);
Vojtech Vitek (V-Teq) c6c5f0d
 	return rv;
Vojtech Vitek (V-Teq) c6c5f0d
     }
Vojtech Vitek (V-Teq) c6c5f0d
@@ -1522,20 +1523,49 @@ static int
Vojtech Vitek (V-Teq) c8ffd86
 #else
Vojtech Vitek (V-Teq) c8ffd86
 int
Vojtech Vitek (V-Teq) c8ffd86
 #endif /*WINNT_NATIVE*/
Vojtech Vitek (V-Teq) c8ffd86
-srcfile(const char *f, int onlyown, int flag, Char **av)
Vojtech Vitek (V-Teq) c8ffd86
+srcfile(const char *f, int onlyown, int flg, Char **av)
Vojtech Vitek (V-Teq) c8ffd86
 {
Vojtech Vitek (V-Teq) c8ffd86
-    int unit;
Vojtech Vitek (V-Teq) c8ffd86
-
Vojtech Vitek (V-Teq) c8ffd86
-    if ((unit = xopen(f, O_RDONLY|O_LARGEFILE)) == -1) 
Vojtech Vitek (V-Teq) c8ffd86
-	return 0;
Vojtech Vitek (V-Teq) c8ffd86
-    cleanup_push(&unit, open_cleanup);
Vojtech Vitek (V-Teq) c8ffd86
-    unit = dmove(unit, -1);
Vojtech Vitek (V-Teq) c8ffd86
-    cleanup_ignore(&unit);
Vojtech Vitek (V-Teq) c8ffd86
-    cleanup_until(&unit);
Vojtech Vitek (V-Teq) c8ffd86
-
Vojtech Vitek (V-Teq) c8ffd86
-    (void) close_on_exec(unit, 1);
Vojtech Vitek (V-Teq) c8ffd86
-    srcunit(unit, onlyown, flag, av);
Vojtech Vitek (V-Teq) c8ffd86
-    return 1;
Vojtech Vitek (V-Teq) c6c5f0d
+    int *unit;
Vojtech Vitek (V-Teq) c8ffd86
+
Vojtech Vitek (V-Teq) c8ffd86
+    unit = xmalloc(sizeof(*unit));
Vojtech Vitek (V-Teq) c8ffd86
+    cleanup_push(unit, xfree);
Vojtech Vitek (V-Teq) c8ffd86
+    *unit = xopen(f, O_LARGEFILE |
Vojtech Vitek (V-Teq) c6c5f0d
+		    ((flg & HIST_FILE_WRLCK) ? (O_CREAT|O_RDWR) : O_RDONLY), 0600);
Vojtech Vitek (V-Teq) c6c5f0d
+    if (*unit == -1)
Vojtech Vitek (V-Teq) c6c5f0d
+	return 0; /* Error. */
Vojtech Vitek (V-Teq) c8ffd86
+
Vojtech Vitek (V-Teq) c8ffd86
+    cleanup_push(unit, open_cleanup);
Vojtech Vitek (V-Teq) c8ffd86
+    *unit = dmove(*unit, -1);
Vojtech Vitek (V-Teq) c8ffd86
+    (void) close_on_exec(*unit, 1);
Vojtech Vitek (V-Teq) c8ffd86
+
Vojtech Vitek (V-Teq) c6c5f0d
+    if (flg & (HIST_FILE_WRLCK | HIST_FILE_RDLCK)) {
Vojtech Vitek (V-Teq) c8ffd86
+	struct flock fl;
Vojtech Vitek (V-Teq) 66fbce9
+
Vojtech Vitek (V-Teq) c6c5f0d
+	fl.l_type = (flg & HIST_FILE_WRLCK) ? F_WRLCK : F_RDLCK;
Vojtech Vitek (V-Teq) c8ffd86
+	fl.l_whence = SEEK_SET;
Vojtech Vitek (V-Teq) c8ffd86
+	fl.l_start = 0;
Vojtech Vitek (V-Teq) c8ffd86
+	fl.l_len = 0;
Vojtech Vitek (V-Teq) c8ffd86
+
Vojtech Vitek (V-Teq) c6c5f0d
+	cleanup_push(unit, fcntl_cleanup);
Vojtech Vitek (V-Teq) c6c5f0d
+	if (fcntl(*unit, F_SETLKW, &fl) == -1)
Vojtech Vitek (V-Teq) c6c5f0d
+	    cleanup_ignore(unit);
Vojtech Vitek (V-Teq) c8ffd86
+    }
Vojtech Vitek (V-Teq) c8ffd86
+
Vojtech Vitek (V-Teq) c6c5f0d
+    srcunit(*unit, onlyown, flg, av);
Vojtech Vitek (V-Teq) c8ffd86
+
Vojtech Vitek (V-Teq) c6c5f0d
+    /* Unlock the unit, if we don't want to leave it locked (or open). */
Vojtech Vitek (V-Teq) c6c5f0d
+    if ((flg & (HIST_FILE_WRLCK | HIST_FILE_RDLCK)) &&
Vojtech Vitek (V-Teq) c6c5f0d
+        (!(flg & HIST_FILE_LOCK) || !(flg & HIST_FILE_OPEN)))
Vojtech Vitek (V-Teq) c8ffd86
+	cleanup_until(unit); /* fcntl_cleanup */
Vojtech Vitek (V-Teq) 66fbce9
+
Vojtech Vitek (V-Teq) c6c5f0d
+    /* Close the unit, if we don't want to leave it open. */
Vojtech Vitek (V-Teq) c6c5f0d
+    if (!(flg & HIST_FILE_OPEN)) {
Vojtech Vitek (V-Teq) c6c5f0d
+	cleanup_until(unit); /* open_cleanup */
Vojtech Vitek (V-Teq) c6c5f0d
+	cleanup_until(unit); /* xfree */
Vojtech Vitek (V-Teq) c6c5f0d
+	return -1; /* Not error but invalid file descriptor. */
Vojtech Vitek (V-Teq) c8ffd86
+    }
Vojtech Vitek (V-Teq) 66fbce9
+
Vojtech Vitek (V-Teq) c6c5f0d
+    return *unit; /* File descriptor (fd > FSAFE). */
Vojtech Vitek (V-Teq) c8ffd86
 }
Vojtech Vitek (V-Teq) c8ffd86
 
Vojtech Vitek (V-Teq) c8ffd86
 
bed5d53
@@ -1544,7 +1574,7 @@ srcfile(const char *f, int onlyown, int
Vojtech Vitek (V-Teq) c6c5f0d
  * fd.
Vojtech Vitek (V-Teq) c6c5f0d
  */
Vojtech Vitek (V-Teq) c6c5f0d
 static void
Vojtech Vitek (V-Teq) c6c5f0d
-st_save(struct saved_state *st, int unit, int hflg, Char **al, Char **av)
Vojtech Vitek (V-Teq) c6c5f0d
+st_save(struct saved_state *st, int unit, int flg, Char **al, Char **av)
Vojtech Vitek (V-Teq) c6c5f0d
 {
Vojtech Vitek (V-Teq) c6c5f0d
     st->insource	= insource;
Vojtech Vitek (V-Teq) c6c5f0d
     st->SHIN		= SHIN;
bed5d53
@@ -1593,10 +1623,14 @@ st_save(struct saved_state *st, int unit
Vojtech Vitek (V-Teq) c8ffd86
     st->onelflg		= onelflg;
Vojtech Vitek (V-Teq) c8ffd86
     st->enterhist	= enterhist;
Vojtech Vitek (V-Teq) c8ffd86
     st->justpr		= justpr;
Vojtech Vitek (V-Teq) c8ffd86
-    if (hflg)
Vojtech Vitek (V-Teq) c6c5f0d
+    if (flg & (HIST_ONLY | HIST_MERGE))
Vojtech Vitek (V-Teq) c8ffd86
 	st->HIST	= HIST;
Vojtech Vitek (V-Teq) c8ffd86
     else
Vojtech Vitek (V-Teq) c8ffd86
 	st->HIST	= '\0';
Vojtech Vitek (V-Teq) c6c5f0d
+    if (flg & HIST_FILE_OPEN)
Vojtech Vitek (V-Teq) c8ffd86
+	st->close_unit = 0;
Vojtech Vitek (V-Teq) c8ffd86
+    else
Vojtech Vitek (V-Teq) c8ffd86
+	st->close_unit = 1;
Vojtech Vitek (V-Teq) c8ffd86
     st->cantell		= cantell;
Vojtech Vitek (V-Teq) c8ffd86
     cpybin(st->B, B);
Vojtech Vitek (V-Teq) c8ffd86
 
bed5d53
@@ -1635,7 +1669,7 @@ st_save(struct saved_state *st, int unit
Vojtech Vitek (V-Teq) c6c5f0d
     evalp	= 0;
Vojtech Vitek (V-Teq) c6c5f0d
     alvec	= al;
Vojtech Vitek (V-Teq) c6c5f0d
     alvecp	= 0;
Vojtech Vitek (V-Teq) c6c5f0d
-    enterhist	= hflg;
Vojtech Vitek (V-Teq) c6c5f0d
+    enterhist	= flg & (HIST_ONLY | HIST_MERGE);
Vojtech Vitek (V-Teq) c6c5f0d
     if (enterhist)
Vojtech Vitek (V-Teq) c6c5f0d
 	HIST	= '\0';
Vojtech Vitek (V-Teq) c6c5f0d
     insource	= 1;
Vojtech Vitek (V-Teq) c6c5f0d
@@ -1668,7 +1702,8 @@ st_restore(void *xst)
Vojtech Vitek (V-Teq) c8ffd86
     }
Vojtech Vitek (V-Teq) c8ffd86
     cpybin(B, st->B);
Vojtech Vitek (V-Teq) c8ffd86
 
Vojtech Vitek (V-Teq) c8ffd86
-    xclose(SHIN);
Vojtech Vitek (V-Teq) c8ffd86
+    if (st->close_unit)
Vojtech Vitek (V-Teq) c8ffd86
+	xclose(SHIN);
Vojtech Vitek (V-Teq) c8ffd86
 
Vojtech Vitek (V-Teq) c8ffd86
     insource	= st->insource;
Vojtech Vitek (V-Teq) c8ffd86
     SHIN	= st->SHIN;
Vojtech Vitek (V-Teq) c6c5f0d
@@ -1704,7 +1739,7 @@ st_restore(void *xst)
Vojtech Vitek (V-Teq) c6c5f0d
  * we don't chance it.	This occurs on ".cshrc"s and the like.
Vojtech Vitek (V-Teq) c6c5f0d
  */
Vojtech Vitek (V-Teq) c6c5f0d
 static void
Vojtech Vitek (V-Teq) c6c5f0d
-srcunit(int unit, int onlyown, int hflg, Char **av)
Vojtech Vitek (V-Teq) c6c5f0d
+srcunit(int unit, int onlyown, int flg, Char **av)
Vojtech Vitek (V-Teq) c6c5f0d
 {
Vojtech Vitek (V-Teq) c6c5f0d
     struct saved_state st;
Vojtech Vitek (V-Teq) c6c5f0d
 
bed5d53
@@ -1730,7 +1765,7 @@ srcunit(int unit, int onlyown, int hflg,
Vojtech Vitek (V-Teq) c6c5f0d
     }
Vojtech Vitek (V-Teq) c6c5f0d
 
Vojtech Vitek (V-Teq) c6c5f0d
     /* Save the current state and move us to a new state */
Vojtech Vitek (V-Teq) c6c5f0d
-    st_save(&st, unit, hflg, NULL, av);
Vojtech Vitek (V-Teq) c6c5f0d
+    st_save(&st, unit, flg, NULL, av);
Vojtech Vitek (V-Teq) c6c5f0d
 
Vojtech Vitek (V-Teq) c6c5f0d
     /*
Vojtech Vitek (V-Teq) c6c5f0d
      * Now if we are allowing commands to be interrupted, we let ourselves be
bed5d53
@@ -2069,7 +2104,7 @@ process(int catch)
bed5d53
 	 * elsewhere...
bed5d53
 	 */
bed5d53
 	if (enterhist || (catch && intty && !whyles && !tellwhat && !arun))
bed5d53
-	    savehist(&paraml, enterhist > 1);
bed5d53
+	    savehist(&paraml, enterhist > 1 ? HIST_MERGE : 0);
bed5d53
 
bed5d53
 	if (Expand && seterr)
bed5d53
 	    Expand = 0;
Roman Kollar 2acb8bf
@@ -2156,21 +2191,28 @@ process(int catch)
Roman Kollar 2acb8bf
 void
Roman Kollar 2acb8bf
 dosource(Char **t, struct command *c)
Vojtech Vitek (V-Teq) c8ffd86
 {
Roman Kollar 2acb8bf
+    (void) dosource_flg(t, c, 0);
Roman Kollar 2acb8bf
+}
Roman Kollar 2acb8bf
+
Roman Kollar 2acb8bf
+int
Roman Kollar 2acb8bf
+dosource_flg(Char **t, struct command *c, int flg)
Roman Kollar 2acb8bf
+{
Vojtech Vitek (V-Teq) c8ffd86
     Char *f;
Vojtech Vitek (V-Teq) c8ffd86
-    int    hflg = 0;
Vojtech Vitek (V-Teq) c8ffd86
     char *file;
Vojtech Vitek (V-Teq) c8ffd86
+    int fd;
Vojtech Vitek (V-Teq) c6c5f0d
+    int newflg = 0;
Vojtech Vitek (V-Teq) c8ffd86
 
Vojtech Vitek (V-Teq) c8ffd86
     USE(c);
Vojtech Vitek (V-Teq) c8ffd86
     t++;
Vojtech Vitek (V-Teq) c8ffd86
     if (*t && eq(*t, STRmh)) {
Vojtech Vitek (V-Teq) c8ffd86
 	if (*++t == NULL)
Vojtech Vitek (V-Teq) c8ffd86
 	    stderror(ERR_NAME | ERR_HFLAG);
Vojtech Vitek (V-Teq) c8ffd86
-	hflg++;
Vojtech Vitek (V-Teq) c6c5f0d
+	newflg |= HIST_ONLY;
Vojtech Vitek (V-Teq) c8ffd86
     }
Vojtech Vitek (V-Teq) c8ffd86
     else if (*t && eq(*t, STRmm)) {
Vojtech Vitek (V-Teq) c8ffd86
     	if (*++t == NULL)
Vojtech Vitek (V-Teq) c8ffd86
 	    stderror(ERR_NAME | ERR_MFLAG);
Vojtech Vitek (V-Teq) c8ffd86
-	hflg = 2;
Vojtech Vitek (V-Teq) c6c5f0d
+	newflg |= HIST_MERGE;
Vojtech Vitek (V-Teq) c8ffd86
     }
Vojtech Vitek (V-Teq) c8ffd86
 
Vojtech Vitek (V-Teq) c8ffd86
     f = globone(*t++, G_ERROR);
Roman Kollar 2acb8bf
@@ -2178,9 +2220,16 @@ dosource(Char **t, struct command *c)
Vojtech Vitek (V-Teq) c8ffd86
     cleanup_push(file, xfree);
Vojtech Vitek (V-Teq) c8ffd86
     xfree(f);
Vojtech Vitek (V-Teq) c8ffd86
     t = glob_all_or_error(t);
Vojtech Vitek (V-Teq) c8ffd86
-    if ((!srcfile(file, 0, hflg, t)) && (!hflg) && (!bequiet))
Vojtech Vitek (V-Teq) c6c5f0d
+    fd = srcfile(file, 0, (flg | newflg), t);
Vojtech Vitek (V-Teq) c6c5f0d
+    if ((!fd) && (!newflg) && (!bequiet))
Roman Kollar 5b57aa6
 	stderror(ERR_SYSTEM, file, strerror(errno));
Roman Kollar 5b57aa6
-    cleanup_until(file);
Vojtech Vitek (V-Teq) 66fbce9
+
Vojtech Vitek (V-Teq) c6c5f0d
+    /* We need to preserve fd and it's cleaning routines on the top of the
Vojtech Vitek (V-Teq) c6c5f0d
+     * cleaning stack. Don't call cleanup_until() but clean it manually. */
Vojtech Vitek (V-Teq) c8ffd86
+    cleanup_ignore(file);
Vojtech Vitek (V-Teq) c8ffd86
+    xfree(file);
Vojtech Vitek (V-Teq) 66fbce9
+
Vojtech Vitek (V-Teq) c6c5f0d
+    return fd; /* Valid/invalid file descriptor (>FSAVE, -1). Zero on error. */
Vojtech Vitek (V-Teq) c8ffd86
 }
Vojtech Vitek (V-Teq) c8ffd86
 
Vojtech Vitek (V-Teq) c8ffd86
 /*
bed5d53
diff -upr tcsh-6.18.00_orig/sh.decls.h tcsh-6.18.00_work/sh.decls.h
bed5d53
--- tcsh-6.18.00_orig/sh.decls.h	2013-03-28 10:06:17.988859538 +0100
bed5d53
+++ tcsh-6.18.00_work/sh.decls.h	2013-03-28 10:06:42.897948590 +0100
Roman Kollar 2acb8bf
@@ -38,6 +38,7 @@
Vojtech Vitek (V-Teq) c8ffd86
  */
Vojtech Vitek (V-Teq) c8ffd86
 extern	Char	 	 *gethdir	(const Char *);
Roman Kollar 2acb8bf
 extern	void		  dosource	(Char **, struct command *);
Roman Kollar 2acb8bf
+extern	int		  dosource_flg	(Char **, struct command *, int);
Vojtech Vitek (V-Teq) c8ffd86
 extern	void		  exitstat	(void);
Vojtech Vitek (V-Teq) c8ffd86
 extern	void		  goodbye	(Char **, struct command *);
Vojtech Vitek (V-Teq) c8ffd86
 extern	void		  importpath	(Char *);
Roman Kollar 2acb8bf
@@ -98,6 +99,7 @@ extern	void		  cleanup_until_mark(void);
Vojtech Vitek (V-Teq) c8ffd86
 extern	size_t		  cleanup_push_mark(void);
Vojtech Vitek (V-Teq) c8ffd86
 extern	void		  cleanup_pop_mark(size_t);
Vojtech Vitek (V-Teq) c8ffd86
 extern	void		  open_cleanup(void *);
Vojtech Vitek (V-Teq) c8ffd86
+extern	void		  fcntl_cleanup(void *);
Vojtech Vitek (V-Teq) c8ffd86
 extern	void		  opendir_cleanup(void *);
Vojtech Vitek (V-Teq) c8ffd86
 extern	void		  sigint_cleanup(void *);
Vojtech Vitek (V-Teq) c8ffd86
 extern	void		  sigprocmask_cleanup(void *);
bed5d53
@@ -219,7 +221,7 @@ extern  struct Hist 	 *enthist	(int, str
Vojtech Vitek (V-Teq) c8ffd86
 extern	void	 	  savehist	(struct wordent *, int);
Vojtech Vitek (V-Teq) c8ffd86
 extern	char		 *fmthist	(int, ptr_t);
Vojtech Vitek (V-Teq) c8ffd86
 extern	void		  rechist	(Char *, int);
Vojtech Vitek (V-Teq) c8ffd86
-extern	void		  loadhist	(Char *, int);
Vojtech Vitek (V-Teq) c8ffd86
+extern	int		  loadhist	(Char *, int);
Vojtech Vitek (V-Teq) 66fbce9
 extern	void		  displayHistStats(const char *);
Vojtech Vitek (V-Teq) c8ffd86
 
Vojtech Vitek (V-Teq) c8ffd86
 /*
bed5d53
diff -upr tcsh-6.18.00_orig/sh.dol.c tcsh-6.18.00_work/sh.dol.c
bed5d53
--- tcsh-6.18.00_orig/sh.dol.c	2013-03-28 10:06:17.988859538 +0100
bed5d53
+++ tcsh-6.18.00_work/sh.dol.c	2013-03-28 10:06:42.898948594 +0100
Vojtech Vitek (V-Teq) 66fbce9
@@ -1110,6 +1110,6 @@ again:
Vojtech Vitek (V-Teq) c8ffd86
     *obp = 0;
Vojtech Vitek (V-Teq) c8ffd86
     tmp = short2str(obuf);
Vojtech Vitek (V-Teq) c8ffd86
     (void) xwrite(0, tmp, strlen (tmp));
Vojtech Vitek (V-Teq) c8ffd86
-    (void) lseek(0, (off_t) 0, L_SET);
Roman Kollar 5b57aa6
+    (void) lseek(0, (off_t) 0, SEEK_SET);
Vojtech Vitek (V-Teq) c8ffd86
     cleanup_until(&inheredoc);
Vojtech Vitek (V-Teq) c8ffd86
 }
bed5d53
diff -upr tcsh-6.18.00_orig/sh.err.c tcsh-6.18.00_work/sh.err.c
bed5d53
--- tcsh-6.18.00_orig/sh.err.c	2013-03-28 10:06:17.972859480 +0100
bed5d53
+++ tcsh-6.18.00_work/sh.err.c	2013-03-28 10:06:42.824948331 +0100
Vojtech Vitek (V-Teq) 66fbce9
@@ -514,6 +514,22 @@ open_cleanup(void *xptr)
Vojtech Vitek (V-Teq) c8ffd86
 }
Vojtech Vitek (V-Teq) c8ffd86
 
Vojtech Vitek (V-Teq) c8ffd86
 void
Vojtech Vitek (V-Teq) c8ffd86
+fcntl_cleanup(void *xptr)
Vojtech Vitek (V-Teq) c8ffd86
+{
Vojtech Vitek (V-Teq) c8ffd86
+    int *ptr;
Vojtech Vitek (V-Teq) c8ffd86
+    struct flock fl;
Vojtech Vitek (V-Teq) c8ffd86
+
Vojtech Vitek (V-Teq) c8ffd86
+    ptr = xptr;
Vojtech Vitek (V-Teq) 66fbce9
+
Vojtech Vitek (V-Teq) c8ffd86
+    fl.l_type = F_UNLCK;
Vojtech Vitek (V-Teq) c8ffd86
+    fl.l_whence = SEEK_SET;
Vojtech Vitek (V-Teq) c8ffd86
+    fl.l_start = 0;
Vojtech Vitek (V-Teq) c8ffd86
+    fl.l_len = 0;
Vojtech Vitek (V-Teq) 66fbce9
+
Vojtech Vitek (V-Teq) c8ffd86
+    fcntl(*ptr, F_SETLK, &fl);
Vojtech Vitek (V-Teq) c8ffd86
+}
Vojtech Vitek (V-Teq) c8ffd86
+
Vojtech Vitek (V-Teq) c8ffd86
+void
Vojtech Vitek (V-Teq) c8ffd86
 opendir_cleanup(void *xdir)
Vojtech Vitek (V-Teq) c8ffd86
 {
Vojtech Vitek (V-Teq) c8ffd86
     DIR *dir;
bed5d53
diff -upr tcsh-6.18.00_orig/sh.h tcsh-6.18.00_work/sh.h
bed5d53
--- tcsh-6.18.00_orig/sh.h	2013-03-28 10:06:17.988859538 +0100
bed5d53
+++ tcsh-6.18.00_work/sh.h	2013-03-28 10:06:42.899948597 +0100
Vojtech Vitek (V-Teq) c6c5f0d
@@ -50,6 +50,24 @@
Vojtech Vitek (V-Teq) c8ffd86
 # include <inttypes.h>
Vojtech Vitek (V-Teq) c8ffd86
 #endif
Vojtech Vitek (V-Teq) c8ffd86
 
Vojtech Vitek (V-Teq) c8ffd86
+#include <unistd.h>
Vojtech Vitek (V-Teq) c8ffd86
+#include <fcntl.h>
Vojtech Vitek (V-Teq) c6c5f0d
+
Vojtech Vitek (V-Teq) c8ffd86
+/*
Vojtech Vitek (V-Teq) c6c5f0d
+ * History flags.
Vojtech Vitek (V-Teq) c8ffd86
+ */
Vojtech Vitek (V-Teq) c6c5f0d
+#define HIST_ONLY	0x001
Vojtech Vitek (V-Teq) c6c5f0d
+#define HIST_SAVE	0x002
Vojtech Vitek (V-Teq) c6c5f0d
+#define HIST_LOAD	0x004
Vojtech Vitek (V-Teq) c6c5f0d
+#define HIST_REV	0x008
Vojtech Vitek (V-Teq) c6c5f0d
+#define HIST_CLEAR	0x010
Vojtech Vitek (V-Teq) c6c5f0d
+#define HIST_MERGE	0x020
Vojtech Vitek (V-Teq) c6c5f0d
+#define HIST_TIME	0x040
Vojtech Vitek (V-Teq) c6c5f0d
+#define HIST_FILE_WRLCK	0x080 /* Write lock */
Vojtech Vitek (V-Teq) c6c5f0d
+#define HIST_FILE_RDLCK	0x100 /* Read lock */
Vojtech Vitek (V-Teq) c6c5f0d
+#define HIST_FILE_OPEN	0x200 /* Leave file open */
Vojtech Vitek (V-Teq) c6c5f0d
+#define HIST_FILE_LOCK	0x400 /* Leave file locked */
Vojtech Vitek (V-Teq) c8ffd86
+
Vojtech Vitek (V-Teq) c8ffd86
 #if !defined(HAVE_STDINT_H) && !defined(HAVE_INTTYPES_H) && !defined(WINNT_NATIVE)
Vojtech Vitek (V-Teq) c8ffd86
 typedef unsigned long intptr_t;
Vojtech Vitek (V-Teq) c8ffd86
 #endif
bed5d53
diff -upr tcsh-6.18.00_orig/sh.hist.c tcsh-6.18.00_work/sh.hist.c
bed5d53
--- tcsh-6.18.00_orig/sh.hist.c	2013-03-28 10:06:17.967859465 +0100
bed5d53
+++ tcsh-6.18.00_work/sh.hist.c	2013-03-28 10:06:42.815948309 +0100
Vojtech Vitek (V-Teq) c6c5f0d
@@ -44,14 +44,6 @@ Char HistLit = 0;
Vojtech Vitek (V-Teq) c6c5f0d
 static	int	heq	(const struct wordent *, const struct wordent *);
Vojtech Vitek (V-Teq) c6c5f0d
 static	void	hfree	(struct Hist *);
Vojtech Vitek (V-Teq) c6c5f0d
 
Vojtech Vitek (V-Teq) c6c5f0d
-#define HIST_ONLY	0x01
Vojtech Vitek (V-Teq) c6c5f0d
-#define HIST_SAVE	0x02
Vojtech Vitek (V-Teq) c6c5f0d
-#define HIST_LOAD	0x04
Vojtech Vitek (V-Teq) c6c5f0d
-#define HIST_REV	0x08
Vojtech Vitek (V-Teq) c6c5f0d
-#define HIST_CLEAR	0x10
Vojtech Vitek (V-Teq) c6c5f0d
-#define HIST_MERGE	0x20
Vojtech Vitek (V-Teq) c6c5f0d
-#define HIST_TIME	0x40
Vojtech Vitek (V-Teq) c6c5f0d
-
Vojtech Vitek (V-Teq) c6c5f0d
 /*
Vojtech Vitek (V-Teq) c6c5f0d
  * C shell
Vojtech Vitek (V-Teq) c6c5f0d
  */
Vojtech Vitek (V-Teq) c6c5f0d
@@ -143,7 +135,7 @@ discardExcess(int histlen)
Vojtech Vitek (V-Teq) c6c5f0d
 void
Vojtech Vitek (V-Teq) c6c5f0d
 savehist(
Vojtech Vitek (V-Teq) c6c5f0d
   struct wordent *sp,
Vojtech Vitek (V-Teq) c6c5f0d
-  int mflg)				/* true if -m (merge) specified */
Vojtech Vitek (V-Teq) c6c5f0d
+  int flg)
Vojtech Vitek (V-Teq) c6c5f0d
 {
Vojtech Vitek (V-Teq) c6c5f0d
     int histlen = 0;
Vojtech Vitek (V-Teq) c6c5f0d
     Char   *cp;
Vojtech Vitek (V-Teq) c6c5f0d
@@ -160,7 +152,7 @@ savehist(
Vojtech Vitek (V-Teq) c6c5f0d
 	histlen = histlen * 10 + *cp++ - '0';
Vojtech Vitek (V-Teq) c6c5f0d
     }
Vojtech Vitek (V-Teq) c6c5f0d
     if (sp)
Vojtech Vitek (V-Teq) c6c5f0d
-        (void) enthist(++eventno, sp, 1, mflg, histlen);
Vojtech Vitek (V-Teq) c6c5f0d
+        (void) enthist(++eventno, sp, 1, flg, histlen);
Vojtech Vitek (V-Teq) c6c5f0d
     discardExcess(histlen);
Vojtech Vitek (V-Teq) c6c5f0d
 }
Vojtech Vitek (V-Teq) c6c5f0d
 
Vojtech Vitek (V-Teq) c6c5f0d
@@ -933,7 +925,7 @@ enthist(
Vojtech Vitek (V-Teq) c6c5f0d
   int event,				/* newly incremented global eventno */
Vojtech Vitek (V-Teq) c6c5f0d
   struct wordent *lp,
Vojtech Vitek (V-Teq) c6c5f0d
   int docopy,
Vojtech Vitek (V-Teq) c6c5f0d
-  int mflg,				/* true if merge requested */
Vojtech Vitek (V-Teq) c6c5f0d
+  int flg,
Vojtech Vitek (V-Teq) c6c5f0d
   int histlen)				/* -1 if unknown */
Vojtech Vitek (V-Teq) c6c5f0d
 {
Vojtech Vitek (V-Teq) c6c5f0d
     struct Hist *p = NULL, *pp = &Histlist, *pTime = NULL;
Vojtech Vitek (V-Teq) c6c5f0d
@@ -953,7 +945,7 @@ enthist(
Vojtech Vitek (V-Teq) c6c5f0d
 		    Htime = p->Htime;
Vojtech Vitek (V-Teq) c6c5f0d
                 /* If we are merging, and the old entry is at the place we want
Vojtech Vitek (V-Teq) c6c5f0d
                  * to insert the new entry, then remember the place. */
Vojtech Vitek (V-Teq) c6c5f0d
-                if (mflg && Htime != 0 && p->Hprev->Htime >= Htime)
Vojtech Vitek (V-Teq) c6c5f0d
+                if ((flg & HIST_MERGE) && Htime != 0 && p->Hprev->Htime >= Htime)
Vojtech Vitek (V-Teq) c6c5f0d
                     pTime = p->Hprev;
Vojtech Vitek (V-Teq) c6c5f0d
 		if (!fastMergeErase)
Vojtech Vitek (V-Teq) c6c5f0d
 		    renumberHist(p);	/* Reset Href of subsequent entries */
Vojtech Vitek (V-Teq) c6c5f0d
@@ -1012,7 +1004,7 @@ enthist(
Vojtech Vitek (V-Teq) c6c5f0d
     /* The head of history list is the default insertion point.
Vojtech Vitek (V-Teq) c6c5f0d
        If merging, advance insertion point, in pp, according to Htime. */
Vojtech Vitek (V-Teq) c6c5f0d
     /* XXX -- In histdup=all, Htime values can be non-monotonic. */
Vojtech Vitek (V-Teq) c6c5f0d
-    if (mflg) {                         /* merge according to np->Htime */
Vojtech Vitek (V-Teq) c6c5f0d
+    if (flg & HIST_MERGE) {             /* merge according to np->Htime */
Vojtech Vitek (V-Teq) c6c5f0d
         pp = mergeInsertionPoint(np, pTime);
Vojtech Vitek (V-Teq) c6c5f0d
         for (p = pp->Hnext; p && p->Htime == np->Htime; pp = p, p = p->Hnext) {
Vojtech Vitek (V-Teq) c6c5f0d
             if (heq(&p->Hlex, &np->Hlex)) {
Vojtech Vitek (V-Teq) c6c5f0d
@@ -1051,9 +1043,9 @@ hfree(struct Hist *hp)
Vojtech Vitek (V-Teq) c6c5f0d
 }
Vojtech Vitek (V-Teq) c6c5f0d
 
Vojtech Vitek (V-Teq) c6c5f0d
 PG_STATIC void
Vojtech Vitek (V-Teq) c6c5f0d
-phist(struct Hist *hp, int hflg)
Vojtech Vitek (V-Teq) c6c5f0d
+phist(struct Hist *hp, int flg)
Vojtech Vitek (V-Teq) c6c5f0d
 {
Vojtech Vitek (V-Teq) c6c5f0d
-    if (hflg & HIST_ONLY) {
Vojtech Vitek (V-Teq) c6c5f0d
+    if (flg & HIST_ONLY) {
Vojtech Vitek (V-Teq) c6c5f0d
 	int old_output_raw;
Vojtech Vitek (V-Teq) c6c5f0d
 
Vojtech Vitek (V-Teq) c6c5f0d
        /*
Vojtech Vitek (V-Teq) c6c5f0d
@@ -1065,7 +1057,7 @@ phist(struct Hist *hp, int hflg)
Vojtech Vitek (V-Teq) c6c5f0d
 	old_output_raw = output_raw;
Vojtech Vitek (V-Teq) c6c5f0d
         output_raw = 1;
Vojtech Vitek (V-Teq) c6c5f0d
 	cleanup_push(&old_output_raw, output_raw_restore);
Vojtech Vitek (V-Teq) c6c5f0d
-	if (hflg & HIST_TIME)
Vojtech Vitek (V-Teq) c6c5f0d
+	if (flg & HIST_TIME)
Vojtech Vitek (V-Teq) c6c5f0d
 	    /* 
Vojtech Vitek (V-Teq) c6c5f0d
 	     * Make file entry with history time in format:
Vojtech Vitek (V-Teq) c6c5f0d
 	     * "+NNNNNNNNNN" (10 digits, left padded with ascii '0') 
Vojtech Vitek (V-Teq) c6c5f0d
@@ -1096,7 +1088,7 @@ phist(struct Hist *hp, int hflg)
Vojtech Vitek (V-Teq) c6c5f0d
 }
Vojtech Vitek (V-Teq) c6c5f0d
 
Vojtech Vitek (V-Teq) c6c5f0d
 PG_STATIC void
Vojtech Vitek (V-Teq) c6c5f0d
-dophist(int n, int hflg)
Vojtech Vitek (V-Teq) c6c5f0d
+dophist(int n, int flg)
Vojtech Vitek (V-Teq) c6c5f0d
 {
Vojtech Vitek (V-Teq) c6c5f0d
     struct Hist *hp;
Vojtech Vitek (V-Teq) c6c5f0d
     if (setintr) {
Vojtech Vitek (V-Teq) c6c5f0d
@@ -1105,7 +1097,7 @@ dophist(int n, int hflg)
Vojtech Vitek (V-Teq) c6c5f0d
 	pintr_push_enable(&old_pintr_disabled);
Vojtech Vitek (V-Teq) c6c5f0d
 	cleanup_until(&old_pintr_disabled);
Vojtech Vitek (V-Teq) c6c5f0d
     }
Vojtech Vitek (V-Teq) c6c5f0d
-    if ((hflg & HIST_REV) == 0) {
Vojtech Vitek (V-Teq) c6c5f0d
+    if (!(flg & HIST_REV)) {
Vojtech Vitek (V-Teq) c6c5f0d
 	/* Since the history list is stored most recent first, non-reversing
Vojtech Vitek (V-Teq) c6c5f0d
 	 * print needs to print (backwards) up the list. */
Vojtech Vitek (V-Teq) c6c5f0d
 	if ((unsigned)n >= histCount)
Vojtech Vitek (V-Teq) c6c5f0d
@@ -1119,10 +1111,10 @@ dophist(int n, int hflg)
Vojtech Vitek (V-Teq) c6c5f0d
 	if (hp == NULL)
Vojtech Vitek (V-Teq) c6c5f0d
 	    return;			/* nothing to print */
Vojtech Vitek (V-Teq) c6c5f0d
 	for (; hp != &Histlist; hp = hp->Hprev)
Vojtech Vitek (V-Teq) c6c5f0d
-	    phist(hp, hflg);
Vojtech Vitek (V-Teq) c6c5f0d
+	    phist(hp, flg);
Vojtech Vitek (V-Teq) c6c5f0d
     } else {
Vojtech Vitek (V-Teq) c6c5f0d
 	for (hp = Histlist.Hnext; n-- > 0 && hp != NULL; hp = hp->Hnext)
Vojtech Vitek (V-Teq) c6c5f0d
-	    phist(hp, hflg);
Vojtech Vitek (V-Teq) c6c5f0d
+	    phist(hp, flg);
Vojtech Vitek (V-Teq) c6c5f0d
     }
Vojtech Vitek (V-Teq) c6c5f0d
 }
Vojtech Vitek (V-Teq) c6c5f0d
 
Vojtech Vitek (V-Teq) c6c5f0d
@@ -1130,7 +1122,7 @@ dophist(int n, int hflg)
Vojtech Vitek (V-Teq) c6c5f0d
 void
Vojtech Vitek (V-Teq) c6c5f0d
 dohist(Char **vp, struct command *c)
Vojtech Vitek (V-Teq) c6c5f0d
 {
Vojtech Vitek (V-Teq) c6c5f0d
-    int     n, hflg = 0;
Vojtech Vitek (V-Teq) c6c5f0d
+    int     n, flg = 0;
Vojtech Vitek (V-Teq) c6c5f0d
 
Vojtech Vitek (V-Teq) c6c5f0d
     USE(c);
Vojtech Vitek (V-Teq) c6c5f0d
     if (getn(varval(STRhistory)) == 0)
Vojtech Vitek (V-Teq) c6c5f0d
@@ -1141,40 +1133,40 @@ dohist(Char **vp, struct command *c)
Vojtech Vitek (V-Teq) c6c5f0d
 	while (*++vp2)
Vojtech Vitek (V-Teq) c6c5f0d
 	    switch (*vp2) {
Vojtech Vitek (V-Teq) c6c5f0d
 	    case 'c':
Vojtech Vitek (V-Teq) c6c5f0d
-		hflg |= HIST_CLEAR;
Vojtech Vitek (V-Teq) c6c5f0d
+		flg |= HIST_CLEAR;
Vojtech Vitek (V-Teq) c6c5f0d
 		break;
Vojtech Vitek (V-Teq) c6c5f0d
 	    case 'h':
Vojtech Vitek (V-Teq) c6c5f0d
-		hflg |= HIST_ONLY;
Vojtech Vitek (V-Teq) c6c5f0d
+		flg |= HIST_ONLY;
Vojtech Vitek (V-Teq) c6c5f0d
 		break;
Vojtech Vitek (V-Teq) c6c5f0d
 	    case 'r':
Vojtech Vitek (V-Teq) c6c5f0d
-		hflg |= HIST_REV;
Vojtech Vitek (V-Teq) c6c5f0d
+		flg |= HIST_REV;
Vojtech Vitek (V-Teq) c6c5f0d
 		break;
Vojtech Vitek (V-Teq) c6c5f0d
 	    case 'S':
Vojtech Vitek (V-Teq) c6c5f0d
-		hflg |= HIST_SAVE;
Vojtech Vitek (V-Teq) c6c5f0d
+		flg |= HIST_SAVE;
Vojtech Vitek (V-Teq) c6c5f0d
 		break;
Vojtech Vitek (V-Teq) c6c5f0d
 	    case 'L':
Vojtech Vitek (V-Teq) c6c5f0d
-		hflg |= HIST_LOAD;
Vojtech Vitek (V-Teq) c6c5f0d
+		flg |= HIST_LOAD;
Vojtech Vitek (V-Teq) c6c5f0d
 		break;
Vojtech Vitek (V-Teq) c6c5f0d
 	    case 'M':
Vojtech Vitek (V-Teq) c6c5f0d
-	    	hflg |= HIST_MERGE;
Vojtech Vitek (V-Teq) c6c5f0d
+	    	flg |= HIST_MERGE;
Vojtech Vitek (V-Teq) c6c5f0d
 		break;
Vojtech Vitek (V-Teq) c6c5f0d
 	    case 'T':
Vojtech Vitek (V-Teq) c6c5f0d
-	    	hflg |= HIST_TIME;
Vojtech Vitek (V-Teq) c6c5f0d
+	    	flg |= HIST_TIME;
Vojtech Vitek (V-Teq) c6c5f0d
 		break;
Vojtech Vitek (V-Teq) c6c5f0d
 	    default:
Vojtech Vitek (V-Teq) c6c5f0d
 		stderror(ERR_HISTUS, "chrSLMT");
Vojtech Vitek (V-Teq) c6c5f0d
 		break;
Vojtech Vitek (V-Teq) c6c5f0d
 	    }
Vojtech Vitek (V-Teq) c6c5f0d
     }
Vojtech Vitek (V-Teq) c6c5f0d
-    if (hflg & HIST_CLEAR) {
Vojtech Vitek (V-Teq) c6c5f0d
+    if (flg & HIST_CLEAR) {
Vojtech Vitek (V-Teq) c6c5f0d
         struct Hist *np, *hp;
Vojtech Vitek (V-Teq) c6c5f0d
         for (hp = &Histlist; (np = hp->Hnext) != NULL;)
Vojtech Vitek (V-Teq) c6c5f0d
             hremove(np), hfree(np);
Vojtech Vitek (V-Teq) c8ffd86
     }
Vojtech Vitek (V-Teq) c8ffd86
 
Vojtech Vitek (V-Teq) c6c5f0d
-    if (hflg & (HIST_LOAD | HIST_MERGE))
Vojtech Vitek (V-Teq) c8ffd86
-	loadhist(*vp, (hflg & HIST_MERGE) ? 1 : 0);
Vojtech Vitek (V-Teq) c6c5f0d
-    else if (hflg & HIST_SAVE)
Vojtech Vitek (V-Teq) c6c5f0d
+    if (flg & (HIST_LOAD | HIST_MERGE))
Vojtech Vitek (V-Teq) c6c5f0d
+	loadhist(*vp, (flg | HIST_FILE_RDLCK));
Vojtech Vitek (V-Teq) c6c5f0d
+    else if (flg & HIST_SAVE)
Vojtech Vitek (V-Teq) c8ffd86
 	rechist(*vp, 1);
Vojtech Vitek (V-Teq) c8ffd86
     else {
Vojtech Vitek (V-Teq) c6c5f0d
 	if (*vp)
Vojtech Vitek (V-Teq) c6c5f0d
@@ -1182,7 +1174,7 @@ dohist(Char **vp, struct command *c)
Vojtech Vitek (V-Teq) c6c5f0d
 	else {
Vojtech Vitek (V-Teq) c6c5f0d
 	    n = getn(varval(STRhistory));
Vojtech Vitek (V-Teq) c6c5f0d
 	}
Vojtech Vitek (V-Teq) c6c5f0d
-	dophist(n, hflg);
Vojtech Vitek (V-Teq) c6c5f0d
+	dophist(n, flg);
Vojtech Vitek (V-Teq) c6c5f0d
     }
Vojtech Vitek (V-Teq) c6c5f0d
 }
Vojtech Vitek (V-Teq) c6c5f0d
 
Vojtech Vitek (V-Teq) c6c5f0d
@@ -1224,8 +1216,8 @@ fmthist(int fmt, ptr_t ptr)
Vojtech Vitek (V-Teq) c8ffd86
 void
Vojtech Vitek (V-Teq) c8ffd86
 rechist(Char *fname, int ref)
Vojtech Vitek (V-Teq) c8ffd86
 {
Vojtech Vitek (V-Teq) c8ffd86
-    Char    *snum;
Vojtech Vitek (V-Teq) c8ffd86
-    int     fp, ftmp, oldidfds;
Vojtech Vitek (V-Teq) c8ffd86
+    Char   *snum;
Vojtech Vitek (V-Teq) c8ffd86
+    int    fd = -1, ftmp, oldidfds;
Vojtech Vitek (V-Teq) c8ffd86
     struct varent *shist;
Vojtech Vitek (V-Teq) c8ffd86
     static Char   *dumphist[] = {STRhistory, STRmhT, 0, 0};
Vojtech Vitek (V-Teq) c8ffd86
 
Vojtech Vitek (V-Teq) c6c5f0d
@@ -1255,15 +1247,12 @@ rechist(Char *fname, int ref)
Vojtech Vitek (V-Teq) c8ffd86
      * with numerous shells being in simultaneous use. Imagine
Vojtech Vitek (V-Teq) c8ffd86
      * any kind of window system. All these shells 'share' the same 
Vojtech Vitek (V-Teq) c8ffd86
      * ~/.history file for recording their command line history. 
Vojtech Vitek (V-Teq) c8ffd86
-     * Currently the automatic merge can only succeed when the shells
Vojtech Vitek (V-Teq) c8ffd86
-     * nicely quit one after another. 
Vojtech Vitek (V-Teq) c8ffd86
-     *
Vojtech Vitek (V-Teq) c8ffd86
-     * Users that like to nuke their environment require here an atomic
Vojtech Vitek (V-Teq) c8ffd86
-     * 	loadhist-creat-dohist(dumphist)-close
Vojtech Vitek (V-Teq) c8ffd86
-     * sequence.
Vojtech Vitek (V-Teq) 66fbce9
      *
Vojtech Vitek (V-Teq) c8ffd86
-     * jw.
Vojtech Vitek (V-Teq) c8ffd86
-     */ 
Vojtech Vitek (V-Teq) c8ffd86
+     * Atomic merge loadhist-creat/ftrunc-dohist(dumphist)-close
Vojtech Vitek (V-Teq) c8ffd86
+     * implemented using fcntl (shared readers, exclusive writer)
Vojtech Vitek (V-Teq) c8ffd86
+     * by Vojtech Vitek (V-Teq) <vvitek@redhat.com>.
Vojtech Vitek (V-Teq) c8ffd86
+     */
Vojtech Vitek (V-Teq) c8ffd86
+
Vojtech Vitek (V-Teq) c8ffd86
     /*
Vojtech Vitek (V-Teq) c8ffd86
      * We need the didfds stuff before loadhist otherwise
Vojtech Vitek (V-Teq) c8ffd86
      * exec in a script will fail to print if merge is set.
Vojtech Vitek (V-Teq) c6c5f0d
@@ -1271,32 +1260,42 @@ rechist(Char *fname, int ref)
Vojtech Vitek (V-Teq) c8ffd86
      */
Vojtech Vitek (V-Teq) c8ffd86
     oldidfds = didfds;
Vojtech Vitek (V-Teq) c8ffd86
     didfds = 0;
Vojtech Vitek (V-Teq) c8ffd86
-    if ((shist = adrof(STRsavehist)) != NULL && shist->vec != NULL)
Vojtech Vitek (V-Teq) 66fbce9
-	if (shist->vec[1] && eq(shist->vec[1], STRmerge))
Vojtech Vitek (V-Teq) c8ffd86
-	    loadhist(fname, 1);
Vojtech Vitek (V-Teq) 66fbce9
-
Vojtech Vitek (V-Teq) 66fbce9
-    fp = xcreat(short2str(fname), 0600);
Vojtech Vitek (V-Teq) 66fbce9
-    cleanup_until(fname);
Vojtech Vitek (V-Teq) 66fbce9
-    if (fp == -1) {
Vojtech Vitek (V-Teq) 66fbce9
-	didfds = oldidfds;
Vojtech Vitek (V-Teq) 66fbce9
-	return;
Vojtech Vitek (V-Teq) c6c5f0d
+    if (((shist = adrof(STRsavehist)) != NULL && shist->vec != NULL) &&
Vojtech Vitek (V-Teq) c6c5f0d
+        (shist->vec[1] && eq(shist->vec[1], STRmerge))) {
Vojtech Vitek (V-Teq) c8ffd86
+	/* Read .history file, leave it's fd open for writing. */
Vojtech Vitek (V-Teq) c6c5f0d
+	fd = loadhist(fname, HIST_MERGE|HIST_FILE_WRLCK|HIST_FILE_OPEN|HIST_FILE_LOCK);
Vojtech Vitek (V-Teq) c6c5f0d
+	if (fd > 0) {
Vojtech Vitek (V-Teq) c8ffd86
+	    /* Truncate the .history file. */
Vojtech Vitek (V-Teq) c8ffd86
+	    (void) ftruncate(fd, 0);
Roman Kollar 5b57aa6
+	    (void) lseek(fd, (off_t) 0, SEEK_SET);
Vojtech Vitek (V-Teq) 66fbce9
+	}
Vojtech Vitek (V-Teq) c6c5f0d
+    }
Vojtech Vitek (V-Teq) c6c5f0d
+    if (fd <= 0) {
Vojtech Vitek (V-Teq) c6c5f0d
+        /* Open .history file for writing (if not open yet). */
Vojtech Vitek (V-Teq) c8ffd86
+	fd = xopen(short2str(fname), O_LARGEFILE|O_CREAT|O_WRONLY|O_TRUNC, 0600);
Vojtech Vitek (V-Teq) c8ffd86
+	if (fd != -1)
Vojtech Vitek (V-Teq) c8ffd86
+	    cleanup_push(&fd, open_cleanup);
Vojtech Vitek (V-Teq) c8ffd86
+    }
Vojtech Vitek (V-Teq) c8ffd86
+    if (fd != -1) {
Vojtech Vitek (V-Teq) c8ffd86
+	ftmp = SHOUT;
Vojtech Vitek (V-Teq) c8ffd86
+	SHOUT = fd;
Vojtech Vitek (V-Teq) c8ffd86
+	dumphist[2] = snum;
Vojtech Vitek (V-Teq) c8ffd86
+	/* Write history to the .history file. */
Vojtech Vitek (V-Teq) c8ffd86
+	dohist(dumphist, NULL);
Vojtech Vitek (V-Teq) c8ffd86
+	SHOUT = ftmp;
Vojtech Vitek (V-Teq) c6c5f0d
     }
Vojtech Vitek (V-Teq) c6c5f0d
-    ftmp = SHOUT;
Vojtech Vitek (V-Teq) c6c5f0d
-    SHOUT = fp;
Vojtech Vitek (V-Teq) c6c5f0d
-    dumphist[2] = snum;
Vojtech Vitek (V-Teq) c6c5f0d
-    dohist(dumphist, NULL);
Vojtech Vitek (V-Teq) c6c5f0d
-    xclose(fp);
Vojtech Vitek (V-Teq) c6c5f0d
-    SHOUT = ftmp;
Vojtech Vitek (V-Teq) c8ffd86
     didfds = oldidfds;
Vojtech Vitek (V-Teq) c6c5f0d
+    cleanup_until(fname);
Vojtech Vitek (V-Teq) c8ffd86
 }
Vojtech Vitek (V-Teq) c8ffd86
 
Vojtech Vitek (V-Teq) c6c5f0d
 
Vojtech Vitek (V-Teq) c6c5f0d
 /* This is the entry point for loading history data from a file. */
Vojtech Vitek (V-Teq) c6c5f0d
-void
Vojtech Vitek (V-Teq) c6c5f0d
-loadhist(Char *fname, int mflg)
Vojtech Vitek (V-Teq) c6c5f0d
+int
Vojtech Vitek (V-Teq) c6c5f0d
+loadhist(Char *fname, int flg)
Vojtech Vitek (V-Teq) c6c5f0d
 {
Vojtech Vitek (V-Teq) c6c5f0d
     static Char   *loadhist_cmd[] = {STRsource, NULL, NULL, NULL};
Vojtech Vitek (V-Teq) c6c5f0d
-    loadhist_cmd[1] = mflg ? STRmm : STRmh;
Vojtech Vitek (V-Teq) c6c5f0d
+    int fd;
Vojtech Vitek (V-Teq) c6c5f0d
+    loadhist_cmd[1] = (flg & HIST_MERGE) ? STRmm : STRmh;
Vojtech Vitek (V-Teq) c6c5f0d
 
Vojtech Vitek (V-Teq) c6c5f0d
     if (fname != NULL)
Vojtech Vitek (V-Teq) c6c5f0d
 	loadhist_cmd[2] = fname;
Vojtech Vitek (V-Teq) c6c5f0d
@@ -1305,15 +1304,17 @@ loadhist(Char *fname, int mflg)
Vojtech Vitek (V-Teq) c6c5f0d
     else
Vojtech Vitek (V-Teq) c6c5f0d
 	loadhist_cmd[2] = STRtildothist;
Vojtech Vitek (V-Teq) c6c5f0d
 
Vojtech Vitek (V-Teq) c6c5f0d
-    dosource(loadhist_cmd, NULL);
Roman Kollar 2acb8bf
+    fd = dosource_flg(loadhist_cmd, NULL, flg);
Vojtech Vitek (V-Teq) c6c5f0d
 
Vojtech Vitek (V-Teq) c6c5f0d
-    /* During history merging (enthist sees mflg set), we disable management of
Vojtech Vitek (V-Teq) c6c5f0d
-     * Hnum and Href (because fastMergeErase is true).  So now reset all the
Vojtech Vitek (V-Teq) c6c5f0d
+    /* During history merging (enthist sees merge flag), we disable management
Vojtech Vitek (V-Teq) c6c5f0d
+     * of Hnum and Href (because fastMergeErase is true).  So now reset all the
Vojtech Vitek (V-Teq) c6c5f0d
      * values based on the final ordering of the history list. */
Vojtech Vitek (V-Teq) c6c5f0d
-    if (mflg) {
Vojtech Vitek (V-Teq) c6c5f0d
+    if (flg & HIST_MERGE) {
Vojtech Vitek (V-Teq) c6c5f0d
 	int n = eventno;
Vojtech Vitek (V-Teq) c6c5f0d
         struct Hist *hp = &Histlist;
Vojtech Vitek (V-Teq) c6c5f0d
         while ((hp = hp->Hnext))
Vojtech Vitek (V-Teq) c6c5f0d
 	    hp->Hnum = hp->Href = n--;
Vojtech Vitek (V-Teq) c6c5f0d
     }
Vojtech Vitek (V-Teq) c6c5f0d
+
Vojtech Vitek (V-Teq) c6c5f0d
+    return fd; /* Valid/invalid file descriptor (>FSAVE, -1). Zero on error. */
Vojtech Vitek (V-Teq) c6c5f0d
 }
bed5d53
diff -upr tcsh-6.18.00_orig/sh.lex.c tcsh-6.18.00_work/sh.lex.c
bed5d53
--- tcsh-6.18.00_orig/sh.lex.c	2013-03-28 10:06:17.971859478 +0100
bed5d53
+++ tcsh-6.18.00_work/sh.lex.c	2013-03-28 10:06:42.820948316 +0100
bed5d53
@@ -1595,7 +1595,7 @@ wide_read(int fildes, Char *buf, size_t
Vojtech Vitek (V-Teq) c8ffd86
     /* Throwing away possible partial multibyte characters on error if the
Vojtech Vitek (V-Teq) c8ffd86
        stream is not seekable */
Vojtech Vitek (V-Teq) c8ffd86
     err = errno;
Vojtech Vitek (V-Teq) c8ffd86
-    lseek(fildes, -(off_t)partial, L_INCR);
Roman Kollar 5b57aa6
+    lseek(fildes, -(off_t)partial, SEEK_CUR);
Vojtech Vitek (V-Teq) c8ffd86
     errno = err;
Vojtech Vitek (V-Teq) c8ffd86
     return res != 0 ? res : r;
Vojtech Vitek (V-Teq) c8ffd86
 }
Vojtech Vitek (V-Teq) 66fbce9
@@ -1610,7 +1610,7 @@ bgetc(void)
Vojtech Vitek (V-Teq) c8ffd86
     if (cantell) {
Vojtech Vitek (V-Teq) c8ffd86
 	if (fseekp < fbobp || fseekp > feobp) {
Vojtech Vitek (V-Teq) c8ffd86
 	    fbobp = feobp = fseekp;
Vojtech Vitek (V-Teq) c8ffd86
-	    (void) lseek(SHIN, fseekp, L_SET);
Vojtech Vitek (V-Teq) c8ffd86
+	    (void) lseek(SHIN, fseekp, SEEK_SET);
Vojtech Vitek (V-Teq) c8ffd86
 	}
Vojtech Vitek (V-Teq) c8ffd86
 	if (fseekp == feobp) {
Vojtech Vitek (V-Teq) c8ffd86
 #ifdef WIDE_STRINGS
Vojtech Vitek (V-Teq) 66fbce9
@@ -1814,7 +1814,7 @@ btell(struct Ain *l)
Vojtech Vitek (V-Teq) c8ffd86
 void
Vojtech Vitek (V-Teq) c8ffd86
 btoeof(void)
Vojtech Vitek (V-Teq) c8ffd86
 {
Vojtech Vitek (V-Teq) c8ffd86
-    (void) lseek(SHIN, (off_t) 0, L_XTND);
Roman Kollar 5b57aa6
+    (void) lseek(SHIN, (off_t) 0, SEEK_END);
Vojtech Vitek (V-Teq) c8ffd86
     aret = TCSH_F_SEEK;
Vojtech Vitek (V-Teq) c8ffd86
     fseekp = feobp;
Vojtech Vitek (V-Teq) c8ffd86
     alvec = NULL;
Vojtech Vitek (V-Teq) 66fbce9
@@ -1832,7 +1832,7 @@ settell(void)
Vojtech Vitek (V-Teq) c8ffd86
     cantell = 0;
Vojtech Vitek (V-Teq) c8ffd86
     if (arginp || onelflg || intty)
Vojtech Vitek (V-Teq) c8ffd86
 	return;
Vojtech Vitek (V-Teq) c8ffd86
-    if ((x = lseek(SHIN, (off_t) 0, L_INCR)) == -1)
Roman Kollar 5b57aa6
+    if ((x = lseek(SHIN, (off_t) 0, SEEK_CUR)) == -1)
Vojtech Vitek (V-Teq) c8ffd86
 	return;
Vojtech Vitek (V-Teq) c8ffd86
     fbuf = xcalloc(2, sizeof(Char **));
Vojtech Vitek (V-Teq) c8ffd86
     fblocks = 1;
bed5d53
diff -upr tcsh-6.18.00_orig/sh.sem.c tcsh-6.18.00_work/sh.sem.c
bed5d53
--- tcsh-6.18.00_orig/sh.sem.c	2013-03-28 10:06:17.970859477 +0100
bed5d53
+++ tcsh-6.18.00_work/sh.sem.c	2013-03-28 10:06:42.819948308 +0100
bed5d53
@@ -892,7 +892,7 @@ doio(struct command *t, int *pipein, int
Vojtech Vitek (V-Teq) c8ffd86
 	    fd = xopen(tmp, O_WRONLY|O_APPEND|O_LARGEFILE);
Vojtech Vitek (V-Teq) c8ffd86
 #else /* !O_APPEND */
Vojtech Vitek (V-Teq) c8ffd86
 	    fd = xopen(tmp, O_WRONLY|O_LARGEFILE);
Vojtech Vitek (V-Teq) c8ffd86
-	    (void) lseek(fd, (off_t) 0, L_XTND);
Roman Kollar 5b57aa6
+	    (void) lseek(fd, (off_t) 0, SEEK_END);
Vojtech Vitek (V-Teq) c8ffd86
 #endif /* O_APPEND */
Vojtech Vitek (V-Teq) c8ffd86
 	}
Vojtech Vitek (V-Teq) c8ffd86
 	else