| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | /* oslib.c - functions present only in some unix versions. */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-22 19:11:26 -05:00
										 |  |  | /* Copyright (C) 1995,2010 Free Software Foundation, Inc.
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |    This file is part of GNU Bash, the Bourne Again SHell. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |    Bash is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  |    it under the terms of the GNU General Public License as published by | 
					
						
							|  |  |  |    the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  |    (at your option) any later version. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Bash 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 General Public License for more details. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |    along with Bash.  If not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-17 19:52:44 +00:00
										 |  |  | #include <config.h>
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-17 19:52:44 +00:00
										 |  |  | #include <bashtypes.h>
 | 
					
						
							|  |  |  | #ifndef _MINIX
 | 
					
						
							|  |  |  | #  include <sys/param.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if defined (HAVE_UNISTD_H)
 | 
					
						
							|  |  |  | #  include <unistd.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | #if defined (HAVE_LIMITS_H)
 | 
					
						
							|  |  |  | #  include <limits.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-17 19:52:44 +00:00
										 |  |  | #include <posixstat.h>
 | 
					
						
							|  |  |  | #include <filecntl.h>
 | 
					
						
							|  |  |  | #include <bashansi.h>
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-22 19:11:26 -05:00
										 |  |  | #if !defined (HAVE_KILLPG)
 | 
					
						
							|  |  |  | #  include <signal.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <errno.h>
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  | #include <chartypes.h>
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-04-17 19:52:44 +00:00
										 |  |  | #include <shell.h>
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if !defined (errno)
 | 
					
						
							|  |  |  | extern int errno; | 
					
						
							|  |  |  | #endif /* !errno */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Make the functions strchr and strrchr if they do not exist. */ | 
					
						
							|  |  |  | #if !defined (HAVE_STRCHR)
 | 
					
						
							|  |  |  | char * | 
					
						
							|  |  |  | strchr (string, c) | 
					
						
							|  |  |  |      char *string; | 
					
						
							|  |  |  |      int c; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   register char *s; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (s = string; s && *s; s++) | 
					
						
							|  |  |  |     if (*s == c) | 
					
						
							|  |  |  |       return (s); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ((char *) NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | char * | 
					
						
							|  |  |  | strrchr (string, c) | 
					
						
							|  |  |  |      char *string; | 
					
						
							|  |  |  |      int c; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   register char *s, *t; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (s = string, t = (char *)NULL; s && *s; s++) | 
					
						
							|  |  |  |     if (*s == c) | 
					
						
							|  |  |  |       t = s; | 
					
						
							|  |  |  |   return (t); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif /* !HAVE_STRCHR */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if !defined (HAVE_DUP2) || defined (DUP2_BROKEN)
 | 
					
						
							|  |  |  | /* Replacement for dup2 (), for those systems which either don't have it,
 | 
					
						
							|  |  |  |    or supply one with broken behaviour. */ | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | dup2 (fd1, fd2) | 
					
						
							|  |  |  |      int fd1, fd2; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   int saved_errno, r; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* If FD1 is not a valid file descriptor, then return immediately with
 | 
					
						
							|  |  |  |      an error. */ | 
					
						
							|  |  |  |   if (fcntl (fd1, F_GETFL, 0) == -1) | 
					
						
							|  |  |  |     return (-1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (fd2 < 0 || fd2 >= getdtablesize ()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       errno = EBADF; | 
					
						
							|  |  |  |       return (-1); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (fd1 == fd2) | 
					
						
							|  |  |  |     return (0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   saved_errno = errno; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   (void) close (fd2); | 
					
						
							|  |  |  |   r = fcntl (fd1, F_DUPFD, fd2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (r >= 0) | 
					
						
							|  |  |  |     errno = saved_errno; | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     if (errno == EINVAL) | 
					
						
							|  |  |  |       errno = EBADF; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Force the new file descriptor to remain open across exec () calls. */ | 
					
						
							|  |  |  |   SET_OPEN_ON_EXEC (fd2); | 
					
						
							|  |  |  |   return (r); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif /* !HAVE_DUP2 */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Return the total number of available file descriptors. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * On some systems, like 4.2BSD and its descendents, there is a system call | 
					
						
							|  |  |  |  * that returns the size of the descriptor table: getdtablesize().  There are | 
					
						
							|  |  |  |  * lots of ways to emulate this on non-BSD systems. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * On System V.3, this can be obtained via a call to ulimit: | 
					
						
							|  |  |  |  *	return (ulimit(4, 0L)); | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * On other System V systems, NOFILE is defined in /usr/include/sys/param.h | 
					
						
							|  |  |  |  * (this is what we assume below), so we can simply use it: | 
					
						
							|  |  |  |  *	return (NOFILE); | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * On POSIX systems, there are specific functions for retrieving various | 
					
						
							|  |  |  |  * configuration parameters: | 
					
						
							|  |  |  |  *	return (sysconf(_SC_OPEN_MAX)); | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if !defined (HAVE_GETDTABLESIZE)
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | getdtablesize () | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #  if defined (_POSIX_VERSION) && defined (HAVE_SYSCONF) && defined (_SC_OPEN_MAX)
 | 
					
						
							|  |  |  |   return (sysconf(_SC_OPEN_MAX));	/* Posix systems use sysconf */ | 
					
						
							|  |  |  | #  else /* ! (_POSIX_VERSION && HAVE_SYSCONF && _SC_OPEN_MAX) */
 | 
					
						
							|  |  |  | #    if defined (ULIMIT_MAXFDS)
 | 
					
						
							|  |  |  |   return (ulimit (4, 0L));	/* System V.3 systems use ulimit(4, 0L) */ | 
					
						
							|  |  |  | #    else /* !ULIMIT_MAXFDS */
 | 
					
						
							|  |  |  | #      if defined (NOFILE)	/* Other systems use NOFILE */
 | 
					
						
							|  |  |  |   return (NOFILE); | 
					
						
							|  |  |  | #      else /* !NOFILE */
 | 
					
						
							|  |  |  |   return (20);			/* XXX - traditional value is 20 */ | 
					
						
							|  |  |  | #      endif /* !NOFILE */
 | 
					
						
							|  |  |  | #    endif /* !ULIMIT_MAXFDS */
 | 
					
						
							|  |  |  | #  endif /* ! (_POSIX_VERSION && _SC_OPEN_MAX) */
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif /* !HAVE_GETDTABLESIZE */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if !defined (HAVE_BCOPY)
 | 
					
						
							| 
									
										
										
										
											1999-02-19 17:11:39 +00:00
										 |  |  | #  if defined (bcopy)
 | 
					
						
							|  |  |  | #    undef bcopy
 | 
					
						
							|  |  |  | #  endif
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | void | 
					
						
							|  |  |  | bcopy (s,d,n) | 
					
						
							|  |  |  |      char *d, *s; | 
					
						
							|  |  |  |      int n; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   FASTCOPY (s, d, n); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif /* !HAVE_BCOPY */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if !defined (HAVE_BZERO)
 | 
					
						
							| 
									
										
										
										
											1999-02-19 17:11:39 +00:00
										 |  |  | #  if defined (bzero)
 | 
					
						
							|  |  |  | #    undef bzero
 | 
					
						
							|  |  |  | #  endif
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | void | 
					
						
							|  |  |  | bzero (s, n) | 
					
						
							|  |  |  |      char *s; | 
					
						
							|  |  |  |      int n; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   register int i; | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  |   register char *r; | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  |   for (i = 0, r = s; i < n; i++) | 
					
						
							|  |  |  |     *r++ = '\0'; | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if !defined (HAVE_GETHOSTNAME)
 | 
					
						
							|  |  |  | #  if defined (HAVE_UNAME)
 | 
					
						
							|  |  |  | #    include <sys/utsname.h>
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | gethostname (name, namelen) | 
					
						
							|  |  |  |      char *name; | 
					
						
							|  |  |  |      int namelen; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   int i; | 
					
						
							|  |  |  |   struct utsname ut; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   --namelen; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   uname (&ut); | 
					
						
							|  |  |  |   i = strlen (ut.nodename) + 1; | 
					
						
							|  |  |  |   strncpy (name, ut.nodename, i < namelen ? i : namelen); | 
					
						
							|  |  |  |   name[namelen] = '\0'; | 
					
						
							|  |  |  |   return (0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #  else /* !HAVE_UNAME */
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | gethostname (name, namelen) | 
					
						
							| 
									
										
										
										
											2011-11-22 19:11:26 -05:00
										 |  |  |      char *name; | 
					
						
							|  |  |  |      int namelen; | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   strncpy (name, "unknown", namelen); | 
					
						
							|  |  |  |   name[namelen] = '\0'; | 
					
						
							|  |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #  endif /* !HAVE_UNAME */
 | 
					
						
							|  |  |  | #endif /* !HAVE_GETHOSTNAME */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if !defined (HAVE_KILLPG)
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | killpg (pgrp, sig) | 
					
						
							|  |  |  |      pid_t pgrp; | 
					
						
							|  |  |  |      int sig; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return (kill (-pgrp, sig)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif /* !HAVE_KILLPG */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if !defined (HAVE_MKFIFO) && defined (PROCESS_SUBSTITUTION)
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | mkfifo (path, mode) | 
					
						
							|  |  |  |      char *path; | 
					
						
							|  |  |  |      int mode; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #if defined (S_IFIFO)
 | 
					
						
							|  |  |  |   return (mknod (path, (mode | S_IFIFO), 0)); | 
					
						
							|  |  |  | #else /* !S_IFIFO */
 | 
					
						
							|  |  |  |   return (-1); | 
					
						
							|  |  |  | #endif /* !S_IFIFO */
 | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											1998-04-17 19:52:44 +00:00
										 |  |  | #endif /* !HAVE_MKFIFO && PROCESS_SUBSTITUTION */
 | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define DEFAULT_MAXGROUPS 64
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | getmaxgroups () | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   static int maxgroups = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (maxgroups > 0) | 
					
						
							|  |  |  |     return maxgroups; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined (HAVE_SYSCONF) && defined (_SC_NGROUPS_MAX)
 | 
					
						
							|  |  |  |   maxgroups = sysconf (_SC_NGROUPS_MAX); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #  if defined (NGROUPS_MAX)
 | 
					
						
							|  |  |  |   maxgroups = NGROUPS_MAX; | 
					
						
							|  |  |  | #  else /* !NGROUPS_MAX */
 | 
					
						
							|  |  |  | #    if defined (NGROUPS)
 | 
					
						
							|  |  |  |   maxgroups = NGROUPS; | 
					
						
							|  |  |  | #    else /* !NGROUPS */
 | 
					
						
							|  |  |  |   maxgroups = DEFAULT_MAXGROUPS; | 
					
						
							|  |  |  | #    endif /* !NGROUPS */
 | 
					
						
							|  |  |  | #  endif /* !NGROUPS_MAX */  
 | 
					
						
							|  |  |  | #endif /* !HAVE_SYSCONF || !SC_NGROUPS_MAX */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (maxgroups <= 0) | 
					
						
							|  |  |  |     maxgroups = DEFAULT_MAXGROUPS; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return maxgroups; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | long | 
					
						
							|  |  |  | getmaxchild () | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   static long maxchild = -1L; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (maxchild > 0) | 
					
						
							|  |  |  |     return maxchild; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined (HAVE_SYSCONF) && defined (_SC_CHILD_MAX)
 | 
					
						
							|  |  |  |   maxchild = sysconf (_SC_CHILD_MAX); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #  if defined (CHILD_MAX)
 | 
					
						
							|  |  |  |   maxchild = CHILD_MAX; | 
					
						
							|  |  |  | #  else
 | 
					
						
							|  |  |  | #    if defined (MAXUPRC)
 | 
					
						
							|  |  |  |   maxchild = MAXUPRC; | 
					
						
							|  |  |  | #    endif /* MAXUPRC */
 | 
					
						
							|  |  |  | #  endif /* CHILD_MAX */
 | 
					
						
							|  |  |  | #endif /* !HAVE_SYSCONF || !_SC_CHILD_MAX */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return (maxchild); | 
					
						
							|  |  |  | } |