diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 06aa3945b..2029f4007 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,9 @@ +2000-05-23 DJ Delorie + + * syscalls.cc (_cygwin_istext_for_stdio): New, for newlib + * include/cygwin/version.h: Bump API number for detect old + programs using old getc/putc macros + 2000-05-23 DJ Delorie * dir.cc (writable_directory): handle root directories diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index f145ed62d..b2abf1699 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -70,6 +70,13 @@ details. */ (CYGWIN_VERSION_DLL_MAKE_COMBINED (user_data->api_major, user_data->api_minor) <= \ CYGWIN_VERSION_DLL_OLD_TERMIOS) + /* Old APIs had getc/putc macros that conflict with new CR/LF + handling in the stdio buffers */ +#define CYGWIN_VERSION_OLD_STDIO_CRLF_HANDLING \ + (CYGWIN_VERSION_DLL_MAKE_COMBINED (user_data->api_major, user_data->api_minor) <= \ + 00020) + + /* We used to use the DLL major/minor to track non-backward-compatible interface changes to the API. Now we use an API major/minor number for this purpose. */ @@ -96,10 +103,11 @@ details. */ 18: Stop exporting _strace_wm 19: Export fchown, lchown, lacl 20: regsub, inet_network + 21: incompatible change to stdio cr/lf and buffering */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 20 +#define CYGWIN_VERSION_API_MINOR 21 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index e6a5c0670..cf743d005 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -1431,6 +1431,42 @@ ttyname (int fd) return (char *)(dtable[fd]->ttyname ()); } +/* Tells stdio if it should do the cr/lf conversion for this file */ +extern "C" int _cygwin_istext_for_stdio (int fd); +int +_cygwin_istext_for_stdio (int fd) +{ + syscall_printf("_cygwin_istext_for_stdio (%d)\n", fd); + if (CYGWIN_VERSION_OLD_STDIO_CRLF_HANDLING) + { + syscall_printf(" _cifs: old API\n"); + return 0; /* we do it for old apps, due to getc/putc macros */ + } + + if (dtable.not_open (fd)) + { + syscall_printf(" _cifs: fd not open\n"); + return 0; + } + + fhandler_base *p = dtable[fd]; + + if (p->get_device() != FH_DISK) + { + syscall_printf(" _cifs: fd not disk file\n"); + return 0; + } + + if (p->get_w_binary () || p->get_r_binary ()) + { + syscall_printf(" _cifs: get_*_binary\n"); + return 0; + } + + syscall_printf("_cygwin_istext_for_stdio says yes\n"); + return 1; +} + /* internal newlib function */ extern "C" int _fwalk (struct _reent *ptr, int (*function)(FILE *)); @@ -1442,6 +1478,9 @@ setmode_helper (FILE *f) { if (fileno(f) != setmode_file) return 0; + syscall_printf("setmode: file was %s now %s\n", + f->_flags & __SCLE ? "cle" : "raw", + setmode_mode & O_TEXT ? "cle" : "raw"); if (setmode_mode & O_TEXT) f->_flags |= __SCLE; else @@ -1491,10 +1530,17 @@ setmode (int fd, int mode) p->set_r_binary (0); } - setmode_mode = mode; + if (_cygwin_istext_for_stdio (fd)) + setmode_mode = O_TEXT; + else + setmode_mode = O_BINARY; setmode_file = fd; _fwalk(_REENT, setmode_helper); + syscall_printf ("setmode (%d, %s) returns %s\n", fd, + mode&O_TEXT ? "text" : "binary", + res&O_TEXT ? "text" : "binary"); + return res; }