diff options
Diffstat (limited to 'sysdeps/posix')
-rw-r--r-- | sysdeps/posix/getaddrinfo.c | 10 | ||||
-rw-r--r-- | sysdeps/posix/rename.c | 2 | ||||
-rw-r--r-- | sysdeps/posix/sigwait.c | 92 | ||||
-rw-r--r-- | sysdeps/posix/ttyname_r.c | 30 |
4 files changed, 121 insertions, 13 deletions
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index 32b050ecf4..90af24fb61 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -287,6 +287,10 @@ static int gaih_inet(const char *name, const struct gaih_service *service, struct gaih_servtuple *st2; struct gaih_addrtuple *at2 = at; int j; +#ifndef MAXHOSTNAMELEN +# define MAXHOSTNAMELEN 128 +#endif /* MAXHOSTNAMELEN */ + char buffer[MAXHOSTNAMELEN]; while(at2) { if (req->ai_flags & AI_CANONNAME) { @@ -308,9 +312,9 @@ static int gaih_inet(const char *name, const struct gaih_service *service, sizeof(struct in_addr), at2->family); #endif /* HOSTTABLE */ - if (!h) { - c = inet_ntop(at2->family, at2->addr, NULL, 0); - } else + if (!h) + c = inet_ntop(at2->family, at2->addr, buffer, sizeof(buffer)); + else c = h->h_name; if (!c) { diff --git a/sysdeps/posix/rename.c b/sysdeps/posix/rename.c index c318081bac..b8d31f900c 100644 --- a/sysdeps/posix/rename.c +++ b/sysdeps/posix/rename.c @@ -31,7 +31,7 @@ rename (old, new) { if (errno == EEXIST) { - errno = save; + __set_errno (save); /* Race condition, required for 1003.1 conformance. */ if (__unlink (new) < 0 || __link (old, new) < 0) diff --git a/sysdeps/posix/sigwait.c b/sysdeps/posix/sigwait.c new file mode 100644 index 0000000000..0cd5f80fda --- /dev/null +++ b/sysdeps/posix/sigwait.c @@ -0,0 +1,92 @@ +/* sigwait - implementation of sigwait function from POSIX.1c. + Copyright (C) 1996 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <assert.h> +#include <errno.h> +#include <signal.h> + + +/* This is our dummy signal handler we use here. */ +static void ignore_signal (int sig); + +/* Place where to remember which signal we got. Please note that this + implementation cannot be used for the threaded libc. The + libpthread must provide an own version. */ +static int was_sig; + + +int +__sigwait (const sigset_t *set, int *sig) +{ + sigset_t tmp_mask; + struct sigaction saved[NSIG]; + struct sigaction action; + int save_errno; + int this; + + /* Prepare set. */ + sigfillset (&tmp_mask); + + /* Unblock all signals in the SET and register our nice handler. */ + action.sa_handler = ignore_signal; + action.sa_flags = 0; + sigfillset (&action.sa_mask); /* Block all signals for handler. */ + + /* Make sure we recognize error conditions by setting WAS_SIG to a + value which does not describe a legal signal number. */ + was_sig = -1; + + for (this = 0; this < NSIG; ++this) + if (sigismember (set, this)) + { + /* Unblock this signal. */ + sigdelset (&tmp_mask, this); + + /* Register temporary action handler. */ + if (sigaction (this, &action, &saved[this]) != 0) + goto restore_handler; + } + + /* Now we can wait for signals. */ + sigsuspend (&tmp_mask); + + restore_handler: + save_errno = errno; + + while (--this >= 0) + if (sigismember (set, this)) + /* We ignore errors here since we must restore all handlers. */ + sigaction (this, &saved[this], NULL); + + __set_errno (save_errno); + + /* Store the result and return. */ + *sig = was_sig; + return was_sig == -1 ? -1 : 0; +} +weak_alias (__sigwait, sigwait) + + +static void +ignore_signal (int sig) +{ + /* Remember the signal. */ + was_sig = sig; +} diff --git a/sysdeps/posix/ttyname_r.c b/sysdeps/posix/ttyname_r.c index d7f6026d8a..5b62826a19 100644 --- a/sysdeps/posix/ttyname_r.c +++ b/sysdeps/posix/ttyname_r.c @@ -36,7 +36,7 @@ int __ttyname_r (fd, buf, buflen) int fd; char *buf; - int buflen; + size_t buflen; { static const char dev[] = "/dev"; struct stat st; @@ -50,21 +50,24 @@ __ttyname_r (fd, buf, buflen) the loop. */ if (buflen < (int) (sizeof (dev) + 1)) { - __set_errno (EINVAL); - return -1; + __set_errno (ERANGE); + return ERANGE; } if (!__isatty (fd)) - return -1; + { + __set_errno (ENOTTY); + return ENOTTY; + } if (fstat (fd, &st) < 0) - return -1; + return errno; mydev = st.st_dev; myino = st.st_ino; dirstream = opendir (dev); if (dirstream == NULL) - return -1; + return errno; /* Prepare the result buffer. */ memcpy (buf, dev, sizeof (dev) - 1); @@ -75,9 +78,16 @@ __ttyname_r (fd, buf, buflen) if ((ino_t) d->d_fileno == myino) { char *cp; + size_t needed = _D_EXACT_NAMLEN (d) + 1; + + if (needed > buflen) + { + (void) closedir (dirstream); + __set_errno (ERANGE); + return ERANGE; + } - cp = __stpncpy (&buf[sizeof (dev)], d->d_name, - MIN ((int) (_D_EXACT_NAMLEN (d) + 1), buflen)); + cp = __stpncpy (&buf[sizeof (dev)], d->d_name, needed); cp[0] = '\0'; if (stat (buf, &st) == 0 && st.st_dev == mydev) @@ -90,6 +100,8 @@ __ttyname_r (fd, buf, buflen) (void) closedir (dirstream); __set_errno (save); - return -1; + /* 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; } weak_alias (__ttyname_r, ttyname_r) |