From owner-freebsd-hackers@FreeBSD.ORG Tue Mar 2 01:07:01 2004 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id BA63016A4CE for ; Tue, 2 Mar 2004 01:07:01 -0800 (PST) Received: from jkh-gw.brierdr.com (adsl-64-173-3-158.dsl.sntc01.pacbell.net [64.173.3.158]) by mx1.FreeBSD.org (Postfix) with ESMTP id 4A60643D1F for ; Tue, 2 Mar 2004 01:07:01 -0800 (PST) (envelope-from jkh@queasyweasel.com) Received: from [64.173.15.98] (IDENT:470-ident-is-a-completely-pointless-protocol-that-offers-no-security-or-traceability-at-all-so-take@adsl-64-173-15-98.dsl.sntc01.pacbell.net [64.173.15.98]) by jkh-gw.brierdr.com (8.12.10/8.12.10) with ESMTP id i2296OrF015719 for ; Tue, 2 Mar 2004 01:06:24 -0800 (PST) (envelope-from jkh@queasyweasel.com) Mime-Version: 1.0 (Apple Message framework v612) To: FreeBSD Hackers Message-Id: Content-Type: multipart/signed; micalg=sha1; boundary=Apple-Mail-2--1020512019; protocol="application/pkcs7-signature" From: "Jordan K. Hubbard" Date: Tue, 2 Mar 2004 01:06:59 -0800 X-Mailer: Apple Mail (2.612) X-Mailman-Approved-At: Tue, 02 Mar 2004 05:16:55 -0800 X-Content-Filtered-By: Mailman/MimeDel 2.1.1 Subject: Another conformance question... This time fputs(). X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 02 Mar 2004 09:07:01 -0000 --Apple-Mail-2--1020512019 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=US-ASCII; format=flowed I submit for your consideration the following test program and the wonderful variety of test results it produces: #include #include int main(int argc, char *argv[]) { int rc; FILE *fp=fopen("/dev/zero", "r"); rc = fputs("Hello world\n", fp); printf("errno = %d, rc = %d\n", errno, rc); errno = 0; rc = fwrite("Hello world again\n", 1, 18, fp); printf("fwrite errno = %d, rc = %d\n", errno, rc); fclose(fp); } On Red Hat Linux 9.0, it outputs the following: errno = 9, rc = -1 fwrite errno = 9, rc = 0 Just to save you the grepping, errno #9 is EBADF, "bad file number". Now we KNOW that the mode on that fopen is (a) on a device which doesn't allow writing and (b) of the wrong open mode ("r" rather than "w"), but this discussion concerns "the right thing to do" when faced with just these sorts of bogus situations and one could probably argue that Linux returns the wrong errno here, but it does set errno. What does FreeBSD do? It does this: errno = 0, rc = -1 fwrite errno = 0, rc = 0 Given that it's just not kosher to write on a read-only fp and get no error back at all, I would argue (though not passionately) for the following diff to libc: --- stdio/fvwrite.c 22 Mar 2002 21:53:04 -0000 1.15 +++ stdio/fvwrite.c 2 Mar 2004 08:40:25 -0000 @@ -43,6 +43,7 @@ #include #include #include +#include #include "local.h" #include "fvwrite.h" @@ -67,8 +68,10 @@ if ((len = uio->uio_resid) == 0) return (0); /* make sure we can write */ - if (cantwrite(fp)) + if (cantwrite(fp)) { + errno = EACCES; return (EOF); + } #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define COPY(n) (void)memcpy((void *)fp->_p, (void *)p, (size_t)(n)) That gives us this behavior for our little test program: errno = 13, rc = -1 fwrite errno = 13, rc = 0 In both cases, we get EACCES for fputs() or fwrite() attempts on a read-only file pointer pointing to a read-only device, something we'd expect to get "permission denied" for I think. In the case where we open the fp for write access, the FreeBSD behavior is unchanged: errno = 19, rc = 0 fwrite errno = 0, rc = 18 Which gives us ENODEV for the fputs(3) and no error for the fwrite(3). I'm not sure why an error is returned at all in the fputs(3) case since it seems perfectly valid to write onto /dev/null and simply have the data be discarded, but that error is coming back from somewhere deeper of the bowels of stdio and has nothing to do with my proposed diff in any case. Red Hat Linux, interestingly enough, returns errno 25 in this case (ENOTTY)! This is your libc. This is your libc on SUSv2*. Any questions? * References: http://www.opengroup.org/onlinepubs/007908799/xsh/fwrite.html http://www.opengroup.org/onlinepubs/007908799/xsh/fputs.html -- Jordan K. Hubbard Engineering Manager, BSD technology group Apple Computer --Apple-Mail-2--1020512019--