diff options
author | Miles Bader <miles@gnu.org> | 1996-06-07 20:32:20 +0000 |
---|---|---|
committer | Miles Bader <miles@gnu.org> | 1996-06-07 20:32:20 +0000 |
commit | 500590c7675c714ea700f24c402ef4fc2166cc4c (patch) | |
tree | 1bfa215031ccec5a41d5266d277751584fb997c4 /login | |
parent | 64a921419da5d602cf8004d4d677b2419420180e (diff) | |
download | glibc-500590c7675c714ea700f24c402ef4fc2166cc4c.tar.gz glibc-500590c7675c714ea700f24c402ef4fc2166cc4c.tar.xz glibc-500590c7675c714ea700f24c402ef4fc2166cc4c.zip |
(tty_name): New function. (login): Use it. (PATH_MAX): MACRO removed. <stdlib.h>: New include.
Diffstat (limited to 'login')
-rw-r--r-- | login/login.c | 71 |
1 files changed, 63 insertions, 8 deletions
diff --git a/login/login.c b/login/login.c index 446b6b927b..ede02d7938 100644 --- a/login/login.c +++ b/login/login.c @@ -21,27 +21,79 @@ Boston, MA 02111-1307, USA. */ #include <limits.h> #include <string.h> #include <unistd.h> +#include <stdlib.h> #include <utmp.h> + +/* Return the result of ttyname in the buffer pointed to by TTY, which should + be of length BUF_LEN. If it is too long to fit in this buffer, a + sufficiently long buffer is allocated using malloc, and returned in TTY. + 0 is returned upon success, -1 otherwise. */ +static int +tty_name (int fd, char **tty, size_t buf_len) +{ + int rv; /* Return value. 0 = success. */ + char *buf = *tty; /* Buffer for ttyname, initially the user's. */ -/* XXX used for tty name array in login. */ -#ifndef PATH_MAX -#define PATH_MAX 1024 -#endif + for (;;) + { + char *new_buf; + + if (buf_len) + { + rv = ttyname_r (fd, buf, buf_len); + + if (rv < 0 || memchr (buf, '\0', buf_len)) + /* We either got an error, or we succeeded and the returned name fit + in the buffer. */ + break; + /* Try again with a longer buffer. */ + buf_len += buf_len; /* Double it */ + } + else + /* No initial buffer; start out by mallocing one. */ + buf_len = 128; /* First time guess. */ + + if (buf != *tty) + /* We've already malloced another buffer at least once. */ + new_buf = realloc (buf, buf_len); + else + new_buf = malloc (buf_len); + if (! new_buf) + { + rv = -1; + errno = ENOMEM; + break; + } + } + + if (rv == 0) + *tty = buf; /* Return buffer to the user. */ + else if (buf != *tty) + free (buf); /* Free what we malloced when returning an error. */ + + return rv; +} + void login (const struct utmp *ut) { - char tty[PATH_MAX + UT_LINESIZE]; +#ifdef PATH_MAX + char _tty[PATH_MAX + UT_LINESIZE]; +#else + char _tty[512 + UT_LINESIZE]; +#endif + char *tty = _tty; int found_tty; const char *ttyp; struct utmp_data data; /* Seek tty. */ - found_tty = ttyname_r (STDIN_FILENO, tty, sizeof tty); + found_tty = tty_name (STDIN_FILENO, &tty, sizeof (_tty)); if (found_tty < 0) - found_tty = ttyname_r (STDOUT_FILENO, tty, sizeof tty); + found_tty = tty_name (STDOUT_FILENO, &tty, sizeof (_tty)); if (found_tty < 0) - found_tty = ttyname_r (STDERR_FILENO, tty, sizeof tty); + found_tty = tty_name (STDERR_FILENO, &tty, sizeof (_tty)); if (found_tty >= 0) { @@ -78,6 +130,9 @@ login (const struct utmp *ut) /* Close UTMP file. */ endutent_r (&data); } + + if (tty != _tty) + free (tty); /* Free buffer malloced by tty_name. */ } /* Update the WTMP file. Here we have to add a new entry. */ |