threads/76938: include/unistd.h: ttyname_r prototype missing

Craig Rodrigues rodrigc at crodrigues.org
Fri Feb 18 12:40:21 PST 2005


The following reply was made to PR threads/76938; it has been noted by GNATS.

From: Craig Rodrigues <rodrigc at crodrigues.org>
To: freebsd-gnats-submit at freebsd.org
Cc: tmclaugh at sdf.lonestar.org, freebsd-standards at freebsd.org
Subject: Re: threads/76938: include/unistd.h: ttyname_r prototype missing
Date: Fri, 18 Feb 2005 15:30:45 -0500

 The following patch exports ttyname_r() from <unistd.h> and makes it
 conform to the Single Unix Specification:
 http://www.opengroup.org/onlinepubs/009695399/functions/ttyname.html
 
 Can someone with a commit bit take a look at it?  
 
 -- 
 Craig Rodrigues        
 rodrigc at crodrigues.org
 
 
 --- lib/libc/gen/ttyname.3.orig	Thu Feb 17 17:10:20 2005
 +++ lib/libc/gen/ttyname.3	Fri Feb 18 15:10:31 2005
 @@ -37,6 +37,7 @@
  .Os
  .Sh NAME
  .Nm ttyname ,
 +.Nm ttyname_r ,
  .Nm isatty ,
  .Nm ttyslot
  .Nd get name of associated terminal (tty) from file descriptor
 @@ -47,6 +48,8 @@
  .Ft char *
  .Fn ttyname "int fd"
  .Ft int
 +.Fn ttyname_r "int fd" "char *buf" "size_t bufsize"
 +.Ft int
  .Fn isatty "int fd"
  .Ft int
  .Fn ttyslot void
 @@ -80,7 +83,13 @@
  gets the related device name of
  a file descriptor for which
  .Fn isatty
 -is true
 +is true.
 +.Pp
 +.Fn ttyname
 +returns the name stored in a static buffer which will be overwritten
 +on subsequent calls.
 +.Fn ttyname_r
 +takes a buffer and length as arguments to avoid this problem.
  .Pp
  The
  .Fn ttyslot
 @@ -98,12 +107,25 @@
  a
  .Dv NULL
  pointer is returned.
 +The
 +.Fn ttyname_r
 +function returns 0 if successful.  Otherwise an error number is returned.
  .Pp
  The
  .Fn ttyslot
  function
  returns the unit number of the device file if found; otherwise
  the value zero is returned.
 +.Sh ERRORS
 +.Fn ttyname_r
 +may return the following error codes:
 +.Bl -tag -width Er
 +.It Bq Er ENOTTY
 +.Fa fd
 +is not a valid file descriptor.
 +.It Bq Er ERANGE
 +.Fa bufsize
 +is smaller than the length of the string to be returned.
  .Sh FILES
  .Bl -tag -width /etc/ttys -compact
  .It Pa /dev/\(**
 @@ -121,11 +143,6 @@
  function
  appeared in
  .At v7 .
 -.Sh BUGS
 -The
 -.Fn ttyname
 -function leaves its result in an internal static object and returns
 -a pointer to that object.
 -Subsequent calls to
 -.Fn ttyname
 -will modify the same object.
 +.Fn ttyname_r
 +appeared in
 +.Fx 6.0 .
 --- lib/libc/gen/ttyname.c.orig	Thu Feb 17 17:14:32 2005
 +++ lib/libc/gen/ttyname.c	Fri Feb 18 15:20:09 2005
 @@ -48,12 +48,13 @@
  #include <string.h>
  #include <paths.h>
  #include <pthread.h>
 +#include <errno.h>
  #include "un-namespace.h"
  
  #include "libc_private.h"
  
  static char buf[sizeof(_PATH_DEV) + MAXNAMLEN];
 -static char *ttyname_threaded(int fd);
 +static void ttyname_threaded(int fd, char **b);
  static char *ttyname_unthreaded(int fd);
  
  static pthread_mutex_t	ttyname_lock = PTHREAD_MUTEX_INITIALIZER;
 @@ -68,45 +69,41 @@
  	if (__isthreaded == 0)
  		ret = ttyname_unthreaded(fd);
  	else
 -		ret = ttyname_threaded(fd);
 +		ttyname_threaded(fd, &ret);
  	return (ret);
  }
  
 -char *
 +int
  ttyname_r(int fd, char *buf, size_t len)
  {
  	struct stat	sb;
 -	char		*rval;
 -
 -	rval = NULL;
  
  	/* Must be a terminal. */
  	if (!isatty(fd))
 -		return (rval);
 +		return ENOTTY;
  	/* Must be a character device. */
  	if (_fstat(fd, &sb) || !S_ISCHR(sb.st_mode))
 -		return (rval);
 +		return ENOTTY;
  	/* Must have enough room */
  	if (len <= sizeof(_PATH_DEV))
 -		return (rval);
 +		return ERANGE;
  
  	strcpy(buf, _PATH_DEV);
  	devname_r(sb.st_rdev, S_IFCHR,
 -	    buf + strlen(buf), sizeof(buf) - strlen(buf));
 -	return (buf);
 +	    buf + strlen(buf), len - strlen(buf));
 +	return 0;
  }
  
 -static char *
 -ttyname_threaded(int fd)
 +static void
 +ttyname_threaded(int fd, char **b)
  {
 -	char	*buf;
 -
  	if (ttyname_init == 0) {
  		_pthread_mutex_lock(&ttyname_lock);
  		if (ttyname_init == 0) {
  			if (_pthread_key_create(&ttyname_key, free)) {
  				_pthread_mutex_unlock(&ttyname_lock);
 -				return (NULL);
 +				*b = NULL;
 +				return;
  			}
  			ttyname_init = 1;
  		}
 @@ -114,17 +111,19 @@
  	}
  
  	/* Must have thread specific data field to put data */
 -	if ((buf = _pthread_getspecific(ttyname_key)) == NULL) {
 -		if ((buf = malloc(sizeof(_PATH_DEV) + MAXNAMLEN)) != NULL) {
 -			if (_pthread_setspecific(ttyname_key, buf) != 0) {
 -				free(buf);
 -				return (NULL);
 +	if ((*b = _pthread_getspecific(ttyname_key)) == NULL) {
 +		if ((*b = malloc(sizeof(_PATH_DEV) + MAXNAMLEN)) != NULL) {
 +			if (_pthread_setspecific(ttyname_key, *b) != 0) {
 +				free(*b);
 +				*b = NULL;
 +				return;
  			}
  		} else {
 -			return (NULL);
 +			*b = NULL;
 +			return;
  		}
  	}
 -	return (ttyname_r(fd, buf, sizeof(_PATH_DEV) + MAXNAMLEN));
 +	ttyname_r(fd, *b, sizeof(_PATH_DEV) + MAXNAMLEN);
  }
  
  static char *
 --- include/unistd.h.orig	Thu Feb 17 17:37:41 2005
 +++ include/unistd.h	Thu Feb 17 17:38:19 2005
 @@ -365,6 +365,7 @@
  pid_t	 tcgetpgrp(int);
  int	 tcsetpgrp(int, pid_t);
  char	*ttyname(int);
 +int	ttyname_r(int, char *, size_t);
  int	 unlink(const char *);
  ssize_t	 write(int, const void *, size_t);
  
 
 


More information about the freebsd-threads mailing list