1998-10-29  Ulrich Drepper  <drepper@cygnus.com>

	* sysdeps/unix/sysv/linux/ttyname_r.c (ttyname_r): Try reading
	/prof/self/fd/FD first.
	* sysdeps/unix/sysv/linux/ttyname.c (ttyname): Likewise.

	* stdio-common/_itoa.h (_fitoa_word): New inline function.  Write
	formatted number starting at given position and return pointer to
	following byte.
	(_fitoa): Likewise, for long long.
This commit is contained in:
Ulrich Drepper 1998-10-29 15:17:25 +00:00
parent 05e951cd1a
commit c5e340c71b
14 changed files with 109 additions and 51 deletions

View File

@ -1,3 +1,14 @@
1998-10-29 Ulrich Drepper <drepper@cygnus.com>
* sysdeps/unix/sysv/linux/ttyname_r.c (ttyname_r): Try reading
/prof/self/fd/FD first.
* sysdeps/unix/sysv/linux/ttyname.c (ttyname): Likewise.
* stdio-common/_itoa.h (_fitoa_word): New inline function. Write
formatted number starting at given position and return pointer to
following byte.
(_fitoa): Likewise, for long long.
1998-10-29 Roland McGrath <roland@baalperazim.frob.com> 1998-10-29 Roland McGrath <roland@baalperazim.frob.com>
* sysdeps/unix/sysv/linux/bits/sem.h, * sysdeps/unix/sysv/linux/bits/sem.h,

View File

