301 lines
		
	
	
	
		
			6.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			301 lines
		
	
	
	
		
			6.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* oslib.c - functions present only in some unix versions. */
 | 
						|
 | 
						|
/* Copyright (C) 1995,2010 Free Software Foundation, Inc.
 | 
						|
 | 
						|
   This file is part of GNU Bash, the Bourne Again SHell.
 | 
						|
 | 
						|
   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/>.
 | 
						|
*/
 | 
						|
 | 
						|
#include <config.h>
 | 
						|
 | 
						|
#include <bashtypes.h>
 | 
						|
#if defined (HAVE_SYS_PARAM_H)
 | 
						|
#  include <sys/param.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#if defined (HAVE_UNISTD_H)
 | 
						|
#  include <unistd.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#if defined (HAVE_LIMITS_H)
 | 
						|
#  include <limits.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#include <posixstat.h>
 | 
						|
#include <filecntl.h>
 | 
						|
#include <bashansi.h>
 | 
						|
 | 
						|
#if !defined (HAVE_KILLPG)
 | 
						|
#  include <signal.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#include <stdio.h>
 | 
						|
#include <errno.h>
 | 
						|
#include <chartypes.h>
 | 
						|
 | 
						|
#include <shell.h>
 | 
						|
 | 
						|
#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 descendants, 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)
 | 
						|
#  if defined (bcopy)
 | 
						|
#    undef bcopy
 | 
						|
#  endif
 | 
						|
void
 | 
						|
bcopy (s,d,n)
 | 
						|
     char *d, *s;
 | 
						|
     int n;
 | 
						|
{
 | 
						|
  FASTCOPY (s, d, n);
 | 
						|
}
 | 
						|
#endif /* !HAVE_BCOPY */
 | 
						|
 | 
						|
#if !defined (HAVE_BZERO)
 | 
						|
#  if defined (bzero)
 | 
						|
#    undef bzero
 | 
						|
#  endif
 | 
						|
void
 | 
						|
bzero (s, n)
 | 
						|
     char *s;
 | 
						|
     int n;
 | 
						|
{
 | 
						|
  register int i;
 | 
						|
  register char *r;
 | 
						|
 | 
						|
  for (i = 0, r = s; i < n; i++)
 | 
						|
    *r++ = '\0';
 | 
						|
}
 | 
						|
#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)
 | 
						|
     char *name;
 | 
						|
     int namelen;
 | 
						|
{
 | 
						|
  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 */
 | 
						|
}
 | 
						|
#endif /* !HAVE_MKFIFO && PROCESS_SUBSTITUTION */
 | 
						|
 | 
						|
#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);
 | 
						|
}
 |