From 697d170928a0b0abec0b7a9650bf9a2068b9060f Mon Sep 17 00:00:00 2001 From: Wayne Davison Date: Thu, 6 Mar 2008 17:23:00 +0000 Subject: History file-handling improvments. --- ChangeLog | 11 +++++++++++ Src/hist.c | 30 ++++++++++++++++++++++-------- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 32cee6ae4..8d9b4f681 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2008-03-06 Wayne Davison + + * 24693: Src/utils.c: provide better errors when skipping + history-file saving due to ownership. Allow root to do the + save anyway if zsh can chown a file descriptor. Fixed the + propagation of the errno from a failed open() of the history + file (zsh used to complain about an invalid file descriptor). + + * unposted: Src/Zle/zle_utils.c: fixed 2 compiler warnings + about comparing signed and unsigned. + 2008-03-04 Peter Stephenson * unposted: Completion/Unix/Command/_perforce: ignore range diff --git a/Src/hist.c b/Src/hist.c index 05fc6e003..1e4e6f3ba 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -2192,13 +2192,13 @@ savehistfile(char *fn, int err, int writeflags) } errno = 0; if (writeflags & HFILE_APPEND) { + int fd = open(unmeta(fn), O_CREAT | O_WRONLY | O_APPEND | O_NOCTTY, 0600); tmpfile = NULL; - out = fdopen(open(unmeta(fn), - O_CREAT | O_WRONLY | O_APPEND | O_NOCTTY, 0600), "a"); + out = fd >= 0 ? fdopen(fd, "a") : NULL; } else if (!isset(HISTSAVEBYCOPY)) { + int fd = open(unmeta(fn), O_CREAT | O_WRONLY | O_TRUNC | O_NOCTTY, 0600); tmpfile = NULL; - out = fdopen(open(unmeta(fn), - O_CREAT | O_WRONLY | O_TRUNC | O_NOCTTY, 0600), "w"); + out = fd >= 0 ? fdopen(fd, "w") : NULL; } else { tmpfile = bicat(unmeta(fn), ".new"); if (unlink(tmpfile) < 0 && errno != ENOENT) @@ -2206,13 +2206,27 @@ savehistfile(char *fn, int err, int writeflags) else { struct stat sb; int old_exists = stat(unmeta(fn), &sb) == 0; + uid_t euid = geteuid(); - if (old_exists && sb.st_uid != geteuid()) { + if (old_exists +#if defined HAVE_FCHMOD && defined HAVE_FCHOWN + && euid +#endif + && sb.st_uid != euid) { free(tmpfile); - tmpfile = NULL; /* Avoid an error about HISTFILE.new */ + if (err) { + if (isset(APPENDHISTORY) || isset(INCAPPENDHISTORY) + || isset(SHAREHISTORY)) + zerr("rewriting %s would change its ownership -- skipped", fn); + else + zerr("rewriting %s would change its ownership -- history not saved", fn); + err = 0; /* Don't report a generic error below. */ + } out = NULL; - } else - out = fdopen(open(tmpfile, O_CREAT | O_WRONLY | O_EXCL, 0600), "w"); + } else { + int fd = open(tmpfile, O_CREAT | O_WRONLY | O_EXCL, 0600); + out = fd >= 0 ? fdopen(fd, "w") : NULL; + } #ifdef HAVE_FCHMOD if (old_exists && out) { -- cgit 1.4.1