Imported from ../bash-2.0.tar.gz.
This commit is contained in:
parent
726f63884d
commit
ccc6cda312
502 changed files with 91988 additions and 69123 deletions
429
oslib.c
Normal file
429
oslib.c
Normal file
|
|
@ -0,0 +1,429 @@
|
|||
/* oslib.c - functions present only in some unix versions. */
|
||||
|
||||
/* Copyright (C) 1995 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 2, 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; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "bashtypes.h"
|
||||
#include <sys/param.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "posixstat.h"
|
||||
#include "filecntl.h"
|
||||
#include "bashansi.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "shell.h"
|
||||
#include "maxpath.h"
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif /* !errno */
|
||||
|
||||
/* A standard error message to use when getcwd() returns NULL. */
|
||||
char *bash_getcwd_errstr = "getcwd: cannot access parent directories";
|
||||
|
||||
#if !defined (HAVE_SYSCONF) || !defined (_SC_CLK_TCK)
|
||||
# if !defined (CLK_TCK)
|
||||
# if defined (HZ)
|
||||
# define CLK_TCK HZ
|
||||
# else
|
||||
# define CLK_TCK 60
|
||||
# endif
|
||||
# endif /* !CLK_TCK */
|
||||
#endif /* !HAVE_SYSCONF && !_SC_CLK_TCK */
|
||||
|
||||
long
|
||||
get_clk_tck ()
|
||||
{
|
||||
static long retval = 0;
|
||||
|
||||
if (retval != 0)
|
||||
return (retval);
|
||||
|
||||
#if defined (HAVE_SYSCONF) && defined (_SC_CLK_TCK)
|
||||
retval = sysconf (_SC_CLK_TCK);
|
||||
#else /* !SYSCONF || !_SC_CLK_TCK */
|
||||
retval = CLK_TCK;
|
||||
#endif /* !SYSCONF || !_SC_CLK_TCK */
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
/* 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_STRCASECMP)
|
||||
|
||||
#if !defined (to_lower)
|
||||
# define to_lower(c) (islower(c) ? (c) : toupper(c))
|
||||
#endif /* to_lower */
|
||||
|
||||
/* Compare at most COUNT characters from string1 to string2. Case
|
||||
doesn't matter. */
|
||||
int
|
||||
strncasecmp (string1, string2, count)
|
||||
char *string1, *string2;
|
||||
int count;
|
||||
{
|
||||
register char *s1, *s2;
|
||||
register int r;
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
s1 = string1;
|
||||
s2 = string2;
|
||||
do
|
||||
{
|
||||
if ((r = to_lower (*s1) - to_lower (*s2)) != 0)
|
||||
return r;
|
||||
if (*s1++ == '\0')
|
||||
break;
|
||||
s2++;
|
||||
}
|
||||
while (--count != 0);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* strcmp (), but caseless. */
|
||||
int
|
||||
strcasecmp (string1, string2)
|
||||
char *string1, *string2;
|
||||
{
|
||||
register char *s1, *s2;
|
||||
register int r;
|
||||
|
||||
s1 = string1;
|
||||
s2 = string2;
|
||||
|
||||
while ((r = to_lower (*s1) - to_lower (*s2)) == 0)
|
||||
{
|
||||
if (*s1++ == '\0')
|
||||
return 0;
|
||||
s2++;
|
||||
}
|
||||
return (r);
|
||||
}
|
||||
#endif /* !HAVE_STRCASECMP */
|
||||
|
||||
/* Return a string corresponding to the error number E. From
|
||||
the ANSI C spec. */
|
||||
#if defined (strerror)
|
||||
# undef strerror
|
||||
#endif
|
||||
|
||||
#if !defined (HAVE_STRERROR)
|
||||
char *
|
||||
strerror (e)
|
||||
int e;
|
||||
{
|
||||
static char emsg[40];
|
||||
#if defined (HAVE_SYS_ERRLIST)
|
||||
extern int sys_nerr;
|
||||
extern char *sys_errlist[];
|
||||
|
||||
if (e > 0 && e < sys_nerr)
|
||||
return (sys_errlist[e]);
|
||||
else
|
||||
#endif /* HAVE_SYS_ERRLIST */
|
||||
{
|
||||
sprintf (emsg, "Unknown error %d", e);
|
||||
return (&emsg[0]);
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_STRERROR */
|
||||
|
||||
#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)
|
||||
void
|
||||
bcopy (s,d,n)
|
||||
char *d, *s;
|
||||
int n;
|
||||
{
|
||||
FASTCOPY (s, d, n);
|
||||
}
|
||||
#endif /* !HAVE_BCOPY */
|
||||
|
||||
#if !defined (HAVE_BZERO)
|
||||
void
|
||||
bzero (s, n)
|
||||
char *s;
|
||||
int n;
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
s[i] = '\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)
|
||||
int name, 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 */
|
||||
|
||||
|
||||
/* We supply our own version of getenv () because we want library
|
||||
routines to get the changed values of exported variables. */
|
||||
|
||||
/* The NeXT C library has getenv () defined and used in the same file.
|
||||
This screws our scheme. However, Bash will run on the NeXT using
|
||||
the C library getenv (), since right now the only environment variable
|
||||
that we care about is HOME, and that is already defined. */
|
||||
#if defined (CAN_REDEFINE_GETENV)
|
||||
static char *last_tempenv_value = (char *)NULL;
|
||||
extern char **environ;
|
||||
|
||||
char *
|
||||
getenv (name)
|
||||
#if defined (__linux__) || defined (__bsdi__) || defined (convex)
|
||||
const char *name;
|
||||
#else
|
||||
char const *name;
|
||||
#endif /* !__linux__ && !__bsdi__ && !convex */
|
||||
{
|
||||
SHELL_VAR *var;
|
||||
|
||||
var = find_tempenv_variable ((char *)name);
|
||||
if (var)
|
||||
{
|
||||
FREE (last_tempenv_value);
|
||||
|
||||
last_tempenv_value = savestring (value_cell (var));
|
||||
dispose_variable (var);
|
||||
return (last_tempenv_value);
|
||||
}
|
||||
else if (shell_variables)
|
||||
{
|
||||
var = find_variable ((char *)name);
|
||||
if (var && exported_p (var))
|
||||
return (value_cell (var));
|
||||
}
|
||||
else
|
||||
{
|
||||
register int i, len;
|
||||
|
||||
/* In some cases, s5r3 invokes getenv() before main(); BSD systems
|
||||
using gprof also exhibit this behavior. This means that
|
||||
shell_variables will be 0 when this is invoked. We look up the
|
||||
variable in the real environment in that case. */
|
||||
|
||||
for (i = 0, len = strlen (name); environ[i]; i++)
|
||||
{
|
||||
if ((STREQN (environ[i], name, len)) && (environ[i][len] == '='))
|
||||
return (environ[i] + len + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return ((char *)NULL);
|
||||
}
|
||||
|
||||
/* Some versions of Unix use _getenv instead. */
|
||||
char *
|
||||
_getenv (name)
|
||||
#if defined (__linux__) || defined (__bsdi__) || defined (convex)
|
||||
const char *name;
|
||||
#else
|
||||
char const *name;
|
||||
#endif /* !__linux__ && !__bsdi__ && !convex */
|
||||
{
|
||||
return (getenv (name));
|
||||
}
|
||||
|
||||
#endif /* CAN_REDEFINE_GETENV */
|
||||
|
||||
#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
|
||||
|
||||
#if !defined (HAVE_SETLINEBUF)
|
||||
/* Cause STREAM to buffer lines as opposed to characters or blocks. */
|
||||
int
|
||||
setlinebuf (stream)
|
||||
FILE *stream;
|
||||
{
|
||||
#if defined (_IOLBF)
|
||||
# if defined (SETVBUF_REVERSED)
|
||||
setvbuf (stream, _IOLBF, (char *)NULL, BUFSIZ);
|
||||
# else /* !SETVBUF_REVERSED */
|
||||
setvbuf (stream, (char *)NULL, _IOLBF, BUFSIZ);
|
||||
# endif /* !SETVBUF_REVERSED */
|
||||
#endif /* _IOLBF */
|
||||
return (0);
|
||||
}
|
||||
#endif /* !HAVE_SETLINEBUF */
|
||||
Loading…
Add table
Add a link
Reference in a new issue