Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Johnston <jjohnstn@redhat.com>2002-07-23 23:40:45 +0400
committerJeff Johnston <jjohnstn@redhat.com>2002-07-23 23:40:45 +0400
commitbc10065533261fbde738caea2096b2bac81a970b (patch)
treefa6331544d9f8fb21b59685f241716ffd818e894 /newlib/libc/sys
parent010bb8a4a1548252fc0c72943441a2252bc7aca9 (diff)
2002-07-23 Jeff Johnston <jjohnstn@redhat.com>
* 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.
Diffstat (limited to 'newlib/libc/sys')
-rw-r--r--newlib/libc/sys/linux/Makefile.am5
-rw-r--r--newlib/libc/sys/linux/Makefile.in79
-rw-r--r--newlib/libc/sys/linux/ctermid.c16
-rw-r--r--newlib/libc/sys/linux/readdir64.c97
-rw-r--r--newlib/libc/sys/linux/sys/stdio.h2
-rw-r--r--newlib/libc/sys/linux/sys/types.h1
-rw-r--r--newlib/libc/sys/linux/sys/unistd.h3
-rw-r--r--newlib/libc/sys/linux/ttyname_r.c194
8 files changed, 358 insertions, 39 deletions
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 <stdio.h>
+#include <string.h>
+
+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 <dirent.h>
+#include <machine/syscall.h>
+
+#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 <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <machine/weakalias.h>
+
+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)