[PATCH] open O_TEXT and O_BINARY for cygwin/windows

Ville Herva vherva at niksula.hut.fi
Thu Jan 23 07:50:00 EST 2003


> > perhaps you would want to consider the "force binary open for data files
> > on CYGWIN" -patch I sent ages ago? I feel it's quite important, and to
> > me it never makes sense to open data files in ascii (CR/LF translation
> > mode) nor config files in BINARY mode (opening them in ascii makes it
> > possible to edit them with both NOTEPAD etc and the unix line ending
> > compliant cygwin editors.)
> > 
> > See the thread starting at:
> > 
> > http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=utf-8&threadm=a4vfnh%242ec%241%40FreeBSD.csie.NCTU.edu.tw&rnum=1&prev=/groups%3Fq%3Drsync%2Bon%2Bcygwin%2B-%2Btextmode%2Bconfig%2Bfiles%26num%3D50%26hl%3Den%26lr%3D%26ie%3DUTF-8%26oe%3Dutf-8%26sa%3DN%26tab%3Dwg
> > 
> > I'm mostly talking about (4) - others are not that important.

On Wed, Jan 22, 2003 at 03:53:27PM -0600, you [Dave Dykstra] wrote:
> Could you please port the patch to 2.5.6pre2 and post it to the mailing
> list?  

Here it is.

In short: on Cygwin you can mount volumes as text or binary. For text mounts
CR/LF->CR translation is done on the fly, binary mounts do not alter the
data. For applications that deal with raw data (gzip, tar, md5sum, cp,
rsync) it makes sense to access the data in binary always (and actually
rsync does nowadays, the O_BINARY flag is set in do_open). On the other hand
it makes sense to open config files in text so that the user can change
them with windows editors - the CR/LF translation will do no harm even if
the file has unix line endings.

This batch adds a few O_TEXT and O_BINARY flags to *open() calls - files
that are obviously text are opened as such; data files are opened as
binary.

- Files batch.c checksum.c generator.c receiver.c sender.c util.c use
  do_open which does O_BINARY already (which has chanced since I originally
  made the patch years ago), so no need to touch those. Other than that 
  I went through all open, fdopen, and fopen calls and tried to 
  add either O_TEXT or O_BINARY where it made sense.
- O_BINARY and O_TEXT are defined in rsync.h unless they are available
  on the platform:

   +#if !defined(O_TEXT)
   +#define O_TEXT 0
   +#endif
   +#if !defined(O_BINARY)
   +#define O_BINARY 0
   +#endif

