From patchwork Tue Jan 25 17:33:31 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janne Blomqvist X-Patchwork-Id: 80392 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id F1999B70DF for ; Wed, 26 Jan 2011 04:33:48 +1100 (EST) Received: (qmail 13092 invoked by alias); 25 Jan 2011 17:33:42 -0000 Received: (qmail 13010 invoked by uid 22791); 25 Jan 2011 17:33:40 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, TW_BG, TW_CP, TW_IQ, TW_PW, TW_TP, TW_WU X-Spam-Check-By: sourceware.org Received: from mail-iw0-f175.google.com (HELO mail-iw0-f175.google.com) (209.85.214.175) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 25 Jan 2011 17:33:33 +0000 Received: by iwn8 with SMTP id 8so18053iwn.20 for ; Tue, 25 Jan 2011 09:33:31 -0800 (PST) MIME-Version: 1.0 Received: by 10.231.10.200 with SMTP id q8mr6904401ibq.122.1295976811437; Tue, 25 Jan 2011 09:33:31 -0800 (PST) Received: by 10.231.160.68 with HTTP; Tue, 25 Jan 2011 09:33:31 -0800 (PST) Date: Tue, 25 Jan 2011 19:33:31 +0200 Message-ID: Subject: [Patch, libfortran] PR 47432 Use thread-safe ttyname_r() if available From: Janne Blomqvist To: Fortran List , GCC Patches Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hi, the attached patch makes libgfortran use the thread-safe ttyname_r() function if available. Regtested on x86_64-unknown-linux-gnu, Ok for trunk? diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac index 4f137e4..7c7a915 100644 --- a/libgfortran/configure.ac +++ b/libgfortran/configure.ac @@ -249,7 +249,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) +AC_CHECK_FUNCS(localtime_r gmtime_r strerror_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 24481cc..252f29f 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 f2f532b..f48bd77 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 950b7a2..ad90552 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) -{ - return ttyname (((unix_stream *) s)->fd); -} +int +stream_ttyname (stream *s __attribute__ ((unused)), + char * buf __attribute__ ((unused)), + size_t buflen __attribute__ ((unused))) +{ +#ifdef HAVE_TTYNAME_R + return ttyname_r (((unix_stream *) s)->fd, buf, buflen); +#elif defined HAVE_TTYNAME + char *p; + int 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 0e147aa..f7d6f08 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);