From owner-freebsd-hackers Sat Oct 31 01:27:13 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id BAA02155 for freebsd-hackers-outgoing; Sat, 31 Oct 1998 01:27:13 -0800 (PST) (envelope-from owner-freebsd-hackers@FreeBSD.ORG) Received: from verdi.nethelp.no (verdi.nethelp.no [158.36.41.162]) by hub.freebsd.org (8.8.8/8.8.8) with SMTP id BAA02149 for ; Sat, 31 Oct 1998 01:27:10 -0800 (PST) (envelope-from sthaug@nethelp.no) From: sthaug@nethelp.no Received: (qmail 17884 invoked by uid 1001); 31 Oct 1998 09:27:06 +0000 (GMT) To: Arjan.deVet@adv.iae.nl Cc: hackers@FreeBSD.ORG Subject: Re: Possible bug in freopen()? In-Reply-To: Your message of "Fri, 30 Oct 1998 22:39:02 +0100 (CET)" References: <199810302139.WAA13889@adv.iae.nl> X-Mailer: Mew version 1.05+ on Emacs 19.34.2 Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Date: Sat, 31 Oct 1998 10:27:06 +0100 Message-ID: <17882.909826026@verdi.nethelp.no> Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG > I may have found a bug in freopen() while testing INN 2.2-stable. > > Consider the following program: > > #include > #include > > main () { > FILE *f, *g; > long i; > > g = fopen("/tmp/test", "a"); > f = freopen("/tmp/test", "a", g); > i = ftell(f); > printf("%d\n", i); > fprintf(f, "test"); > i = ftell(f); > printf("%d\n", i); > close(f); > } Your program needs to fclose() the FILE :-) Aside from that, I believe you definitely have a point. The FreeBSD freopen() behavior may actually be correct according to the standards. My copy of POSIX 1003.1 (First edition, 1990-12-07) says the following about ftell(): 8.2.3.10 ftell() The underlying function is lseek(). ... If the stream is opened in append mode or if the O_APPEND flag is set as a consequence of dealing with other handles on the file, the result of ftell() on that stream is unspecified. So freopen() behaving differently than fopen() may be allowed by the standards - but it certainly violates POLA, and probably also the FreeBSD manual page, which says: The freopen() function opens the file whose name is the string pointed to by path and associates the stream pointed to by stream with it. The original stream (if it exists) is closed. The mode argument is used just as in the fopen() function. Since it says "just as in the fopen() function", I would expect the effect on file position to be the same also. Here is a proposed patch - it simply consists of the relevant part of the fopen() function, inserted at the appropriate place in freopen(). Steinar Haug, Nethelp consulting, sthaug@nethelp.no ---------------------------------------------------------------------- *** lib/libc/stdio/freopen.c.orig Tue May 30 07:41:43 1995 --- lib/libc/stdio/freopen.c Sat Oct 31 10:06:08 1998 *************** *** 151,155 **** --- 151,166 ---- fp->_write = __swrite; fp->_seek = __sseek; fp->_close = __sclose; + + /* + * When opening in append mode, even though we use O_APPEND, + * we need to seek to the end so that ftell() gets the right + * answer. If the user then alters the seek pointer, or + * the file extends, this will fail, but there is not much + * we can do about this. (We could set __SAPP and check in + * fseek and ftell.) + */ + if (oflags & O_APPEND) + (void) __sseek((void *)fp, (fpos_t)0, SEEK_END); return (fp); } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message