From 3c12752024a356b71760e09560f5ae6f430fca27 Mon Sep 17 00:00:00 2001 From: Francois-Xavier Coudert Date: Wed, 7 Sep 2005 23:25:40 +0200 Subject: [PATCH] re PR libfortran/23262 ([mingw32] rewind truncates file) PR libfortran/23262 * acinclude.m4 (LIBGFOR_CHECK_CRLF): New check. * configure.ac: Use new check. * configure.in: Regenerate. * config.h.in: Regenerate. * configure: Regenerate. * io/transfer.c (next_record_w): Add case for CRLF as line terminator. * io/unix.c (tempfile, regular_file): Open files with O_BINARY on systems with CRLF. From-SVN: r104009 --- libgfortran/ChangeLog | 13 ++++++ libgfortran/acinclude.m4 | 47 ++++++++++++++++++++ libgfortran/config.h.in | 3 ++ libgfortran/configure | 90 +++++++++++++++++++++++++++++++++++++++ libgfortran/configure.ac | 3 ++ libgfortran/io/transfer.c | 13 +++++- libgfortran/io/unix.c | 9 ++++ 7 files changed, 177 insertions(+), 1 deletion(-) diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 8b2bb625a46..d43be2e02c8 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,16 @@ +2005-09-07 Francois-Xavier Coudert + + PR libfortran/23262 + * acinclude.m4 (LIBGFOR_CHECK_CRLF): New check. + * configure.ac: Use new check. + * configure.in: Regenerate. + * config.h.in: Regenerate. + * configure: Regenerate. + * io/transfer.c (next_record_w): Add case for CRLF as line + terminator. + * io/unix.c (tempfile, regular_file): Open files with + O_BINARY on systems with CRLF. + 2005-09-07 Steve Ellcey PR libfortran/23419 diff --git a/libgfortran/acinclude.m4 b/libgfortran/acinclude.m4 index 4355d3a12fc..f9fcca66659 100644 --- a/libgfortran/acinclude.m4 +++ b/libgfortran/acinclude.m4 @@ -183,3 +183,50 @@ esac])]) if test x"$have_unlink_open_file" = xyes; then AC_DEFINE(HAVE_UNLINK_OPEN_FILE, 1, [Define if target can unlink open files.]) fi]) + +dnl Check whether CRLF is the line terminator +AC_DEFUN([LIBGFOR_CHECK_CRLF], [ + AC_CACHE_CHECK([whether the target has CRLF as line terminator], + have_crlf, [ + AC_TRY_RUN([ +/* This test program should exit with status 0 if system uses a CRLF as + line terminator, and status 1 otherwise. + Since it is used to check for mingw systems, and should return 0 in any + other case, in case of a failure we will not use CRLF. */ +#include +#include +#include +#include + +int main () +{ +#ifndef O_BINARY + exit(1); +#else + int fd, bytes; + char buff[5]; + + fd = open ("foo", O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU); + if (fd < 0) + exit(1); + if (write (fd, "\n", 1) < 0) + perror ("write"); + + close (fd); + + if ((fd = open ("foo", O_RDONLY | O_BINARY, S_IRWXU)) < 0) + exit(1); + bytes = read (fd, buff, 5); + if (bytes == 2 && buff[0] == '\r' && buff[1] == '\n') + exit(0); + else + exit(1); +#endif +}], have_crlf=yes, have_crlf=no, [ +case "${target}" in + *mingw*) have_crlf=yes ;; + *) have_crlf=no;; +esac])]) +if test x"$have_crlf" = xyes; then + AC_DEFINE(HAVE_CRLF, 1, [Define if CRLF is line terminator.]) +fi]) diff --git a/libgfortran/config.h.in b/libgfortran/config.h.in index bc110c9fffa..923b2037ec2 100644 --- a/libgfortran/config.h.in +++ b/libgfortran/config.h.in @@ -54,6 +54,9 @@ /* libm includes coshf */ #undef HAVE_COSHF +/* Define if CRLF is line terminator. */ +#undef HAVE_CRLF + /* libm includes erf */ #undef HAVE_ERF diff --git a/libgfortran/configure b/libgfortran/configure index 6b6df14c4f9..74f922b95b3 100755 --- a/libgfortran/configure +++ b/libgfortran/configure @@ -12300,6 +12300,96 @@ _ACEOF fi +# Check whether line terminator is LF or CRLF + + echo "$as_me:$LINENO: checking whether the target has CRLF as line terminator" >&5 +echo $ECHO_N "checking whether the target has CRLF as line terminator... $ECHO_C" >&6 +if test "${have_crlf+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + if test "$cross_compiling" = yes; then + +case "${target}" in + *mingw*) have_crlf=yes ;; + *) have_crlf=no;; +esac +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* This test program should exit with status 0 if system uses a CRLF as + line terminator, and status 1 otherwise. + Since it is used to check for mingw systems, and should return 0 in any + other case, in case of a failure we will not use CRLF. */ +#include +#include +#include +#include + +int main () +{ +#ifndef O_BINARY + exit(1); +#else + int fd, bytes; + char buff[5]; + + fd = open ("foo", O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU); + if (fd < 0) + exit(1); + if (write (fd, "\n", 1) < 0) + perror ("write"); + + close (fd); + + if ((fd = open ("foo", O_RDONLY | O_BINARY, S_IRWXU)) < 0) + exit(1); + bytes = read (fd, buff, 5); + if (bytes == 2 && buff[0] == '\r' && buff[1] == '\n') + exit(0); + else + exit(1); +#endif +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + have_crlf=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +have_crlf=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +echo "$as_me:$LINENO: result: $have_crlf" >&5 +echo "${ECHO_T}$have_crlf" >&6 +if test x"$have_crlf" = xyes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_CRLF 1 +_ACEOF + +fi + cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac index 8968d45bf3a..f9f2b4d46ed 100644 --- a/libgfortran/configure.ac +++ b/libgfortran/configure.ac @@ -261,6 +261,9 @@ LIBGFOR_CHECK_ATTRIBUTE_ALIAS # Various other checks on target LIBGFOR_CHECK_UNLINK_OPEN_FILE +# Check whether line terminator is LF or CRLF +LIBGFOR_CHECK_CRLF + AC_CACHE_SAVE if test ${multilib} = yes; then diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c index 59eb22d3dec..9251cf8f24f 100644 --- a/libgfortran/io/transfer.c +++ b/libgfortran/io/transfer.c @@ -1422,13 +1422,24 @@ next_record_w (void) break; case FORMATTED_SEQUENTIAL: +#ifdef HAVE_CRLF + length = 2; +#else length = 1; +#endif p = salloc_w (current_unit->s, &length); if (!is_internal_unit()) { if (p) - *p = '\n'; /* No CR for internal writes. */ + { /* No new line for internal writes. */ +#ifdef HAVE_CRLF + p[0] = '\r'; + p[1] = '\n'; +#else + *p = '\n'; +#endif + } else goto io_error; } diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c index 69101efff04..87b839b6dd3 100644 --- a/libgfortran/io/unix.c +++ b/libgfortran/io/unix.c @@ -1000,7 +1000,12 @@ tempfile (void) if (mktemp (template)) do +#ifdef HAVE_CRLF + fd = open (template, O_RDWR | O_CREAT | O_EXCL | O_BINARY, + S_IREAD | S_IWRITE); +#else fd = open (template, O_RDWR | O_CREAT | O_EXCL, S_IREAD | S_IWRITE); +#endif while (!(fd == -1 && errno == EEXIST) && mktemp (template)); else fd = -1; @@ -1085,6 +1090,10 @@ regular_file (unit_flags *flags) /* rwflag |= O_LARGEFILE; */ +#ifdef HAVE_CRLF + crflag |= O_BINARY; +#endif + mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; fd = open (path, rwflag | crflag, mode); if (flags->action != ACTION_UNSPECIFIED)