diff --git a/newlib/ChangeLog b/newlib/ChangeLog index 13a916cab..4a57248e8 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,16 @@ +2002-07-23 Jeff Johnston + + * libc/include/stdio.h: Move fcloseall prototype within + #ifndef _REENT_ONLY section. + * libc/sys/linux/Makefile.am: Add new files. + * libc/sys/linux/Makefile.in: Regenerated. + * libc/sys/linux/sys/stdio.h: Add ctermid prototype. + * libc/sys/linux/sys/unistd.h: Add ttyname_r prototype. + * libc/sys/linux/sys/types.h: Add ino64_t type. + * libc/sys/linux/ctermid.c: New file. + * libc/sys/linux/ttyname_r.c: Ditto. + * libc/sys/linux/readdir64.c: Ditto. + 2002-07-22 Jeff Johnston * libc/include/stdio.h (fcloseall, _fcloseall_r): Added prototypes. diff --git a/newlib/libc/include/stdio.h b/newlib/libc/include/stdio.h index debeb2b3b..033e47962 100644 --- a/newlib/libc/include/stdio.h +++ b/newlib/libc/include/stdio.h @@ -204,7 +204,6 @@ int _EXFUN(rename, (const char *, const char *)); #endif #ifndef __STRICT_ANSI__ int _EXFUN(asprintf, (char **, const char *, ...)); -int _EXFUN(fcloseall, (_VOID)); int _EXFUN(fseeko, (FILE *, off_t, int)); off_t _EXFUN(ftello, ( FILE *)); int _EXFUN(vfiprintf, (FILE *, const char *, __VALIST)); @@ -218,6 +217,7 @@ int _EXFUN(vfscanf, (FILE *, const char *, __VALIST)); int _EXFUN(vscanf, (const char *, __VALIST)); int _EXFUN(vsscanf, (const char *, const char *, __VALIST)); #ifndef _REENT_ONLY +int _EXFUN(fcloseall, (_VOID)); int _EXFUN(snprintf, (char *, size_t, const char *, ...)); #endif #endif diff --git a/newlib/libc/sys/linux/Makefile.am b/newlib/libc/sys/linux/Makefile.am index f79e262c0..3635b43c2 100644 --- a/newlib/libc/sys/linux/Makefile.am +++ b/newlib/libc/sys/linux/Makefile.am @@ -2,7 +2,7 @@ AUTOMAKE_OPTIONS = cygnus -INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) +INCLUDES = -I$(srcdir)/include $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) SUBDIRS = machine \ . @@ -19,6 +19,7 @@ LIB_SOURCES = \ clock_getres.c \ clock_gettime.c \ clock_settime.c \ + ctermid.c \ flockfile.c \ fpathconf.c \ free.c \ @@ -67,6 +68,7 @@ LIB_SOURCES = \ pwrite.c \ pwrite64.c \ raise.c \ + readdir64.c \ realloc.c \ reallocr.c \ realpath.c \ @@ -98,6 +100,7 @@ LIB_SOURCES = \ tcsendbrk.c \ termios.c \ time.c \ + ttyname_r.c \ usleep.c \ utimes.c \ vallocr.c \ diff --git a/newlib/libc/sys/linux/Makefile.in b/newlib/libc/sys/linux/Makefile.in index 670964189..bad3db1d1 100644 --- a/newlib/libc/sys/linux/Makefile.in +++ b/newlib/libc/sys/linux/Makefile.in @@ -97,7 +97,7 @@ sys_dir = @sys_dir@ AUTOMAKE_OPTIONS = cygnus -INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) +INCLUDES = -I$(srcdir)/include $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) SUBDIRS = machine \ . @@ -116,6 +116,7 @@ LIB_SOURCES = \ clock_getres.c \ clock_gettime.c \ clock_settime.c \ + ctermid.c \ flockfile.c \ fpathconf.c \ free.c \ @@ -164,6 +165,7 @@ LIB_SOURCES = \ pwrite.c \ pwrite64.c \ raise.c \ + readdir64.c \ realloc.c \ reallocr.c \ realpath.c \ @@ -195,6 +197,7 @@ LIB_SOURCES = \ tcsendbrk.c \ termios.c \ time.c \ + ttyname_r.c \ usleep.c \ utimes.c \ vallocr.c \ @@ -242,14 +245,15 @@ LIBS = @LIBS@ @USE_LIBTOOL_FALSE@calloc.$(OBJEXT) callocr.$(OBJEXT) cfreer.$(OBJEXT) \ @USE_LIBTOOL_FALSE@cfspeed.$(OBJEXT) clock_getres.$(OBJEXT) \ @USE_LIBTOOL_FALSE@clock_gettime.$(OBJEXT) clock_settime.$(OBJEXT) \ -@USE_LIBTOOL_FALSE@flockfile.$(OBJEXT) fpathconf.$(OBJEXT) \ -@USE_LIBTOOL_FALSE@free.$(OBJEXT) freer.$(OBJEXT) ftok.$(OBJEXT) \ -@USE_LIBTOOL_FALSE@funlockfile.$(OBJEXT) getdate.$(OBJEXT) \ -@USE_LIBTOOL_FALSE@getdate_err.$(OBJEXT) gethostname.$(OBJEXT) \ -@USE_LIBTOOL_FALSE@getoptlong.$(OBJEXT) getreent.$(OBJEXT) \ -@USE_LIBTOOL_FALSE@getrlimit64.$(OBJEXT) ids.$(OBJEXT) inode.$(OBJEXT) \ -@USE_LIBTOOL_FALSE@io.$(OBJEXT) io64.$(OBJEXT) ipc.$(OBJEXT) \ -@USE_LIBTOOL_FALSE@linux.$(OBJEXT) malign.$(OBJEXT) malignr.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@ctermid.$(OBJEXT) flockfile.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@fpathconf.$(OBJEXT) free.$(OBJEXT) freer.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@ftok.$(OBJEXT) funlockfile.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@getdate.$(OBJEXT) getdate_err.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@gethostname.$(OBJEXT) getoptlong.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@getreent.$(OBJEXT) getrlimit64.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@ids.$(OBJEXT) inode.$(OBJEXT) io.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@io64.$(OBJEXT) ipc.$(OBJEXT) linux.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@malign.$(OBJEXT) malignr.$(OBJEXT) \ @USE_LIBTOOL_FALSE@mallinfor.$(OBJEXT) mallocr.$(OBJEXT) \ @USE_LIBTOOL_FALSE@malloptr.$(OBJEXT) mallstatsr.$(OBJEXT) \ @USE_LIBTOOL_FALSE@mmap.$(OBJEXT) mq_close.$(OBJEXT) \ @@ -262,45 +266,46 @@ LIBS = @LIBS@ @USE_LIBTOOL_FALSE@pread.$(OBJEXT) pread64.$(OBJEXT) process.$(OBJEXT) \ @USE_LIBTOOL_FALSE@psignal.$(OBJEXT) pvallocr.$(OBJEXT) \ @USE_LIBTOOL_FALSE@pwrite.$(OBJEXT) pwrite64.$(OBJEXT) raise.$(OBJEXT) \ -@USE_LIBTOOL_FALSE@realloc.$(OBJEXT) reallocr.$(OBJEXT) \ -@USE_LIBTOOL_FALSE@realpath.$(OBJEXT) rename.$(OBJEXT) \ -@USE_LIBTOOL_FALSE@resource.$(OBJEXT) sched.$(OBJEXT) select.$(OBJEXT) \ -@USE_LIBTOOL_FALSE@seteuid.$(OBJEXT) sethostname.$(OBJEXT) \ -@USE_LIBTOOL_FALSE@setrlimit64.$(OBJEXT) shm_open.$(OBJEXT) \ -@USE_LIBTOOL_FALSE@shm_unlink.$(OBJEXT) sig.$(OBJEXT) \ -@USE_LIBTOOL_FALSE@sigaction.$(OBJEXT) sigqueue.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@readdir64.$(OBJEXT) realloc.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@reallocr.$(OBJEXT) realpath.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@rename.$(OBJEXT) resource.$(OBJEXT) sched.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@select.$(OBJEXT) seteuid.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@sethostname.$(OBJEXT) setrlimit64.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@shm_open.$(OBJEXT) shm_unlink.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@sig.$(OBJEXT) sigaction.$(OBJEXT) sigqueue.$(OBJEXT) \ @USE_LIBTOOL_FALSE@signal.$(OBJEXT) siglongjmp.$(OBJEXT) \ @USE_LIBTOOL_FALSE@sigset.$(OBJEXT) sigwait.$(OBJEXT) socket.$(OBJEXT) \ @USE_LIBTOOL_FALSE@sleep.$(OBJEXT) stack.$(OBJEXT) strsignal.$(OBJEXT) \ @USE_LIBTOOL_FALSE@sysconf.$(OBJEXT) sysctl.$(OBJEXT) systat.$(OBJEXT) \ @USE_LIBTOOL_FALSE@system.$(OBJEXT) tcdrain.$(OBJEXT) \ @USE_LIBTOOL_FALSE@tcsendbrk.$(OBJEXT) termios.$(OBJEXT) time.$(OBJEXT) \ -@USE_LIBTOOL_FALSE@usleep.$(OBJEXT) utimes.$(OBJEXT) vallocr.$(OBJEXT) \ -@USE_LIBTOOL_FALSE@wait.$(OBJEXT) +@USE_LIBTOOL_FALSE@ttyname_r.$(OBJEXT) usleep.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@utimes.$(OBJEXT) vallocr.$(OBJEXT) wait.$(OBJEXT) LTLIBRARIES = $(noinst_LTLIBRARIES) @USE_LIBTOOL_TRUE@liblinux_la_OBJECTS = aio.lo brk.lo calloc.lo \ @USE_LIBTOOL_TRUE@callocr.lo cfreer.lo cfspeed.lo clock_getres.lo \ -@USE_LIBTOOL_TRUE@clock_gettime.lo clock_settime.lo flockfile.lo \ -@USE_LIBTOOL_TRUE@fpathconf.lo free.lo freer.lo ftok.lo funlockfile.lo \ -@USE_LIBTOOL_TRUE@getdate.lo getdate_err.lo gethostname.lo \ -@USE_LIBTOOL_TRUE@getoptlong.lo getreent.lo getrlimit64.lo ids.lo \ -@USE_LIBTOOL_TRUE@inode.lo io.lo io64.lo ipc.lo linux.lo malign.lo \ -@USE_LIBTOOL_TRUE@malignr.lo mallinfor.lo mallocr.lo malloptr.lo \ -@USE_LIBTOOL_TRUE@mallstatsr.lo mmap.lo mq_close.lo mq_getattr.lo \ -@USE_LIBTOOL_TRUE@mq_notify.lo mq_open.lo mq_receive.lo mq_send.lo \ -@USE_LIBTOOL_TRUE@mq_setattr.lo mq_unlink.lo msize.lo msizer.lo \ -@USE_LIBTOOL_TRUE@mstats.lo mtrim.lo mtrimr.lo ntp_gettime.lo \ +@USE_LIBTOOL_TRUE@clock_gettime.lo clock_settime.lo ctermid.lo \ +@USE_LIBTOOL_TRUE@flockfile.lo fpathconf.lo free.lo freer.lo ftok.lo \ +@USE_LIBTOOL_TRUE@funlockfile.lo getdate.lo getdate_err.lo \ +@USE_LIBTOOL_TRUE@gethostname.lo getoptlong.lo getreent.lo \ +@USE_LIBTOOL_TRUE@getrlimit64.lo ids.lo inode.lo io.lo io64.lo ipc.lo \ +@USE_LIBTOOL_TRUE@linux.lo malign.lo malignr.lo mallinfor.lo mallocr.lo \ +@USE_LIBTOOL_TRUE@malloptr.lo mallstatsr.lo mmap.lo mq_close.lo \ +@USE_LIBTOOL_TRUE@mq_getattr.lo mq_notify.lo mq_open.lo mq_receive.lo \ +@USE_LIBTOOL_TRUE@mq_send.lo mq_setattr.lo mq_unlink.lo msize.lo \ +@USE_LIBTOOL_TRUE@msizer.lo mstats.lo mtrim.lo mtrimr.lo ntp_gettime.lo \ @USE_LIBTOOL_TRUE@pathconf.lo pread.lo pread64.lo process.lo psignal.lo \ -@USE_LIBTOOL_TRUE@pvallocr.lo pwrite.lo pwrite64.lo raise.lo realloc.lo \ -@USE_LIBTOOL_TRUE@reallocr.lo realpath.lo rename.lo resource.lo \ -@USE_LIBTOOL_TRUE@sched.lo select.lo seteuid.lo sethostname.lo \ -@USE_LIBTOOL_TRUE@setrlimit64.lo shm_open.lo shm_unlink.lo sig.lo \ -@USE_LIBTOOL_TRUE@sigaction.lo sigqueue.lo signal.lo siglongjmp.lo \ -@USE_LIBTOOL_TRUE@sigset.lo sigwait.lo socket.lo sleep.lo stack.lo \ -@USE_LIBTOOL_TRUE@strsignal.lo sysconf.lo sysctl.lo systat.lo system.lo \ -@USE_LIBTOOL_TRUE@tcdrain.lo tcsendbrk.lo termios.lo time.lo usleep.lo \ -@USE_LIBTOOL_TRUE@utimes.lo vallocr.lo wait.lo +@USE_LIBTOOL_TRUE@pvallocr.lo pwrite.lo pwrite64.lo raise.lo \ +@USE_LIBTOOL_TRUE@readdir64.lo realloc.lo reallocr.lo realpath.lo \ +@USE_LIBTOOL_TRUE@rename.lo resource.lo sched.lo select.lo seteuid.lo \ +@USE_LIBTOOL_TRUE@sethostname.lo setrlimit64.lo shm_open.lo \ +@USE_LIBTOOL_TRUE@shm_unlink.lo sig.lo sigaction.lo sigqueue.lo \ +@USE_LIBTOOL_TRUE@signal.lo siglongjmp.lo sigset.lo sigwait.lo \ +@USE_LIBTOOL_TRUE@socket.lo sleep.lo stack.lo strsignal.lo sysconf.lo \ +@USE_LIBTOOL_TRUE@sysctl.lo systat.lo system.lo tcdrain.lo tcsendbrk.lo \ +@USE_LIBTOOL_TRUE@termios.lo time.lo ttyname_r.lo usleep.lo utimes.lo \ +@USE_LIBTOOL_TRUE@vallocr.lo wait.lo CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) diff --git a/newlib/libc/sys/linux/ctermid.c b/newlib/libc/sys/linux/ctermid.c new file mode 100644 index 000000000..05914ffad --- /dev/null +++ b/newlib/libc/sys/linux/ctermid.c @@ -0,0 +1,16 @@ +/* ctermid */ + +#include +#include + +static char devname[] = "/dev/tty"; + +char * +_DEFUN (ctermid, (buf), + char *buf) +{ + if (buf == NULL) + return devname; + + return strcpy (buf, "/dev/tty"); +} diff --git a/newlib/libc/sys/linux/readdir64.c b/newlib/libc/sys/linux/readdir64.c new file mode 100644 index 000000000..78fe98e90 --- /dev/null +++ b/newlib/libc/sys/linux/readdir64.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* Modified from newlib/libc/posix/readdir.c */ + +#include +#include + +#define __NR___getdents64 __NR_getdents64 + +static _syscall3(int,__getdents64,int,fd,struct dirent64 *,dirp,unsigned int,count) + +/* + * get next entry in a directory. + */ +struct dirent64 * +__readdir64 (dirp) +register DIR *dirp; { + register struct dirent64 *dp; + +#ifdef HAVE_DD_LOCK + __lock_acquire_recursive(dirp->dd_lock); +#endif + + if (dirp->dd_fd == -1) + return NULL; + + for (;;) { + if (dirp->dd_loc == 0) { + dirp->dd_size = __getdents64 (dirp->dd_fd, + (void *)dirp->dd_buf, + dirp->dd_len); + + if (dirp->dd_size <= 0) { +#ifdef HAVE_DD_LOCK + __lock_release_recursive(dirp->dd_lock); +#endif + return NULL; + } + } + if (dirp->dd_loc >= dirp->dd_size) { + dirp->dd_loc = 0; + continue; + } + dp = (struct dirent64 *)(dirp->dd_buf + dirp->dd_loc); + if ((int)dp & 03) { /* bogus pointer check */ +#ifdef HAVE_DD_LOCK + __lock_release_recursive(dirp->dd_lock); +#endif + return NULL; + } + if (dp->d_reclen <= 0 || + dp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc) { +#ifdef HAVE_DD_LOCK + __lock_release_recursive(dirp->dd_lock); +#endif + return NULL; + } + dirp->dd_loc += dp->d_reclen; + if (dp->d_ino == 0) + continue; +#ifdef HAVE_DD_LOCK + __lock_release_recursive(dirp->dd_lock); +#endif + return (dp); + } +} diff --git a/newlib/libc/sys/linux/sys/stdio.h b/newlib/libc/sys/linux/sys/stdio.h index 29097c89e..a99308161 100644 --- a/newlib/libc/sys/linux/sys/stdio.h +++ b/newlib/libc/sys/linux/sys/stdio.h @@ -16,4 +16,6 @@ #define getline __getline #define getdelim __getdelim +char * _EXFUN(ctermid, (char *)); + #endif /* _NEWLIB_STDIO_H */ diff --git a/newlib/libc/sys/linux/sys/types.h b/newlib/libc/sys/linux/sys/types.h index 99887eb70..41b26b63d 100644 --- a/newlib/libc/sys/linux/sys/types.h +++ b/newlib/libc/sys/linux/sys/types.h @@ -144,6 +144,7 @@ typedef long fd_mask; #define __key_t_defined #define __off_t_defined +typedef __ino64_t ino64_t; typedef __uint32_t uintptr_t; typedef __int32_t intptr_t; diff --git a/newlib/libc/sys/linux/sys/unistd.h b/newlib/libc/sys/linux/sys/unistd.h index 24e813586..52c380118 100644 --- a/newlib/libc/sys/linux/sys/unistd.h +++ b/newlib/libc/sys/linux/sys/unistd.h @@ -113,7 +113,8 @@ void _EXFUN(swab, (const void *, void *, ssize_t)); long _EXFUN(sysconf, (int __name )); pid_t _EXFUN(tcgetpgrp, (int __fildes )); int _EXFUN(tcsetpgrp, (int __fildes, pid_t __pgrp_id )); -char _EXFUN(*ttyname, (int __fildes )); +char * _EXFUN(ttyname, (int __fildes )); +int _EXFUN(ttyname_r, (int __fildes, char *__buf, size_t __len)); int _EXFUN(unlink, (const char *__path )); int _EXFUN(vhangup, (void )); _READ_WRITE_RETURN_TYPE _EXFUN(write, (int __fd, const void *__buf, size_t __nbyte )); diff --git a/newlib/libc/sys/linux/ttyname_r.c b/newlib/libc/sys/linux/ttyname_r.c new file mode 100644 index 000000000..a0cc90199 --- /dev/null +++ b/newlib/libc/sys/linux/ttyname_r.c @@ -0,0 +1,194 @@ +/* Copyright (C) 1991,92,93,1995-1999,2000,2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int getttyname_r (char *buf, size_t buflen, + dev_t mydev, ino64_t myino, int save, + int *dostat); + +extern struct dirent64 *__readdir64 (DIR *); + +#define __set_errno(x) (errno = (x)) + +static int +getttyname_r (char *buf, size_t buflen, dev_t mydev, ino64_t myino, + int save, int *dostat) +{ + struct stat64 st; + DIR *dirstream; + struct dirent64 *d; + size_t devlen = strlen (buf); + + dirstream = opendir (buf); + if (dirstream == NULL) + { + *dostat = -1; + return errno; + } + + while ((d = __readdir64 (dirstream)) != NULL) + { + if ((d->d_ino == myino || *dostat) + && strcmp (d->d_name, "stdin") + && strcmp (d->d_name, "stdout") + && strcmp (d->d_name, "stderr")) + { + size_t needed = strlen (d->d_name) + 1; + + if (needed > buflen) + { + *dostat = -1; + (void) closedir (dirstream); + __set_errno (ERANGE); + return ERANGE; + } + + strncpy (buf + devlen, d->d_name, needed); + + if (stat64 (buf, &st) == 0 +#ifdef _STATBUF_ST_RDEV + && S_ISCHR (st.st_mode) && st.st_rdev == mydev +#else + && d->d_ino == myino && st.st_dev == mydev +#endif + ) + { + (void) closedir (dirstream); + __set_errno (save); + return 0; + } + } + } + + (void) closedir (dirstream); + __set_errno (save); + /* It is not clear what to return in this case. `isatty' says FD + refers to a TTY but no entry in /dev has this inode. */ + return ENOTTY; +} + +/* Store at most BUFLEN character of the pathname of the terminal FD is + open on in BUF. Return 0 on success, otherwise an error number. */ +int +__ttyname_r (int fd, char *buf, size_t buflen) +{ + char procname[30]; + struct stat64 st, st1; + int dostat = 0; + int save = errno; + int ret; + + /* Test for the absolute minimal size. This makes life easier inside + the loop. */ + if (!buf) + { + __set_errno (EINVAL); + return EINVAL; + } + + if (buflen < sizeof ("/dev/pts/")) + { + __set_errno (ERANGE); + return ERANGE; + } + + if (!isatty (fd)) + { + __set_errno (ENOTTY); + return ENOTTY; + } + + /* We try using the /proc filesystem. */ + sprintf (procname, "/proc/self/fd/%d", fd); + + ret = readlink (procname, buf, buflen - 1); + if (ret != -1 && buf[0] != '[') + { + buf[ret] = '\0'; + return 0; + } + if (ret == -1 && errno == ENAMETOOLONG) + { + __set_errno (ERANGE); + return ERANGE; + } + + if (fstat64 (fd, &st) < 0) + return errno; + + /* Prepare the result buffer. */ + memcpy (buf, "/dev/pts/", sizeof ("/dev/pts/")); + buflen -= sizeof ("/dev/pts/") - 1; + + if (stat64 (buf, &st1) == 0 && S_ISDIR (st1.st_mode)) + { +#ifdef _STATBUF_ST_RDEV + ret = getttyname_r (buf, buflen, st.st_rdev, st.st_ino, save, + &dostat); +#else + ret = getttyname_r (buf, buflen, st.st_dev, st.st_ino, save, + &dostat); +#endif + } + else + { + __set_errno (save); + ret = ENOENT; + } + + if (ret && dostat != -1) + { + buf[sizeof ("/dev/") - 1] = '\0'; + buflen += sizeof ("pts/") - 1; +#ifdef _STATBUF_ST_RDEV + ret = getttyname_r (buf, buflen, st.st_rdev, st.st_ino, save, + &dostat); +#else + ret = getttyname_r (buf, buflen, st.st_dev, st.st_ino, save, + &dostat); +#endif + } + + if (ret && dostat != -1) + { + buf[sizeof ("/dev/") - 1] = '\0'; + dostat = 1; +#ifdef _STATBUF_ST_RDEV + ret = getttyname_r (buf, buflen, st.st_rdev, st.st_ino, + save, &dostat); +#else + ret = getttyname_r (buf, buflen, st.st_dev, st.st_ino, + save, &dostat); +#endif + } + + return ret; +} + +weak_alias (__ttyname_r, ttyname_r)