- I also use fopen(filename, "rt"). I _think_ that all fopen implementations
  should ignore "t" unless they recognize it. At least linux does (it
  seems to ignore all chars it doesn't recognize. "rt" is one of the
  alternatives Chris Faylor recommends for CYGWIN:

  http://www.cygwin.com/ml/cygwin/2000-10/msg00213.html:
  > You do that one of three ways:
  >
  > open ("foo", O_RDONLY | O_TEXT);
  > fopen ("foo", "rt");
  > setmode (fd, O_TEXT);

  "rt" one is the only one for FILEs (and setmode doesn't even exists on
  all other platforms AFAICT.

  man fopen says:

       The mode string can also include the letter  ``b''  either
       as  a last character or as a character between the charac­
       ters in any of the two-character strings described  above.
       This  is  strictly for compatibility with ANSI X3.159-1989
       (``ANSI C'') and has no effect; the ``b''  is  ignored  on
       all  POSIX  conforming  systems,  including Linux.  (Other
       systems may treat text files and binary files differently,
       and adding the ``b'' may be a good idea if you do I/O to a
       binary file and expect that your program may be ported  to
       non-Unix environments.)

  So I would hope that "t" is handled the same way.

  Anyway, if someone knows better, please tell.

Patch attached - compiled, briefly tested (the previous incarnations tested
pretty extensively.) It doesn't alter the behaviour on platforms that don't
do O_BINARY and O_TEXT differently so I thinks it should be quite safe to
apply.


-- v --

v at iki.fi
-------------- next part --------------
diff -Naur --show-c-function --exclude='*.o' --exclude='*.exe' --exclude=Makefile --exclude='*~' rsync-2.5.6pre2.ORIG/authenticate.c rsync-2.5.6pre2/authenticate.c
--- rsync-2.5.6pre2.ORIG/authenticate.c	2002-08-01 03:40:13.000000000 +0300
+++ rsync-2.5.6pre2/authenticate.c	2003-01-23 08:56:09.000000000 +0200
@@ -82,7 +82,7 @@ static int get_secret(int module, char *
 
 	if (!fname || !*fname) return 0;
 
-	fd = open(fname,O_RDONLY);
+	fd = open(fname,O_RDONLY | O_TEXT);
 	if (fd == -1) return 0;
 
 	if (do_stat(fname, &st) == -1) {
@@ -144,7 +144,7 @@ static char *getpassf(char *filename)
 
 	if (!filename) return NULL;
 
-	if ( (fd=open(filename,O_RDONLY)) == -1) {
+	if ( (fd=open(filename,O_RDONLY | O_TEXT)) == -1) {
 		rsyserr(FERROR, errno, "could not open password file \"%s\"",filename);
 		if (envpw) rprintf(FERROR,"falling back to RSYNC_PASSWORD environment variable.\n");	
 		return NULL;
diff -Naur --show-c-function --exclude='*.o' --exclude='*.exe' --exclude=Makefile --exclude='*~' rsync-2.5.6pre2.ORIG/clientserver.c rsync-2.5.6pre2/clientserver.c
--- rsync-2.5.6pre2.ORIG/clientserver.c	2002-08-31 02:30:08.000000000 +0300
+++ rsync-2.5.6pre2/clientserver.c	2003-01-23 09:10:55.000000000 +0200
@@ -514,7 +514,7 @@ int start_daemon(int f_in, int f_out)
 
 	motd = lp_motd_file();
 	if (motd && *motd) {
-		FILE *f = fopen(motd,"r");
+		FILE *f = fopen(motd,"rt");
 		while (f && !feof(f)) {
 			int len = fread(line, 1, sizeof(line)-1, f);
 			if (len > 0) {
diff -Naur --show-c-function --exclude='*.o' --exclude='*.exe' --exclude=Makefile --exclude='*~' rsync-2.5.6pre2.ORIG/exclude.c rsync-2.5.6pre2/exclude.c
--- rsync-2.5.6pre2.ORIG/exclude.c	2003-01-09 06:00:09.000000000 +0200
+++ rsync-2.5.6pre2/exclude.c	2003-01-23 09:11:23.000000000 +0200
@@ -224,9 +224,9 @@ struct exclude_struct **make_exclude_lis
 	char line[MAXPATHLEN];
 
 	if (strcmp(fname, "-")) {
-		f = fopen(fname,"r");
+		f = fopen(fname,"rt");
 	} else {
-		f = fdopen(0, "r");
+		f = fdopen(0, "rt");
 	}
 	if (!f) {
 		if (fatal) {
diff -Naur --show-c-function --exclude='*.o' --exclude='*.exe' --exclude=Makefile --exclude='*~' rsync-2.5.6pre2.ORIG/params.c rsync-2.5.6pre2/params.c
--- rsync-2.5.6pre2.ORIG/params.c	2002-08-31 02:30:08.000000000 +0300
+++ rsync-2.5.6pre2/params.c	2003-01-23 09:06:36.000000000 +0200
@@ -488,7 +488,7 @@ static FILE *OpenConfFile( char *FileNam
     return( NULL );
     }
 
-  OpenedFile = fopen( FileName, "r" );
+  OpenedFile = fopen( FileName, "rt" );
   if( NULL == OpenedFile )
     {
     rprintf(FERROR,"rsync: unable to open configuration file \"%s\": %s\n",
diff -Naur --show-c-function --exclude='*.o' --exclude='*.exe' --exclude=Makefile --exclude='*~' rsync-2.5.6pre2.ORIG/rsync.h rsync-2.5.6pre2/rsync.h
--- rsync-2.5.6pre2.ORIG/rsync.h	2003-01-19 07:55:09.000000000 +0200
+++ rsync-2.5.6pre2/rsync.h	2003-01-23 09:09:20.000000000 +0200
@@ -595,6 +595,16 @@ void rsyserr(enum logcode, int, const ch
 #define inet_ntoa rep_inet_ntoa
 #endif
 
+/* Compability defines just in case. Note: we assume that fopen does not 
+ * barf on fopen(filename, "rt") - are there platforms where this is not 
+ * true? */
+#if !defined(O_TEXT)
+#define O_TEXT 0
+#endif
+#if !defined(O_BINARY)
+#define O_BINARY 0
+#endif
+
 
 #ifndef HAVE_STRLCPY
 size_t strlcpy(char *d, const char *s, size_t bufsize);
diff -Naur --show-c-function --exclude='*.o' --exclude='*.exe' --exclude=Makefile --exclude='*~' rsync-2.5.6pre2.ORIG/syscall.c rsync-2.5.6pre2/syscall.c
--- rsync-2.5.6pre2.ORIG/syscall.c	2003-01-21 03:00:10.000000000 +0200
+++ rsync-2.5.6pre2/syscall.c	2003-01-23 09:20:25.000000000 +0200
@@ -85,10 +85,10 @@ int do_open(char *pathname, int flags, m
 	    if (dry_run) return -1;
 	    CHECK_RO
 	}
-#ifdef O_BINARY
+
 	/* for Windows */
 	flags |= O_BINARY;
-#endif
+
 	/* some systems can't handle a double / */
 	if (pathname[0] == '/' && pathname[1] == '/') pathname++;
 


More information about the rsync mailing list