about summary refs log tree commit diff
diff options
context:
space:
mode:
authorWayne Davison <wayned@users.sourceforge.net>2008-03-06 17:23:00 +0000
committerWayne Davison <wayned@users.sourceforge.net>2008-03-06 17:23:00 +0000
commit697d170928a0b0abec0b7a9650bf9a2068b9060f (patch)
treeb9e1b8173436f5d41be212342888f7770d872ff7
parent9fb0f8dea203e2f3dd2ea715924c6ac08519e523 (diff)
downloadzsh-697d170928a0b0abec0b7a9650bf9a2068b9060f.tar.gz
zsh-697d170928a0b0abec0b7a9650bf9a2068b9060f.tar.xz
zsh-697d170928a0b0abec0b7a9650bf9a2068b9060f.zip
History file-handling improvments.
-rw-r--r--ChangeLog11
-rw-r--r--Src/hist.c30
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  <wayned@users.sourceforge.net>
+
+	* 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  <pws@csr.com>
 
 	* 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) {