1/* oslib.c - functions present only in some unix versions. */ 2 3/* Copyright (C) 1995 Free Software Foundation, Inc. 4 5 This file is part of GNU Bash, the Bourne Again SHell. 6 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 10 version. 11 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 15 for more details. 16 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, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA */ 20 21#include <config.h> 22 23#include <bashtypes.h> 24#ifndef _MINIX 25# include <sys/param.h> 26#endif 27 28#if defined (HAVE_UNISTD_H) 29# include <unistd.h> 30#endif 31 32#if defined (HAVE_LIMITS_H) 33# include <limits.h> 34#endif 35 36#include <posixstat.h> 37#include <filecntl.h> 38#include <bashansi.h> 39 40#include <stdio.h> 41#include <errno.h> 42#include <chartypes.h> 43 44#include <shell.h> 45 46#if !defined (errno) 47extern int errno; 48#endif /* !errno */ 49 50/* Make the functions strchr and strrchr if they do not exist. */ 51#if !defined (HAVE_STRCHR) 52char * 53strchr (string, c) 54 char *string; 55 int c; 56{ 57 register char *s; 58 59 for (s = string; s && *s; s++) 60 if (*s == c) 61 return (s); 62 63 return ((char *) NULL); 64} 65 66char * 67strrchr (string, c) 68 char *string; 69 int c; 70{ 71 register char *s, *t; 72 73 for (s = string, t = (char *)NULL; s && *s; s++) 74 if (*s == c) 75 t = s; 76 return (t); 77} 78#endif /* !HAVE_STRCHR */ 79 80#if !defined (HAVE_DUP2) || defined (DUP2_BROKEN) 81/* Replacement for dup2 (), for those systems which either don't have it, 82 or supply one with broken behaviour. */ 83int 84dup2 (fd1, fd2) 85 int fd1, fd2; 86{ 87 int saved_errno, r; 88 89 /* If FD1 is not a valid file descriptor, then return immediately with 90 an error. */ 91 if (fcntl (fd1, F_GETFL, 0) == -1) 92 return (-1); 93 94 if (fd2 < 0 || fd2 >= getdtablesize ()) 95 { 96 errno = EBADF; 97 return (-1); 98 } 99 100 if (fd1 == fd2) 101 return (0); 102 103 saved_errno = errno; 104 105 (void) close (fd2); 106 r = fcntl (fd1, F_DUPFD, fd2); 107 108 if (r >= 0) 109 errno = saved_errno; 110 else 111 if (errno == EINVAL) 112 errno = EBADF; 113 114 /* Force the new file descriptor to remain open across exec () calls. */ 115 SET_OPEN_ON_EXEC (fd2); 116 return (r); 117} 118#endif /* !HAVE_DUP2 */ 119 120/* 121 * Return the total number of available file descriptors. 122 * 123 * On some systems, like 4.2BSD and its descendents, there is a system call 124 * that returns the size of the descriptor table: getdtablesize(). There are 125 * lots of ways to emulate this on non-BSD systems. 126 * 127 * On System V.3, this can be obtained via a call to ulimit: 128 * return (ulimit(4, 0L)); 129 * 130 * On other System V systems, NOFILE is defined in /usr/include/sys/param.h 131 * (this is what we assume below), so we can simply use it: 132 * return (NOFILE); 133 * 134 * On POSIX systems, there are specific functions for retrieving various 135 * configuration parameters: 136 * return (sysconf(_SC_OPEN_MAX)); 137 * 138 */ 139 140#if !defined (HAVE_GETDTABLESIZE) 141int 142getdtablesize () 143{ 144# if defined (_POSIX_VERSION) && defined (HAVE_SYSCONF) && defined (_SC_OPEN_MAX) 145 return (sysconf(_SC_OPEN_MAX)); /* Posix systems use sysconf */ 146# else /* ! (_POSIX_VERSION && HAVE_SYSCONF && _SC_OPEN_MAX) */ 147# if defined (ULIMIT_MAXFDS) 148 return (ulimit (4, 0L)); /* System V.3 systems use ulimit(4, 0L) */ 149# else /* !ULIMIT_MAXFDS */ 150# if defined (NOFILE) /* Other systems use NOFILE */ 151 return (NOFILE); 152# else /* !NOFILE */ 153 return (20); /* XXX - traditional value is 20 */ 154# endif /* !NOFILE */ 155# endif /* !ULIMIT_MAXFDS */ 156# endif /* ! (_POSIX_VERSION && _SC_OPEN_MAX) */ 157} 158#endif /* !HAVE_GETDTABLESIZE */ 159 160#if !defined (HAVE_BCOPY) 161# if defined (bcopy) 162# undef bcopy 163# endif 164void 165bcopy (s,d,n) 166 char *d, *s; 167 int n; 168{ 169 FASTCOPY (s, d, n); 170} 171#endif /* !HAVE_BCOPY */ 172 173#if !defined (HAVE_BZERO) 174# if defined (bzero) 175# undef bzero 176# endif 177void 178bzero (s, n) 179 char *s; 180 int n; 181{ 182 register int i; 183 register char *r; 184 185 for (i = 0, r = s; i < n; i++) 186 *r++ = '\0'; 187} 188#endif 189 190#if !defined (HAVE_GETHOSTNAME) 191# if defined (HAVE_UNAME) 192# include <sys/utsname.h> 193int 194gethostname (name, namelen) 195 char *name; 196 int namelen; 197{ 198 int i; 199 struct utsname ut; 200 201 --namelen; 202 203 uname (&ut); 204 i = strlen (ut.nodename) + 1; 205 strncpy (name, ut.nodename, i < namelen ? i : namelen); 206 name[namelen] = '\0'; 207 return (0); 208} 209# else /* !HAVE_UNAME */ 210int 211gethostname (name, namelen) 212 int name, namelen; 213{ 214 strncpy (name, "unknown", namelen); 215 name[namelen] = '\0'; 216 return 0; 217} 218# endif /* !HAVE_UNAME */ 219#endif /* !HAVE_GETHOSTNAME */ 220 221#if !defined (HAVE_KILLPG) 222int 223killpg (pgrp, sig) 224 pid_t pgrp; 225 int sig; 226{ 227 return (kill (-pgrp, sig)); 228} 229#endif /* !HAVE_KILLPG */ 230 231#if !defined (HAVE_MKFIFO) && defined (PROCESS_SUBSTITUTION) 232int 233mkfifo (path, mode) 234 char *path; 235 int mode; 236{ 237#if defined (S_IFIFO) 238 return (mknod (path, (mode | S_IFIFO), 0)); 239#else /* !S_IFIFO */ 240 return (-1); 241#endif /* !S_IFIFO */ 242} 243#endif /* !HAVE_MKFIFO && PROCESS_SUBSTITUTION */ 244 245#define DEFAULT_MAXGROUPS 64 246 247int 248getmaxgroups () 249{ 250 static int maxgroups = -1; 251 252 if (maxgroups > 0) 253 return maxgroups; 254 255#if defined (HAVE_SYSCONF) && defined (_SC_NGROUPS_MAX) 256 maxgroups = sysconf (_SC_NGROUPS_MAX); 257#else 258# if defined (NGROUPS_MAX) 259 maxgroups = NGROUPS_MAX; 260# else /* !NGROUPS_MAX */ 261# if defined (NGROUPS) 262 maxgroups = NGROUPS; 263# else /* !NGROUPS */ 264 maxgroups = DEFAULT_MAXGROUPS; 265# endif /* !NGROUPS */ 266# endif /* !NGROUPS_MAX */ 267#endif /* !HAVE_SYSCONF || !SC_NGROUPS_MAX */ 268 269 if (maxgroups <= 0) 270 maxgroups = DEFAULT_MAXGROUPS; 271 272 return maxgroups; 273} 274 275long 276getmaxchild () 277{ 278 static long maxchild = -1L; 279 280 if (maxchild > 0) 281 return maxchild; 282 283#if defined (HAVE_SYSCONF) && defined (_SC_CHILD_MAX) 284 maxchild = sysconf (_SC_CHILD_MAX); 285#else 286# if defined (CHILD_MAX) 287 maxchild = CHILD_MAX; 288# else 289# if defined (MAXUPRC) 290 maxchild = MAXUPRC; 291# endif /* MAXUPRC */ 292# endif /* CHILD_MAX */ 293#endif /* !HAVE_SYSCONF || !_SC_CHILD_MAX */ 294 295 return (maxchild); 296} 297