@ -53,7 +53,7 @@ int pthread_cancel(pthread_t thread)
pthread_handle handle = thread_handle(thread); pthread_handle handle = thread_handle(thread);
int pid; int pid;
__pthread_lock(&handle->h_lock); __pthread_lock(&handle->h_lock, NULL);
if (invalid_handle(handle, thread)) { if (invalid_handle(handle, thread)) {
__pthread_unlock(&handle->h_lock); __pthread_unlock(&handle->h_lock);
return ESRCH; return ESRCH;

View File

@ -43,7 +43,7 @@ int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
{ {
volatile pthread_descr self = thread_self(); volatile pthread_descr self = thread_self();
__pthread_lock(&cond->__c_lock); __pthread_lock(&cond->__c_lock, self);
enqueue(&cond->__c_waiting, self); enqueue(&cond->__c_waiting, self);
__pthread_unlock(&cond->__c_lock); __pthread_unlock(&cond->__c_lock);
pthread_mutex_unlock(mutex); pthread_mutex_unlock(mutex);
@ -53,7 +53,7 @@ int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
if (THREAD_GETMEM(self, p_canceled) if (THREAD_GETMEM(self, p_canceled)
&& THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) { && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) {
/* Remove ourselves from the waiting queue if we're still on it */ /* Remove ourselves from the waiting queue if we're still on it */
__pthread_lock(&cond->__c_lock); __pthread_lock(&cond->__c_lock, self);
remove_from_queue(&cond->__c_waiting, self); remove_from_queue(&cond->__c_waiting, self);
__pthread_unlock(&cond->__c_lock); __pthread_unlock(&cond->__c_lock);
pthread_exit(PTHREAD_CANCELED); pthread_exit(PTHREAD_CANCELED);
@ -72,7 +72,7 @@ pthread_cond_timedwait_relative(pthread_cond_t *cond,
sigjmp_buf jmpbuf; sigjmp_buf jmpbuf;
/* Wait on the condition */ /* Wait on the condition */
__pthread_lock(&cond->__c_lock); __pthread_lock(&cond->__c_lock, self);
enqueue(&cond->__c_waiting, self); enqueue(&cond->__c_waiting, self);
__pthread_unlock(&cond->__c_lock); __pthread_unlock(&cond->__c_lock);
pthread_mutex_unlock(mutex); pthread_mutex_unlock(mutex);
@ -107,7 +107,7 @@ pthread_cond_timedwait_relative(pthread_cond_t *cond,
/* This is a cancellation point */ /* This is a cancellation point */
if (THREAD_GETMEM(self, p_canceled) if (THREAD_GETMEM(self, p_canceled)
&& THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) { && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) {
__pthread_lock(&cond->__c_lock); __pthread_lock(&cond->__c_lock, self);
remove_from_queue(&cond->__c_waiting, self); remove_from_queue(&cond->__c_waiting, self);
__pthread_unlock(&cond->__c_lock); __pthread_unlock(&cond->__c_lock);
pthread_mutex_lock(mutex); pthread_mutex_lock(mutex);
@ -115,7 +115,7 @@ pthread_cond_timedwait_relative(pthread_cond_t *cond,
} }
/* If not signaled: also remove ourselves and return an error code */ /* If not signaled: also remove ourselves and return an error code */
if (THREAD_GETMEM(self, p_signal) == 0) { if (THREAD_GETMEM(self, p_signal) == 0) {
__pthread_lock(&cond->__c_lock); __pthread_lock(&cond->__c_lock, self);
remove_from_queue(&cond->__c_waiting, self); remove_from_queue(&cond->__c_waiting, self);
__pthread_unlock(&cond->__c_lock); __pthread_unlock(&cond->__c_lock);
pthread_mutex_lock(mutex); pthread_mutex_lock(mutex);
@ -147,7 +147,7 @@ int pthread_cond_signal(pthread_cond_t *cond)
{ {
pthread_descr th; pthread_descr th;
__pthread_lock(&cond->__c_lock); __pthread_lock(&cond->__c_lock, NULL);
th = dequeue(&cond->__c_waiting); th = dequeue(&cond->__c_waiting);
__pthread_unlock(&cond->__c_lock); __pthread_unlock(&cond->__c_lock);
if (th != NULL) restart(th); if (th != NULL) restart(th);
@ -158,7 +158,7 @@ int pthread_cond_broadcast(pthread_cond_t *cond)
{ {
pthread_descr tosignal, th; pthread_descr tosignal, th;
__pthread_lock(&cond->__c_lock); __pthread_lock(&cond->__c_lock, NULL);
/* Copy the current state of the waiting queue and empty it */ /* Copy the current state of the waiting queue and empty it */
tosignal = cond->__c_waiting; tosignal = cond->__c_waiting;
cond->__c_waiting = NULL; cond->__c_waiting = NULL;

View File

@ -35,7 +35,7 @@ void pthread_exit(void * retval)
__pthread_perform_cleanup(); __pthread_perform_cleanup();
__pthread_destroy_specifics(); __pthread_destroy_specifics();
/* Store return value */ /* Store return value */
__pthread_lock(THREAD_GETMEM(self, p_lock)); __pthread_lock(THREAD_GETMEM(self, p_lock), self);
THREAD_SETMEM(self, p_retval, retval); THREAD_SETMEM(self, p_retval, retval);
/* Say that we've terminated */ /* Say that we've terminated */
THREAD_SETMEM(self, p_terminated, 1); THREAD_SETMEM(self, p_terminated, 1);
@ -65,7 +65,7 @@ int pthread_join(pthread_t thread_id, void ** thread_return)
pthread_handle handle = thread_handle(thread_id); pthread_handle handle = thread_handle(thread_id);
pthread_descr th; pthread_descr th;
__pthread_lock(&handle->h_lock); __pthread_lock(&handle->h_lock, self);
if (invalid_handle(handle, thread_id)) { if (invalid_handle(handle, thread_id)) {
__pthread_unlock(&handle->h_lock); __pthread_unlock(&handle->h_lock);
return ESRCH; return ESRCH;
@ -91,7 +91,7 @@ int pthread_join(pthread_t thread_id, void ** thread_return)
th->p_joining = NULL; th->p_joining = NULL;
pthread_exit(PTHREAD_CANCELED); pthread_exit(PTHREAD_CANCELED);
} }
__pthread_lock(&handle->h_lock); __pthread_lock(&handle->h_lock, self);
} }
/* Get return value */ /* Get return value */
if (thread_return != NULL) *thread_return = th->p_retval; if (thread_return != NULL) *thread_return = th->p_retval;
@ -114,7 +114,7 @@ int pthread_detach(pthread_t thread_id)
pthread_handle handle = thread_handle(thread_id); pthread_handle handle = thread_handle(thread_id);
pthread_descr th; pthread_descr th;
__pthread_lock(&handle->h_lock); __pthread_lock(&handle->h_lock, NULL);
if (invalid_handle(handle, thread_id)) { if (invalid_handle(handle, thread_id)) {
__pthread_unlock(&handle->h_lock); __pthread_unlock(&handle->h_lock);
return ESRCH; return ESRCH;

View File

@ -417,7 +417,7 @@ static void pthread_free(pthread_descr th)
ASSERT(th->p_exited); ASSERT(th->p_exited);
/* Make the handle invalid */ /* Make the handle invalid */
handle = thread_handle(th->p_tid); handle = thread_handle(th->p_tid);
__pthread_lock(&handle->h_lock); __pthread_lock(&handle->h_lock, NULL);
handle->h_descr = NULL; handle->h_descr = NULL;
handle->h_bottom = (char *)(-1L); handle->h_bottom = (char *)(-1L);
__pthread_unlock(&handle->h_lock); __pthread_unlock(&handle->h_lock);
@ -452,7 +452,7 @@ static void pthread_exited(pid_t pid)
th->p_nextlive->p_prevlive = th->p_prevlive; th->p_nextlive->p_prevlive = th->p_prevlive;
th->p_prevlive->p_nextlive = th->p_nextlive; th->p_prevlive->p_nextlive = th->p_nextlive;
/* Mark thread as exited, and if detached, free its resources */ /* Mark thread as exited, and if detached, free its resources */
__pthread_lock(th->p_lock); __pthread_lock(th->p_lock, NULL);
th->p_exited = 1; th->p_exited = 1;
detached = th->p_detached; detached = th->p_detached;
__pthread_unlock(th->p_lock); __pthread_unlock(th->p_lock);
@ -494,7 +494,7 @@ static void pthread_handle_free(pthread_t th_id)
pthread_handle handle = thread_handle(th_id); pthread_handle handle = thread_handle(th_id);
pthread_descr th; pthread_descr th;
__pthread_lock(&handle->h_lock); __pthread_lock(&handle->h_lock, NULL);
if (invalid_handle(handle, th_id)) { if (invalid_handle(handle, th_id)) {
/* pthread_reap_children has deallocated the thread already, /* pthread_reap_children has deallocated the thread already,
nothing needs to be done */ nothing needs to be done */

View File

@ -81,7 +81,7 @@ int __pthread_mutex_lock(pthread_mutex_t * mutex)
switch(mutex->__m_kind) { switch(mutex->__m_kind) {
case PTHREAD_MUTEX_FAST_NP: case PTHREAD_MUTEX_FAST_NP:
__pthread_lock(&mutex->__m_lock); __pthread_lock(&mutex->__m_lock, NULL);
return 0; return 0;
case PTHREAD_MUTEX_RECURSIVE_NP: case PTHREAD_MUTEX_RECURSIVE_NP:
self = thread_self(); self = thread_self();
@ -89,14 +89,14 @@ int __pthread_mutex_lock(pthread_mutex_t * mutex)
mutex->__m_count++; mutex->__m_count++;
return 0; return 0;
} }
__pthread_lock(&mutex->__m_lock); __pthread_lock(&mutex->__m_lock, self);
mutex->__m_owner = self; mutex->__m_owner = self;
mutex->__m_count = 0; mutex->__m_count = 0;
return 0; return 0;
case PTHREAD_MUTEX_ERRORCHECK_NP: case PTHREAD_MUTEX_ERRORCHECK_NP:
self = thread_self(); self = thread_self();
if (mutex->__m_owner == self) return EDEADLK; if (mutex->__m_owner == self) return EDEADLK;
__pthread_lock(&mutex->__m_lock); __pthread_lock(&mutex->__m_lock, self);
mutex->__m_owner = self; mutex->__m_owner = self;
return 0; return 0;
default: default:

View File

@ -394,7 +394,7 @@ int pthread_setschedparam(pthread_t thread, int policy,
pthread_handle handle = thread_handle(thread); pthread_handle handle = thread_handle(thread);
pthread_descr th; pthread_descr th;
__pthread_lock(&handle->h_lock); __pthread_lock(&handle->h_lock, NULL);
if (invalid_handle(handle, thread)) { if (invalid_handle(handle, thread)) {
__pthread_unlock(&handle->h_lock); __pthread_unlock(&handle->h_lock);
return ESRCH; return ESRCH;
@ -417,7 +417,7 @@ int pthread_getschedparam(pthread_t thread, int *policy,
pthread_handle handle = thread_handle(thread); pthread_handle handle = thread_handle(thread);
int pid, pol; int pid, pol;
__pthread_lock(&handle->h_lock); __pthread_lock(&handle->h_lock, NULL);
if (invalid_handle(handle, thread)) { if (invalid_handle(handle, thread)) {
__pthread_unlock(&handle->h_lock); __pthread_unlock(&handle->h_lock);
return ESRCH; return ESRCH;

View File

@ -57,7 +57,7 @@ pthread_rwlock_destroy (pthread_rwlock_t *rwlock)
int readers; int readers;
_pthread_descr writer; _pthread_descr writer;
__pthread_lock (&rwlock->__rw_lock); __pthread_lock (&rwlock->__rw_lock, NULL);
readers = rwlock->__rw_readers; readers = rwlock->__rw_readers;
writer = rwlock->__rw_writer; writer = rwlock->__rw_writer;
__pthread_unlock (&rwlock->__rw_lock); __pthread_unlock (&rwlock->__rw_lock);
@ -72,11 +72,11 @@ pthread_rwlock_destroy (pthread_rwlock_t *rwlock)
int int
pthread_rwlock_rdlock (pthread_rwlock_t *rwlock) pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
{ {
pthread_descr self; pthread_descr self = NULL;
while (1) while (1)
{ {
__pthread_lock (&rwlock->__rw_lock); __pthread_lock (&rwlock->__rw_lock, self);
if (rwlock->__rw_writer == NULL if (rwlock->__rw_writer == NULL
|| (rwlock->__rw_kind == PTHREAD_RWLOCK_PREFER_READER_NP || (rwlock->__rw_kind == PTHREAD_RWLOCK_PREFER_READER_NP
&& rwlock->__rw_readers != 0)) && rwlock->__rw_readers != 0))
@ -84,7 +84,8 @@ pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
break; break;
/* Suspend ourselves, then try again */ /* Suspend ourselves, then try again */
self = thread_self (); if (self == NULL)
self = thread_self ();
enqueue (&rwlock->__rw_read_waiting, self); enqueue (&rwlock->__rw_read_waiting, self);
__pthread_unlock (&rwlock->__rw_lock); __pthread_unlock (&rwlock->__rw_lock);
suspend (self); /* This is not a cancellation point */ suspend (self); /* This is not a cancellation point */
@ -102,7 +103,7 @@ pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
{ {
int result = EBUSY; int result = EBUSY;
__pthread_lock (&rwlock->__rw_lock); __pthread_lock (&rwlock->__rw_lock, NULL);
if (rwlock->__rw_writer == NULL if (rwlock->__rw_writer == NULL
|| (rwlock->__rw_kind == PTHREAD_RWLOCK_PREFER_READER_NP || (rwlock->__rw_kind == PTHREAD_RWLOCK_PREFER_READER_NP
&& rwlock->__rw_readers != 0)) && rwlock->__rw_readers != 0))
@ -123,7 +124,7 @@ pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
while(1) while(1)
{ {
__pthread_lock (&rwlock->__rw_lock); __pthread_lock (&rwlock->__rw_lock, self);
if (rwlock->__rw_readers == 0 && rwlock->__rw_writer == NULL) if (rwlock->__rw_readers == 0 && rwlock->__rw_writer == NULL)
{ {
rwlock->__rw_writer = self; rwlock->__rw_writer = self;
@ -144,7 +145,7 @@ pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
{ {
int result = EBUSY; int result = EBUSY;
__pthread_lock (&rwlock->__rw_lock); __pthread_lock (&rwlock->__rw_lock, NULL);
if (rwlock->__rw_readers == 0 && rwlock->__rw_writer == NULL) if (rwlock->__rw_readers == 0 && rwlock->__rw_writer == NULL)
{ {
rwlock->__rw_writer = thread_self (); rwlock->__rw_writer = thread_self ();
@ -162,7 +163,7 @@ pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
pthread_descr torestart; pthread_descr torestart;
pthread_descr th; pthread_descr th;
__pthread_lock (&rwlock->__rw_lock); __pthread_lock (&rwlock->__rw_lock, NULL);
if (rwlock->__rw_writer != NULL) if (rwlock->__rw_writer != NULL)
{ {
/* Unlocking a write lock. */ /* Unlocking a write lock. */

View File

@ -40,15 +40,14 @@ int sem_init(sem_t *sem, int pshared, unsigned int value)
int sem_wait(sem_t * sem) int sem_wait(sem_t * sem)
{ {
volatile pthread_descr self; volatile pthread_descr self = thread_self();
__pthread_lock((struct _pthread_fastlock *) &sem->sem_lock); __pthread_lock((struct _pthread_fastlock *) &sem->sem_lock, self);
if (sem->sem_value > 0) { if (sem->sem_value > 0) {
sem->sem_value--; sem->sem_value--;
__pthread_unlock((struct _pthread_fastlock *) &sem->sem_lock); __pthread_unlock((struct _pthread_fastlock *) &sem->sem_lock);
return 0; return 0;
} }
self = thread_self();
enqueue(&sem->sem_waiting, self); enqueue(&sem->sem_waiting, self);
/* Wait for sem_post or cancellation */ /* Wait for sem_post or cancellation */
__pthread_unlock((struct _pthread_fastlock *) &sem->sem_lock); __pthread_unlock((struct _pthread_fastlock *) &sem->sem_lock);
@ -57,7 +56,7 @@ int sem_wait(sem_t * sem)
if (THREAD_GETMEM(self, p_canceled) if (THREAD_GETMEM(self, p_canceled)
&& THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) { && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) {
/* Remove ourselves from the waiting list if we're still on it */ /* Remove ourselves from the waiting list if we're still on it */
__pthread_lock((struct _pthread_fastlock *) &sem->sem_lock); __pthread_lock((struct _pthread_fastlock *) &sem->sem_lock, self);
remove_from_queue(&sem->sem_waiting, self); remove_from_queue(&sem->sem_waiting, self);
__pthread_unlock((struct _pthread_fastlock *) &sem->sem_lock); __pthread_unlock((struct _pthread_fastlock *) &sem->sem_lock);
pthread_exit(PTHREAD_CANCELED); pthread_exit(PTHREAD_CANCELED);
@ -70,7 +69,7 @@ int sem_trywait(sem_t * sem)
{ {
int retval; int retval;
__pthread_lock((struct _pthread_fastlock *) &sem->sem_lock); __pthread_lock((struct _pthread_fastlock *) &sem->sem_lock, NULL);
if (sem->sem_value == 0) { if (sem->sem_value == 0) {
errno = EAGAIN; errno = EAGAIN;
retval = -1; retval = -1;
@ -88,7 +87,7 @@ int sem_post(sem_t * sem)
struct pthread_request request; struct pthread_request request;
if (THREAD_GETMEM(self, p_in_sighandler) == NULL) { if (THREAD_GETMEM(self, p_in_sighandler) == NULL) {
__pthread_lock((struct _pthread_fastlock *) &sem->sem_lock); __pthread_lock((struct _pthread_fastlock *) &sem->sem_lock, self);
if (sem->sem_waiting == NULL) { if (sem->sem_waiting == NULL) {
if (sem->sem_value >= SEM_VALUE_MAX) { if (sem->sem_value >= SEM_VALUE_MAX) {
/* Overflow */ /* Overflow */

View File

@ -53,7 +53,7 @@ int pthread_kill(pthread_t thread, int signo)
pthread_handle handle = thread_handle(thread); pthread_handle handle = thread_handle(thread);
int pid; int pid;
__pthread_lock(&handle->h_lock); __pthread_lock(&handle->h_lock, NULL);
if (invalid_handle(handle, thread)) { if (invalid_handle(handle, thread)) {
__pthread_unlock(&handle->h_lock); __pthread_unlock(&handle->h_lock);
return ESRCH; return ESRCH;

View File

@ -36,17 +36,18 @@
This is safe because there are no concurrent __pthread_unlock This is safe because there are no concurrent __pthread_unlock
operations -- only the thread that locked the mutex can unlock it. */ operations -- only the thread that locked the mutex can unlock it. */
void __pthread_lock(struct _pthread_fastlock * lock) void internal_function __pthread_lock(struct _pthread_fastlock * lock,
pthread_descr self)
{ {
long oldstatus, newstatus; long oldstatus, newstatus;
pthread_descr self = NULL;
do { do {
oldstatus = lock->__status; oldstatus = lock->__status;
if (oldstatus == 0) { if (oldstatus == 0) {
newstatus = 1; newstatus = 1;
} else { } else {
self = thread_self(); if (self == NULL)
self = thread_self();
newstatus = (long) self; newstatus = (long) self;
} }
if (self != NULL) if (self != NULL)
@ -56,18 +57,7 @@ void __pthread_lock(struct _pthread_fastlock * lock)
if (oldstatus != 0) suspend(self); if (oldstatus != 0) suspend(self);
} }
int __pthread_trylock(struct _pthread_fastlock * lock) void internal_function __pthread_unlock(struct _pthread_fastlock * lock)
{
long oldstatus;
do {
oldstatus = lock->__status;
if (oldstatus != 0) return EBUSY;
} while(! compare_and_swap(&lock->__status, 0, 1, &lock->__spinlock));
return 0;
}
void __pthread_unlock(struct _pthread_fastlock * lock)
{ {
long oldstatus; long oldstatus;
pthread_descr thr, * ptr, * maxptr; pthread_descr thr, * ptr, * maxptr;

View File

@ -1,5 +1,5 @@
/* Internal function for converting integers to ASCII. /* Internal function for converting integers to ASCII.
Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc. Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -57,4 +57,24 @@ _itoa_word (unsigned long value, char *buflim,
return bp; return bp;
} }
static inline char * __attribute__ ((unused))
_fitoa_word (unsigned long value, char *buf, unsigned int base, int upper_case)
{
char tmpbuf[sizeof (value) * 4]; /* Worst case length: base 2. */
char *cp = _itoa_word (value, tmpbuf + sizeof (value) * 4, base, upper_case);
while (cp < tmpbuf + sizeof (value) * 4)
*buf++ = *cp++;
return buf;
}
static inline char * __attribute__ ((unused))
_fitoa (unsigned long long value, char *buf, unsigned int base, int upper_case)
{
char tmpbuf[sizeof (value) * 4]; /* Worst case length: base 2. */
char *cp = _itoa (value, tmpbuf + sizeof (value) * 4, base, upper_case);
while (cp < tmpbuf + sizeof (value) * 4)
*buf++ = *cp++;
return buf;
}
#endif /* itoa.h */ #endif /* itoa.h */

View File

@ -26,6 +26,8 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio-common/_itoa.h>
char *__ttyname = NULL; char *__ttyname = NULL;
static char * getttyname __P ((const char *dev, int fd, dev_t mydev, static char * getttyname __P ((const char *dev, int fd, dev_t mydev,
@ -104,6 +106,9 @@ char *
ttyname (fd) ttyname (fd)
int fd; int fd;
{ {
static char *buf;
static size_t buflen = 0;
char procname[30];
struct stat st, st1; struct stat st, st1;
int dostat = 0; int dostat = 0;
char *name; char *name;
@ -112,6 +117,23 @@ ttyname (fd)
if (!__isatty (fd)) if (!__isatty (fd))
return NULL; return NULL;
/* We try using the /proc filesystem. */
*_fitoa_word (fd, __stpcpy (procname, "/proc/self/fd/"), 10, 0) = '\0';
if (buflen == 0)
{
buflen = 4095;
buf = (char *) malloc (buflen + 1);
if (buf == NULL)
{
buflen = 0;
return NULL;
}
}
if (__readlink (procname, buf, buflen) != -1)
return buf;
if (fstat (fd, &st) < 0) if (fstat (fd, &st) < 0)
return NULL; return NULL;

View File

@ -26,6 +26,8 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio-common/_itoa.h>
static int getttyname_r __P ((int fd, char *buf, size_t buflen, static int getttyname_r __P ((int fd, char *buf, size_t buflen,
dev_t mydev, ino_t myino, int save, dev_t mydev, ino_t myino, int save,
int *dostat)) internal_function; int *dostat)) internal_function;
@ -102,6 +104,7 @@ __ttyname_r (fd, buf, buflen)
char *buf; char *buf;
size_t buflen; size_t buflen;
{ {
char procname[30];
struct stat st, st1; struct stat st, st1;
int dostat = 0; int dostat = 0;
int save = errno; int save = errno;
@ -127,6 +130,18 @@ __ttyname_r (fd, buf, buflen)
return ENOTTY; return ENOTTY;
} }
/* We try using the /proc filesystem. */
*_fitoa_word (fd, __stpcpy (procname, "/proc/self/fd/"), 10, 0) = '\0';
ret = __readlink (procname, buf, buflen - 1);
if (ret != -1)
return 0;
if (errno == ENAMETOOLONG)
{
__set_errno (ERANGE);
return ERANGE;
}
if (fstat (fd, &st) < 0) if (fstat (fd, &st) < 0)
return errno; return errno;