diff --git a/tcsh-6.19.00-history-file-locking-order.patch b/tcsh-6.19.00-history-file-locking-order.patch new file mode 100644 index 0000000..02a9934 --- /dev/null +++ b/tcsh-6.19.00-history-file-locking-order.patch @@ -0,0 +1,85 @@ +--- + sh.c | 57 +++++++++++++++++++++++++++++++++------------------------ + 1 file changed, 33 insertions(+), 24 deletions(-) + +--- sh.c ++++ sh.c 2016-08-12 14:40:36.582709621 +0000 +@@ -1537,18 +1537,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; +@@ -1558,26 +1558,35 @@ srcfile(const char *f, int onlyown, int + fl.l_start = 0; + fl.l_len = 0; + +- cleanup_push(unit, fcntl_cleanup); +- if (fcntl(*unit, F_SETLKW, &fl) == -1) +- cleanup_ignore(unit); +- } ++ hd = xmalloc(sizeof(*hd)); ++ cleanup_push(hd, xfree); + +- srcunit(*unit, onlyown, flg, av); ++ *hd = fcntl(unit, F_DUPFD_CLOEXEC, FSAFE+1); ++ cleanup_push(hd, open_cleanup); + +- /* Unlock the unit, if we don't want to leave it locked (or open). */ +- if ((flg & (HIST_FILE_WRLCK | HIST_FILE_RDLCK)) && +- (!(flg & HIST_FILE_LOCK) || !(flg & HIST_FILE_OPEN))) +- cleanup_until(unit); /* fcntl_cleanup */ +- +- /* Close the unit, if we don't want to leave it open. */ +- if (!(flg & HIST_FILE_OPEN)) { +- cleanup_until(unit); /* open_cleanup */ +- cleanup_until(unit); /* xfree */ +- return -1; /* Not error but invalid file descriptor. */ ++ fcntl(*hd, F_SETLKW, &fl); ++ cleanup_push(hd, fcntl_cleanup); + } + +- return *unit; /* File descriptor (fd > FSAFE). */ ++ cleanup_push(&unit, open_cleanup); ++ /* ++ * This one *does* do a cleanup_until() hence a open_cleanup() ++ * therefore use a duplicated fd to lock/unlock the history file ++ */ ++ srcunit(unit, onlyown, flg, av); ++ cleanup_until(&unit); /* Close the official unit. */ ++ ++ if (!hd) ++ return -1; /* Not error but invalid file descriptor. */ ++ ++ if ((flg & HIST_FILE_OPEN) && (flg & HIST_FILE_LOCK)) ++ return -1; ++ ++ cleanup_until(hd); /* fcntl_cleanup */ ++ cleanup_until(hd); /* open_cleanup */ ++ cleanup_until(hd); /* xfree */ ++ ++ return unit; /* File descriptor (fd > FSAFE). */ + } + + diff --git a/tcsh.changes b/tcsh.changes index cc130c9..894c2d6 100644 --- a/tcsh.changes +++ b/tcsh.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Fri Aug 12 14:52:34 UTC 2016 - werner@suse.de + +- Make a copy of the file descriptor of the history file to be + able not only to lock but also unlock this file (bsc#992577) + ------------------------------------------------------------------- Mon Apr 4 09:00:35 UTC 2016 - schwab@suse.de diff --git a/tcsh.spec b/tcsh.spec index 971a6cf..5dd7785 100644 --- a/tcsh.spec +++ b/tcsh.spec @@ -35,7 +35,9 @@ Patch6: tcsh-6.18.03-catalogs.dif # PATCH-FIX-SUSE add history file locking (bsc#901076) Patch9: tcsh-6.18.03-history-file-locking.patch Patch10: tcsh-6.18.03-history-merge.dif -Patch11: union-wait.patch +# PATCH-FIX-SUSE fix history file locking: first unlock then close +Patch11: tcsh-6.19.00-history-file-locking-order.patch +Patch12: union-wait.patch BuildRequires: autoconf BuildRequires: ncurses-devel BuildRequires: screen @@ -62,8 +64,9 @@ correction, a history mechanism, job control, and a C-like syntax. %patch6 -b .catalogs %patch9 -b .histlock %patch10 -b .histmerg +%patch11 -b .histlckord +%patch12 -p1 %patch0 -b .0 -%patch11 -p1 %build