Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Date: Tue, 4 Jun 2002 16:26:28 +0200 From: John Marshall To: Ton van Overbeek Cc: cygwin AT cygwin DOT com Subject: Re: text/binary problem since 20020530 snapshot Message-ID: <20020604142628.GA5056@kahikatea.falch.net> References: <3CFB9C34 DOT 702055D5 AT cistron DOT nl> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="TB36FDmn/VVEgNH/" Content-Disposition: inline In-Reply-To: <3CFB9C34.702055D5@cistron.nl> User-Agent: Mutt/1.3.27i Organization: Falch.net --TB36FDmn/VVEgNH/ Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Mon, Jun 03, 2002 at 06:41:24PM +0200, Ton van Overbeek wrote: > Since the 20020530 snapshot the default mode for open is binary. > From http://www.cygwin.com/snapshots/winsup-changelog-20020529-20020530 : >> 2002-05-29 Christopher Faylor >> >> * fhandler.cc (binmode): Default to binmode when mode is not known. [...] > Questions: > - With the behaviour since 20020503, does it make any difference at all > if a filesystem is text or binary mounted for reading/writing when > no mode is specified in the open() call ? I've always found these binmode/textmode mounts v. LF/CR-LF files issues confusing, so I did some tests to try to see what was going on. Trying to read a six byte file containing "a\r\nb\r\n" (test program attached below), I got the following with cygwin1.dll 1.3.10 (and an empty $CYGWIN): binary mount text mount fopen "rb" 61 0d 0a 62 0d 0a 61 0d 0a 62 0d 0a fopen "r" 61 0d 0a 62 0d 0a 61 0a 62 0a open O_RDONLY 61 0d 0a 62 0d 0a 61 0a 62 0a open O_RDONLY|O_TEXT 61 0a 62 0a 61 0a 62 0a open O_RDONLY|O_BINARY 61 0d 0a 62 0d 0a 61 0d 0a 62 0d 0a I also did this with the 20020530 and 20020603 cygwin1.dll snapshots: in these cases, the results, for files on both binary and text mounts, were as listed above for a binary mount. So in these snapshots, for *reading* the filesystem's text/binary mode isn't making any difference. Probably it still makes a difference on writing (at least for O_WRONLY|O_TEXT and "w") but I didn't test that. > - What is the intended behaviour of a text vs binary mounted filesystem > in the case of question 1 ? FWIW (very little) my naive expectation (based on ISO C's fopen() without "b" meaning text files, and on open() being a Unix function, hence using raw binary files by default) is binary mount text mount fopen "rb" 61 0d 0a 62 0d 0a 61 0d 0a 62 0d 0a fopen "r" (?1) 61 0a 62 0a open O_RDONLY 61 0d 0a 62 0d 0a 61 0d 0a 62 0d 0a open O_RDONLY|O_TEXT (?2) 61 0a 62 0a open O_RDONLY|O_BINARY 61 0d 0a 62 0d 0a 61 0d 0a 62 0d 0a Actually it's a hard question: for the (?) cases, I could make arguments either way. It depends on what a "text file" is: maybe it's CR-LF because Cygwin is trying to interoperate with Windows, or maybe it's LF because Cygwin is trying to be a POSIX environment. I kind of had the impression that choosing binmode/textmode when you mounted things was how you expressed your preference between the two goals, but even after rereading http://cygwin.com/cygwin-ug-net/using-textbinary.html several times, I'm still confused. Theoretically I think ?1 and ?2 should be the same (because they're both asking for the same thing, namely text files, either implicitly or explicitly). Pragmatically I can see why ?1 would want to be 61 0d 0a 62 0d 0a (compatibility with bad Unix code that thinks it doesn't need to use "b" in fopen() calls because there's no such thing as text files) and pragmatically I can see why ?2 would want to be 61 0a 62 0a (convenience for overachieving O_TEXT-using open() code). Ouch. (In the context of what brought this up in Ton's posting: for text mounts, two of those cases have changed between 1.3.10 and the current snapshots. If prc-tools was being broken by the fopen("r") change, I think I'd have grounds for complaint. But it appears that it's being broken by the open(O_RDONLY) change, which I agree with, so this particular problem in prc-tools is definitely my bug.) Clearly my expectation is different from Chris's, at least as expressed in the current snapshots. The case that differs is fopen("r") on a file located on a text mount. There's an argument that it should be 61 0d 0a 62 0d 0a for the sake of that bad Unix code. (And calling it "bad Unix code" is of course unfair -- really what it is is good POSIX code.) There's also an argument that it should be 61 0a 62 0a for the sake of programmers who read the ISO C standard and believe that fopen("r") does the right thing for a text file. Me, I would have thought that the fact that the file is on a text mount would mean the second argument trumps the first. Comments? Or am I just terminally confused? John --TB36FDmn/VVEgNH/ Content-Type: text/plain; charset=us-ascii Content-Disposition: inline; filename="textfile.c" #include #include #include #include #include void dump (const char *buf, int len) { int i; for (i = 0; i < len; i++) printf (" %02x", buf[i]); printf ("\n"); } void with_fopen (const char *fname, const char *mode) { FILE *f = fopen (fname, mode); if (f) { char buf[20]; int len = fread (buf, 1, sizeof buf, f); fclose (f); printf ("fopen (\"%s\")\t", mode); dump (buf, len); } else printf ("Can't fopen (\"%s\")\n", mode); } void with_open (const char *fname, int flags, const char *flags_text) { int fd = open (fname, flags); if (fd >= 0) { char buf[20]; int len = read (fd, buf, sizeof buf); close (fd); printf ("%s\t", flags_text); dump (buf, len); } else printf ("Can't open (%s)\n", flags_text); } int main (int argc, char **argv) { const char *fname = (argc > 1)? argv[1] : "textfile.foo"; FILE *f = fopen (fname, "wb"); if (f) { fwrite ("a\x0d\x0a" "b\x0d\x0a", 1, 6, f); fclose (f); } else printf ("Can't write\n"); with_fopen (fname, "rb"); with_fopen (fname, "r"); with_open (fname, O_RDONLY, "open (O_RDONLY)"); #ifdef O_TEXT with_open (fname, O_RDONLY | O_TEXT, "O_RDONLY|O_TEXT"); #else printf ("Don't have O_TEXT\n"); #endif #ifdef O_BINARY with_open (fname, O_RDONLY | O_BINARY, "O_RD..|O_BINARY"); #else printf ("Don't have O_BINARY\n"); #endif return 0; } --TB36FDmn/VVEgNH/ Content-Type: text/plain; charset=us-ascii -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Bug reporting: http://cygwin.com/bugs.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ --TB36FDmn/VVEgNH/--