1 /* oslib.c - functions present only in some unix versions. */
3 /* Copyright (C) 1995 Free Software Foundation, Inc.
5 This file is part of GNU Bash, the Bourne Again SHell.
7 Bash is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License along
18 with Bash; see the file COPYING. If not, write to the Free Software
19 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
23 #include "bashtypes.h"
24 #include <sys/param.h>
26 #if defined (HAVE_UNISTD_H)
30 #include "posixstat.h"
45 /* A standard error message to use when getcwd() returns NULL. */
46 char *bash_getcwd_errstr = "getcwd: cannot access parent directories";
48 #if !defined (HAVE_SYSCONF) || !defined (_SC_CLK_TCK)
49 # if !defined (CLK_TCK)
55 # endif /* !CLK_TCK */
56 #endif /* !HAVE_SYSCONF && !_SC_CLK_TCK */
61 static long retval = 0;
66 #if defined (HAVE_SYSCONF) && defined (_SC_CLK_TCK)
67 retval = sysconf (_SC_CLK_TCK);
68 #else /* !SYSCONF || !_SC_CLK_TCK */
70 #endif /* !SYSCONF || !_SC_CLK_TCK */
75 /* Make the functions strchr and strrchr if they do not exist. */
76 #if !defined (HAVE_STRCHR)
84 for (s = string; s && *s; s++)
88 return ((char *) NULL);
98 for (s = string, t = (char *)NULL; s && *s; s++)
103 #endif /* !HAVE_STRCHR */
105 #if !defined (HAVE_STRCASECMP)
107 #if !defined (to_lower)
108 # define to_lower(c) (islower(c) ? (c) : tolower(c))
109 #endif /* to_lower */
111 /* Compare at most COUNT characters from string1 to string2. Case
114 strncasecmp (string1, string2, count)
115 char *string1, *string2;
118 register char *s1, *s2;
127 if ((r = to_lower (*s1) - to_lower (*s2)) != 0)
133 while (--count != 0);
138 /* strcmp (), but caseless. */
140 strcasecmp (string1, string2)
141 char *string1, *string2;
143 register char *s1, *s2;
149 while ((r = to_lower (*s1) - to_lower (*s2)) == 0)
157 #endif /* !HAVE_STRCASECMP */
159 /* Return a string corresponding to the error number E. From
161 #if defined (strerror)
165 #if !defined (HAVE_STRERROR)
170 static char emsg[40];
171 #if defined (HAVE_SYS_ERRLIST)
173 extern char *sys_errlist[];
175 if (e > 0 && e < sys_nerr)
176 return (sys_errlist[e]);
178 #endif /* HAVE_SYS_ERRLIST */
180 sprintf (emsg, "Unknown error %d", e);
184 #endif /* HAVE_STRERROR */
186 #if !defined (HAVE_DUP2) || defined (DUP2_BROKEN)
187 /* Replacement for dup2 (), for those systems which either don't have it,
188 or supply one with broken behaviour. */
195 /* If FD1 is not a valid file descriptor, then return immediately with
197 if (fcntl (fd1, F_GETFL, 0) == -1)
200 if (fd2 < 0 || fd2 >= getdtablesize ())
212 r = fcntl (fd1, F_DUPFD, fd2);
220 /* Force the new file descriptor to remain open across exec () calls. */
221 SET_OPEN_ON_EXEC (fd2);
224 #endif /* !HAVE_DUP2 */
227 * Return the total number of available file descriptors.
229 * On some systems, like 4.2BSD and its descendents, there is a system call
230 * that returns the size of the descriptor table: getdtablesize(). There are
231 * lots of ways to emulate this on non-BSD systems.
233 * On System V.3, this can be obtained via a call to ulimit:
234 * return (ulimit(4, 0L));
236 * On other System V systems, NOFILE is defined in /usr/include/sys/param.h
237 * (this is what we assume below), so we can simply use it:
240 * On POSIX systems, there are specific functions for retrieving various
241 * configuration parameters:
242 * return (sysconf(_SC_OPEN_MAX));
246 #if !defined (HAVE_GETDTABLESIZE)
250 # if defined (_POSIX_VERSION) && defined (HAVE_SYSCONF) && defined (_SC_OPEN_MAX)
251 return (sysconf(_SC_OPEN_MAX)); /* Posix systems use sysconf */
252 # else /* ! (_POSIX_VERSION && HAVE_SYSCONF && _SC_OPEN_MAX) */
253 # if defined (ULIMIT_MAXFDS)
254 return (ulimit (4, 0L)); /* System V.3 systems use ulimit(4, 0L) */
255 # else /* !ULIMIT_MAXFDS */
256 # if defined (NOFILE) /* Other systems use NOFILE */
259 return (20); /* XXX - traditional value is 20 */
260 # endif /* !NOFILE */
261 # endif /* !ULIMIT_MAXFDS */
262 # endif /* ! (_POSIX_VERSION && _SC_OPEN_MAX) */
264 #endif /* !HAVE_GETDTABLESIZE */
266 #if !defined (HAVE_BCOPY)
274 #endif /* !HAVE_BCOPY */
276 #if !defined (HAVE_BZERO)
285 for (i = 0, r = s; i < n; i++)
290 #if !defined (HAVE_GETHOSTNAME)
291 # if defined (HAVE_UNAME)
292 # include <sys/utsname.h>
294 gethostname (name, namelen)
304 i = strlen (ut.nodename) + 1;
305 strncpy (name, ut.nodename, i < namelen ? i : namelen);
306 name[namelen] = '\0';
309 # else /* !HAVE_UNAME */
311 gethostname (name, namelen)
314 strncpy (name, "unknown", namelen);
315 name[namelen] = '\0';
318 # endif /* !HAVE_UNAME */
319 #endif /* !HAVE_GETHOSTNAME */
321 #if !defined (HAVE_KILLPG)
327 return (kill (-pgrp, sig));
329 #endif /* !HAVE_KILLPG */
332 /* We supply our own version of getenv () because we want library
333 routines to get the changed values of exported variables. */
335 /* The NeXT C library has getenv () defined and used in the same file.
336 This screws our scheme. However, Bash will run on the NeXT using
337 the C library getenv (), since right now the only environment variable
338 that we care about is HOME, and that is already defined. */
339 #if defined (CAN_REDEFINE_GETENV)
340 static char *last_tempenv_value = (char *)NULL;
341 extern char **environ;
345 #if defined (__linux__) || defined (__bsdi__) || defined (convex)
349 #endif /* !__linux__ && !__bsdi__ && !convex */
353 var = find_tempenv_variable ((char *)name);
356 FREE (last_tempenv_value);
358 last_tempenv_value = savestring (value_cell (var));
359 dispose_variable (var);
360 return (last_tempenv_value);
362 else if (shell_variables)
364 var = find_variable ((char *)name);
365 if (var && exported_p (var))
366 return (value_cell (var));
372 /* In some cases, s5r3 invokes getenv() before main(); BSD systems
373 using gprof also exhibit this behavior. This means that
374 shell_variables will be 0 when this is invoked. We look up the
375 variable in the real environment in that case. */
377 for (i = 0, len = strlen (name); environ[i]; i++)
379 if ((STREQN (environ[i], name, len)) && (environ[i][len] == '='))
380 return (environ[i] + len + 1);
384 return ((char *)NULL);
387 /* Some versions of Unix use _getenv instead. */
390 #if defined (__linux__) || defined (__bsdi__) || defined (convex)
394 #endif /* !__linux__ && !__bsdi__ && !convex */
396 return (getenv (name));
399 #endif /* CAN_REDEFINE_GETENV */
401 #if !defined (HAVE_MKFIFO) && defined (PROCESS_SUBSTITUTION)
407 #if defined (S_IFIFO)
408 return (mknod (path, (mode | S_IFIFO), 0));
411 #endif /* !S_IFIFO */
415 #if !defined (HAVE_SETLINEBUF)
416 /* Cause STREAM to buffer lines as opposed to characters or blocks. */
422 # if defined (SETVBUF_REVERSED)
423 setvbuf (stream, _IOLBF, (char *)NULL, BUFSIZ);
424 # else /* !SETVBUF_REVERSED */
425 setvbuf (stream, (char *)NULL, _IOLBF, BUFSIZ);
426 # endif /* !SETVBUF_REVERSED */
430 #endif /* !HAVE_SETLINEBUF */