From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13991 invoked from network); 6 Mar 2008 17:02:24 -0000 X-Spam-Checker-Version: SpamAssassin 3.2.4 (2008-01-01) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00 autolearn=ham version=3.2.4 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 6 Mar 2008 17:02:24 -0000 Received-SPF: none (ns1.primenet.com.au: domain at sunsite.dk does not designate permitted sender hosts) Received: (qmail 42790 invoked from network); 6 Mar 2008 17:02:19 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 6 Mar 2008 17:02:19 -0000 Received: (qmail 10025 invoked by alias); 6 Mar 2008 17:02:15 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 24693 Received: (qmail 10011 invoked from network); 6 Mar 2008 17:02:14 -0000 Received: from bifrost.dotsrc.org (130.225.254.106) by sunsite.dk with SMTP; 6 Mar 2008 17:02:14 -0000 Received: from smarty.dreamhost.com (smarty.dreamhost.com [208.113.175.8]) by bifrost.dotsrc.org (Postfix) with ESMTP id 0F61D8029404 for ; Thu, 6 Mar 2008 18:02:06 +0100 (CET) Received: from herod.dreamhost.com (herod.dreamhost.com [208.113.239.72]) by smarty.dreamhost.com (Postfix) with ESMTP id 03FE5EE2CF; Thu, 6 Mar 2008 09:02:02 -0800 (PST) Received: by herod.dreamhost.com (Postfix, from userid 130321) id 335196049A; Thu, 6 Mar 2008 09:02:01 -0800 (PST) Date: Thu, 6 Mar 2008 09:02:00 -0800 From: Wayne Davison To: Peter Stephenson Cc: zsh-workers@sunsite.dk, Sven Joachim , 369305@bugs.debian.org Subject: Re: Bug#369305: zsh: failed to write history file /home/sven/.zsh-history: no such file or directory Message-ID: <20080306170200.GA13750@herod.dreamhost.com> References: <87ir01bb68.fsf@gmx.de> <20080305144438.GA9541@scowler.net> <200803051712.m25HCNk6006441@news01.csr.com> <20080305202936.GA24616@scowler.net> <20080305224158.GB9620@herod.dreamhost.com> <20080306101937.6e4bd8a7@news01> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="VS++wcV0S1rZb1Fb" Content-Disposition: inline In-Reply-To: <20080306101937.6e4bd8a7@news01> User-Agent: Mutt/1.5.9i X-Virus-Scanned: ClamAV 0.91.2/6153/Thu Mar 6 14:59:13 2008 on bifrost X-Virus-Status: Clean --VS++wcV0S1rZb1Fb Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Thu, Mar 06, 2008 at 10:19:37AM +0000, Peter Stephenson wrote: > If we decide a warning message is still appropriate, given that we've > detected exactly what's going on it should probably be more specific > than just a vague "failed to write history". Yes, we should definitely be giving the user better information. I've fixed several things: 1. Tell the user when we're refusing to write out the history file so that the ownership won't change. Try to differentiate if we're just skipping the rewrite or if no new history data was written. 2. Allow root to write out the file even if it doesn't own it, as long as zsh knows how to chown a file handle. 3. Avoid the generic failure message that confuses the issue (by setting "err = 0"). 4. (bonus) Output the right error if we can't open the file for writing, not an error about the file-handle being invalid. (This was due to the use of fdopen(open(...), ...), which loses the errno from open().) ..wayne.. --VS++wcV0S1rZb1Fb Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="hist-fixes.patch" --- Src/hist.c 31 Dec 2007 23:14:17 -0000 1.70 +++ Src/hist.c 6 Mar 2008 16:43:05 -0000 @@ -2192,13 +2192,13 @@ savehistfile(char *fn, int err, int writ } 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 writ 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("writing %s would change its ownership -- skipped size trimming", fn); + else + zerr("writing %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) { --VS++wcV0S1rZb1Fb--