diff options
Diffstat (limited to 'sysdeps/posix')
-rw-r--r-- | sysdeps/posix/sigignore.c | 36 | ||||
-rw-r--r-- | sysdeps/posix/sigset.c | 66 | ||||
-rw-r--r-- | sysdeps/posix/ttyname.c | 79 | ||||
-rw-r--r-- | sysdeps/posix/ttyname_r.c | 128 |
4 files changed, 254 insertions, 55 deletions
diff --git a/sysdeps/posix/sigignore.c b/sysdeps/posix/sigignore.c new file mode 100644 index 0000000000..f24aca70c9 --- /dev/null +++ b/sysdeps/posix/sigignore.c @@ -0,0 +1,36 @@ +/* Set the disposition of SIG to SIG_IGN. + Copyright (C) 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. + + 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 <errno.h> +#include <signal.h> + +int +sigignore (sig) + int sig; +{ + struct sigaction act; + + act.sa_handler = SIG_IGN; + if (__sigemptyset (&act.sa_mask) < 0) + return -1; + act.sa_flags = 0; + + return __sigaction (sig, &act, NULL); +} diff --git a/sysdeps/posix/sigset.c b/sysdeps/posix/sigset.c new file mode 100644 index 0000000000..4bd3bf38c8 --- /dev/null +++ b/sysdeps/posix/sigset.c @@ -0,0 +1,66 @@ +/* Copyright (C) 1998 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 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 <errno.h> +#include <signal.h> + + +/* Set the disposition for SIG. */ +__sighandler_t +sigset (sig, disp) + int sig; + __sighandler_t disp; +{ + struct sigaction act, oact; + + /* Handle SIG_HOLD first. */ + if (disp == SIG_HOLD) + { + sigset_t set; + + /* Retrieve current signal set. */ + if (__sigprocmask (SIG_SETMASK, NULL, &set) < 0) + return SIG_ERR; + + /* Add the specified signal. */ + if (sigaddset (&set, sig) < 0) + return SIG_ERR; + + /* Set the new mask. */ + if (__sigprocmask (SIG_SETMASK, &set, NULL) < 0) + return SIG_ERR; + + return SIG_HOLD; + } + + /* Check signal extents to protect __sigismember. */ + if (disp == SIG_ERR || sig < 1 || sig >= NSIG) + { + __set_errno (EINVAL); + return SIG_ERR; + } + + act.sa_handler = disp; + if (__sigemptyset (&act.sa_mask) < 0) + return SIG_ERR; + act.sa_flags = 0; + if (__sigaction (sig, &act, &oact) < 0) + return SIG_ERR; + + return oact.sa_handler; +} diff --git a/sysdeps/posix/ttyname.c b/sysdeps/posix/ttyname.c index a4e4f30526..6a046ea652 100644 --- a/sysdeps/posix/ttyname.c +++ b/sysdeps/posix/ttyname.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1992, 1993, 1996, 1997 Free Software Foundation, Inc. +/* Copyright (C) 1991, 92, 93, 96, 97, 98 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 @@ -28,36 +28,34 @@ char *__ttyname = NULL; -/* Return the pathname of the terminal FD is open on, or NULL on errors. - The returned storage is good only until the next call to this function. */ -char * -ttyname (fd) +static char * getttyname __P ((int fd, dev_t mydev, ino_t myino, + int save, int *dostat)) internal_function; + +static char * +internal_function +getttyname (fd, mydev, myino, save, dostat) int fd; + dev_t mydev; + ino_t myino; + int save; + int *dostat; { static const char dev[] = "/dev"; static char *name; static size_t namelen = 0; struct stat st; - dev_t mydev; - ino_t myino; DIR *dirstream; struct dirent *d; - int save = errno; - - if (!__isatty (fd)) - return NULL; - - if (fstat (fd, &st) < 0) - return NULL; - mydev = st.st_dev; - myino = st.st_ino; dirstream = opendir (dev); if (dirstream == NULL) - return NULL; + { + *dostat = -1; + return NULL; + } while ((d = readdir (dirstream)) != NULL) - if ((ino_t) d->d_fileno == myino) + if ((ino_t) d->d_fileno == myino || *dostat) { size_t dlen = _D_ALLOC_NAMLEN (d); if (sizeof (dev) + dlen > namelen) @@ -67,6 +65,7 @@ ttyname (fd) name = malloc (namelen); if (! name) { + *dostat = -1; /* Perhaps it helps to free the directory stream buffer. */ (void) closedir (dirstream); return NULL; @@ -74,7 +73,13 @@ ttyname (fd) *((char *) __mempcpy (name, dev, sizeof (dev) - 1)) = '/'; } (void) __mempcpy (&name[sizeof (dev)], d->d_name, dlen); - if (stat (name, &st) == 0 && st.st_dev == mydev) + if (stat (name, &st) == 0 +#ifdef _STATBUF_ST_RDEV + && S_ISCHR (st.st_mode) && st.st_rdev == mydev +#else + && (ino_t) d->d_fileno == myino && st.st_dev == mydev +#endif + ) { (void) closedir (dirstream); __ttyname = name; @@ -87,3 +92,39 @@ ttyname (fd) __set_errno (save); return NULL; } + +/* Return the pathname of the terminal FD is open on, or NULL on errors. + The returned storage is good only until the next call to this function. */ +char * +ttyname (fd) + int fd; +{ + struct stat st; + int dostat = 0; + char *name; + int save = errno; + + if (!__isatty (fd)) + return NULL; + + if (fstat (fd, &st) < 0) + return NULL; + +#ifdef _STATBUF_ST_RDEV + name = getttyname (fd, st.st_rdev, st.st_ino, save, &dostat); +#else + name = getttyname (fd, st.st_dev, st.st_ino, save, &dostat); +#endif + + if (!name && dostat != -1) + { + dostat = 1; +#ifdef _STATBUF_ST_RDEV + name = getttyname (fd, st.st_rdev, st.st_ino, save, &dostat); +#else + name = getttyname (fd, st.st_dev, st.st_ino, save, &dostat); +#endif + } + + return name; +} diff --git a/sysdeps/posix/ttyname_r.c b/sysdeps/posix/ttyname_r.c index b3a15d13d1..ad747ad35b 100644 --- a/sysdeps/posix/ttyname_r.c +++ b/sysdeps/posix/ttyname_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 92, 93, 95, 96, 97 Free Software Foundation, Inc. +/* Copyright (C) 1991, 92, 93, 95, 96, 97, 98 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 @@ -30,58 +30,43 @@ # define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif -/* 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 (fd, buf, buflen) +static const char dev[] = "/dev"; + +static int getttyname_r __P ((int fd, char *buf, size_t buflen, + dev_t mydev, ino_t myino, int save, + int *dostat)) internal_function; + +static int +internal_function +getttyname_r (fd, buf, buflen, mydev, myino, save, dostat) int fd; char *buf; size_t buflen; + dev_t mydev; + ino_t myino; + int save; + int *dostat; { - static const char dev[] = "/dev"; struct stat st; - dev_t mydev; - ino_t myino; DIR *dirstream; struct dirent *d; - int save = errno; - - /* Test for the absolute minimal size. This makes life easier inside - the loop. */ - if (buflen < (int) (sizeof (dev) + 1)) - { - __set_errno (ERANGE); - return ERANGE; - } - - if (!__isatty (fd)) - { - __set_errno (ENOTTY); - return ENOTTY; - } - - if (fstat (fd, &st) < 0) - return errno; - mydev = st.st_dev; - myino = st.st_ino; dirstream = opendir (dev); if (dirstream == NULL) - return errno; - - /* Prepare the result buffer. */ - memcpy (buf, dev, sizeof (dev) - 1); - buf[sizeof (dev) - 1] = '/'; - buflen -= sizeof (dev); + { + *dostat = -1; + return errno; + } while ((d = readdir (dirstream)) != NULL) - if ((ino_t) d->d_fileno == myino) + if ((ino_t) d->d_fileno == myino || *dostat) { char *cp; size_t needed = _D_EXACT_NAMLEN (d) + 1; if (needed > buflen) { + *dostat = -1; (void) closedir (dirstream); __set_errno (ERANGE); return ERANGE; @@ -90,7 +75,13 @@ __ttyname_r (fd, buf, buflen) cp = __stpncpy (&buf[sizeof (dev)], d->d_name, needed); cp[0] = '\0'; - if (stat (buf, &st) == 0 && st.st_dev == mydev) + if (stat (buf, &st) == 0 +#ifdef _STATBUF_ST_RDEV + && S_ISCHR (st.st_mode) && st.st_rdev == mydev +#else + && (ino_t) d->d_fileno == myino && st.st_dev == mydev +#endif + ) { (void) closedir (dirstream); __set_errno (save); @@ -104,4 +95,69 @@ __ttyname_r (fd, buf, buflen) 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 (fd, buf, buflen) + int fd; + char *buf; + size_t buflen; +{ + struct stat st; + 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 < (int) (sizeof (dev) + 1)) + { + __set_errno (ERANGE); + return ERANGE; + } + + if (!__isatty (fd)) + { + __set_errno (ENOTTY); + return ENOTTY; + } + + if (fstat (fd, &st) < 0) + return errno; + + /* Prepare the result buffer. */ + memcpy (buf, dev, sizeof (dev) - 1); + buf[sizeof (dev) - 1] = '/'; + buflen -= sizeof (dev); + +#ifdef _STATBUF_ST_RDEV + ret = getttyname_r (fd, buf, buflen, st.st_rdev, st.st_ino, save, + &dostat); +#else + ret = getttyname_r (fd, buf, buflen, st.st_dev, st.st_ino, save, + &dostat); +#endif + + if (ret && dostat != -1) + { + dostat = 1; +#ifdef _STATBUF_ST_RDEV + ret = getttyname_r (fd, buf, buflen, st.st_rdev, st.st_ino, + save, &dostat); +#else + ret = getttyname_r (fd, buf, buflen, st.st_dev, st.st_ino, + save, &dostat); +#endif + } + + return ret; +} + weak_alias (__ttyname_r, ttyname_r) |