From 6a0f6e7799c988524d32767047ca64d05a93adaf Mon Sep 17 00:00:00 2001 From: Janne Blomqvist Date: Thu, 27 Jan 2011 22:05:45 +0200 Subject: [PATCH] PR 47432 Use ttyname_r() if available From-SVN: r169337 --- libgfortran/ChangeLog | 13 +++++++++++++ libgfortran/config.h.in | 3 +++ libgfortran/configure | 2 +- libgfortran/configure.ac | 2 +- libgfortran/io/inquire.c | 15 ++++++++------- libgfortran/io/intrinsics.c | 27 +++++++++++++++------------ libgfortran/io/unix.c | 29 ++++++++++++++++++++--------- libgfortran/io/unix.h | 11 ++++++++++- 8 files changed, 71 insertions(+), 31 deletions(-) diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 3608e14e67b..c096acfbb00 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,16 @@ +2011-01-27 Janne Blomqvist + + PR libfortran/47432 + * config.h.in: Regenerated. + * configure: Regenerated. + * configure.ac: Add check for ttyname_r. + * io/unix.h: Add TTY_NAME_MAX, change stream_ttyname prototype. + * io/unix.c (stream_ttyname): Use ttyname_r if available, conform + to new prototype. + * io/inquire.c (inquire_via_unit): Use changed stream_ttyname. + * io/intrinsics.c (ttynam_sub): Likewise. + (ttynam): Likewise. + 2011-01-27 Janne Blomqvist PR libfortran/47491 diff --git a/libgfortran/config.h.in b/libgfortran/config.h.in index 8340e3b59bc..65414c75fc6 100644 --- a/libgfortran/config.h.in +++ b/libgfortran/config.h.in @@ -807,6 +807,9 @@ /* Define to 1 if you have the `ttyname' function. */ #undef HAVE_TTYNAME +/* Define to 1 if you have the `ttyname_r' function. */ +#undef HAVE_TTYNAME_R + /* Define to 1 if the system has the type `uintptr_t'. */ #undef HAVE_UINTPTR_T diff --git a/libgfortran/configure b/libgfortran/configure index 067c8ce8e45..836dfdc05e3 100755 --- a/libgfortran/configure +++ b/libgfortran/configure @@ -16367,7 +16367,7 @@ _ACEOF fi done -for ac_func in localtime_r gmtime_r strerror_r getpwuid_r +for ac_func in localtime_r gmtime_r strerror_r getpwuid_r ttyname_r do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac index dfbb37a5d94..87d2340ab6c 100644 --- a/libgfortran/configure.ac +++ b/libgfortran/configure.ac @@ -251,7 +251,7 @@ AC_CHECK_FUNCS(chdir strerror getlogin gethostname kill link symlink perror) AC_CHECK_FUNCS(sleep time ttyname signal alarm ctime clock access fork execl) AC_CHECK_FUNCS(wait setmode execvp pipe dup2 close fdopen strcasestr getrlimit) AC_CHECK_FUNCS(gettimeofday stat fstat lstat getpwuid vsnprintf dup getcwd) -AC_CHECK_FUNCS(localtime_r gmtime_r strerror_r getpwuid_r) +AC_CHECK_FUNCS(localtime_r gmtime_r strerror_r getpwuid_r ttyname_r) # Check for glibc backtrace functions AC_CHECK_FUNCS(backtrace backtrace_symbols) diff --git a/libgfortran/io/inquire.c b/libgfortran/io/inquire.c index 24481ccccbe..252f29f0aef 100644 --- a/libgfortran/io/inquire.c +++ b/libgfortran/io/inquire.c @@ -1,8 +1,8 @@ -/* Copyright (C) 2002, 2003, 2005, 2007, 2009, 2010 +/* Copyright (C) 2002, 2003, 2005, 2007, 2009, 2010, 2011 Free Software Foundation, Inc. Contributed by Andy Vaught -This file is part of the GNU Fortran 95 runtime library (libgfortran). +This file is part of the GNU Fortran runtime library (libgfortran). Libgfortran is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -68,16 +68,17 @@ inquire_via_unit (st_parameter_inquire *iqp, gfc_unit * u) if ((cf & IOPARM_INQUIRE_HAS_NAME) != 0 && u != NULL && u->flags.status != STATUS_SCRATCH) { -#ifdef HAVE_TTYNAME +#if defined(HAVE_TTYNAME_R) || defined(HAVE_TTYNAME) if (u->unit_number == options.stdin_unit || u->unit_number == options.stdout_unit || u->unit_number == options.stderr_unit) { - char * tmp = stream_ttyname (u->s); - if (tmp != NULL) + int err = stream_ttyname (u->s, iqp->name, iqp->name_len); + if (err == 0) { - int tmplen = strlen (tmp); - fstrcpy (iqp->name, iqp->name_len, tmp, tmplen); + gfc_charlen_type tmplen = strlen (iqp->name); + if (iqp->name_len > tmplen) + memset (&iqp->name[tmplen], ' ', iqp->name_len - tmplen); } else /* If ttyname does not work, go with the default. */ fstrcpy (iqp->name, iqp->name_len, u->file, u->file_len); diff --git a/libgfortran/io/intrinsics.c b/libgfortran/io/intrinsics.c index f2f532b9291..f48bd777456 100644 --- a/libgfortran/io/intrinsics.c +++ b/libgfortran/io/intrinsics.c @@ -1,6 +1,7 @@ /* Implementation of the FGET, FGETC, FPUT, FPUTC, FLUSH FTELL, TTYNAM and ISATTY intrinsics. - Copyright (C) 2005, 2007, 2009, 2010 Free Software Foundation, Inc. + Copyright (C) 2005, 2007, 2009, 2010, 2011 Free Software + Foundation, Inc. This file is part of the GNU Fortran runtime library (libgfortran). @@ -351,22 +352,23 @@ void ttynam_sub (int *unit, char * name, gfc_charlen_type name_len) { gfc_unit *u; - char * n; - int i; + int nlen; + int err = 1; - memset (name, ' ', name_len); u = find_unit (*unit); if (u != NULL) { - n = stream_ttyname (u->s); - if (n != NULL) + err = stream_ttyname (u->s, name, name_len); + if (err == 0) { - i = 0; - while (*n && i < name_len) - name[i++] = *(n++); + nlen = strlen (name); + memset (&name[nlen], ' ', name_len - nlen); } + unlock_unit (u); } + if (err != 0) + memset (name, ' ', name_len); } @@ -381,14 +383,15 @@ ttynam (char ** name, gfc_charlen_type * name_len, int unit) u = find_unit (unit); if (u != NULL) { - *name = stream_ttyname (u->s); - if (*name != NULL) + *name = get_mem (TTY_NAME_MAX); + int err = stream_ttyname (u->s, *name, TTY_NAME_MAX); + if (err == 0) { *name_len = strlen (*name); - *name = strdup (*name); unlock_unit (u); return; } + free (*name); unlock_unit (u); } diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c index 950b7a25b1f..004e8606c0a 100644 --- a/libgfortran/io/unix.c +++ b/libgfortran/io/unix.c @@ -1811,18 +1811,29 @@ stream_isatty (stream *s) return isatty (((unix_stream *) s)->fd); } -char * -#ifdef HAVE_TTYNAME -stream_ttyname (stream *s) +int +stream_ttyname (stream *s __attribute__ ((unused)), + char * buf __attribute__ ((unused)), + size_t buflen __attribute__ ((unused))) { - return ttyname (((unix_stream *) s)->fd); -} +#ifdef HAVE_TTYNAME_R + return ttyname_r (((unix_stream *) s)->fd, buf, buflen); +#elif defined HAVE_TTYNAME + char *p; + size_t plen; + p = ttyname (((unix_stream *) s)->fd); + if (!p) + return errno; + plen = strlen (p); + if (buflen < plen) + plen = buflen; + memcpy (buf, p, plen); + return 0; #else -stream_ttyname (stream *s __attribute__ ((unused))) -{ - return NULL; -} + return ENOSYS; #endif +} + diff --git a/libgfortran/io/unix.h b/libgfortran/io/unix.h index 0e147aab565..f7d6f08643e 100644 --- a/libgfortran/io/unix.h +++ b/libgfortran/io/unix.h @@ -170,7 +170,16 @@ internal_proto(flush_if_preconnected); extern int stream_isatty (stream *); internal_proto(stream_isatty); -extern char * stream_ttyname (stream *); +#ifndef TTY_NAME_MAX +#ifdef _POSIX_TTY_NAME_MAX +#define TTY_NAME_MAX _POSIX_TTY_NAME_MAX +#else +/* sysconf(_SC_TTY_NAME_MAX) = 32 which should be enough. */ +#define TTY_NAME_MAX 32 +#endif +#endif + +extern int stream_ttyname (stream *, char *, size_t); internal_proto(stream_ttyname); extern int unpack_filename (char *, const char *, int);