blob: bd48dd75849e728eaa46f47bdf10551b81f94e12 [file] [log] [blame]
Jari Aaltocce855b1998-04-17 19:52:44 +00001/* oslib.c - functions present only in some unix versions. */
2
Chet Ramey495aee42011-11-22 19:11:26 -05003/* Copyright (C) 1995,2010 Free Software Foundation, Inc.
Jari Aaltocce855b1998-04-17 19:52:44 +00004
5 This file is part of GNU Bash, the Bourne Again SHell.
6
Jari Aalto31859422009-01-12 13:36:28 +00007 Bash is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
Jari Aaltocce855b1998-04-17 19:52:44 +000011
Jari Aalto31859422009-01-12 13:36:28 +000012 Bash is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
Jari Aaltocce855b1998-04-17 19:52:44 +000016
Jari Aalto31859422009-01-12 13:36:28 +000017 You should have received a copy of the GNU General Public License
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.
19*/
Jari Aaltocce855b1998-04-17 19:52:44 +000020
21#include <config.h>
22
23#include <bashtypes.h>
Chet Rameyac50fba2014-02-26 09:36:43 -050024#if defined (HAVE_SYS_PARAM_H)
Jari Aaltocce855b1998-04-17 19:52:44 +000025# include <sys/param.h>
26#endif
27
28#if defined (HAVE_UNISTD_H)
29# include <unistd.h>
30#endif
31
Jari Aalto7117c2d2002-07-17 14:10:11 +000032#if defined (HAVE_LIMITS_H)
33# include <limits.h>
34#endif
35
Jari Aaltocce855b1998-04-17 19:52:44 +000036#include <posixstat.h>
37#include <filecntl.h>
38#include <bashansi.h>
39
Chet Ramey495aee42011-11-22 19:11:26 -050040#if !defined (HAVE_KILLPG)
41# include <signal.h>
42#endif
43
Jari Aaltocce855b1998-04-17 19:52:44 +000044#include <stdio.h>
45#include <errno.h>
Jari Aaltof73dda02001-11-13 17:56:06 +000046#include <chartypes.h>
Jari Aaltocce855b1998-04-17 19:52:44 +000047
48#include <shell.h>
49
50#if !defined (errno)
Ricardo Cerqueiraa02fbff2013-07-25 22:35:34 +010051#include <errno.h>
Jari Aaltocce855b1998-04-17 19:52:44 +000052#endif /* !errno */
53
54/* Make the functions strchr and strrchr if they do not exist. */
55#if !defined (HAVE_STRCHR)
56char *
57strchr (string, c)
58 char *string;
59 int c;
60{
61 register char *s;
62
63 for (s = string; s && *s; s++)
64 if (*s == c)
65 return (s);
66
67 return ((char *) NULL);
68}
69
70char *
71strrchr (string, c)
72 char *string;
73 int c;
74{
75 register char *s, *t;
76
77 for (s = string, t = (char *)NULL; s && *s; s++)
78 if (*s == c)
79 t = s;
80 return (t);
81}
82#endif /* !HAVE_STRCHR */
83
84#if !defined (HAVE_DUP2) || defined (DUP2_BROKEN)
85/* Replacement for dup2 (), for those systems which either don't have it,
86 or supply one with broken behaviour. */
87int
88dup2 (fd1, fd2)
89 int fd1, fd2;
90{
91 int saved_errno, r;
92
93 /* If FD1 is not a valid file descriptor, then return immediately with
94 an error. */
95 if (fcntl (fd1, F_GETFL, 0) == -1)
96 return (-1);
97
98 if (fd2 < 0 || fd2 >= getdtablesize ())
99 {
100 errno = EBADF;
101 return (-1);
102 }
103
104 if (fd1 == fd2)
105 return (0);
106
107 saved_errno = errno;
108
109 (void) close (fd2);
110 r = fcntl (fd1, F_DUPFD, fd2);
111
112 if (r >= 0)
113 errno = saved_errno;
114 else
115 if (errno == EINVAL)
116 errno = EBADF;
117
118 /* Force the new file descriptor to remain open across exec () calls. */
119 SET_OPEN_ON_EXEC (fd2);
120 return (r);
121}
122#endif /* !HAVE_DUP2 */
123
124/*
125 * Return the total number of available file descriptors.
126 *
Chet Rameyac50fba2014-02-26 09:36:43 -0500127 * On some systems, like 4.2BSD and its descendants, there is a system call
Jari Aaltocce855b1998-04-17 19:52:44 +0000128 * that returns the size of the descriptor table: getdtablesize(). There are
129 * lots of ways to emulate this on non-BSD systems.
130 *
131 * On System V.3, this can be obtained via a call to ulimit:
132 * return (ulimit(4, 0L));
133 *
134 * On other System V systems, NOFILE is defined in /usr/include/sys/param.h
135 * (this is what we assume below), so we can simply use it:
136 * return (NOFILE);
137 *
138 * On POSIX systems, there are specific functions for retrieving various
139 * configuration parameters:
140 * return (sysconf(_SC_OPEN_MAX));
141 *
142 */
143
144#if !defined (HAVE_GETDTABLESIZE)
145int
146getdtablesize ()
147{
148# if defined (_POSIX_VERSION) && defined (HAVE_SYSCONF) && defined (_SC_OPEN_MAX)
149 return (sysconf(_SC_OPEN_MAX)); /* Posix systems use sysconf */
150# else /* ! (_POSIX_VERSION && HAVE_SYSCONF && _SC_OPEN_MAX) */
151# if defined (ULIMIT_MAXFDS)
152 return (ulimit (4, 0L)); /* System V.3 systems use ulimit(4, 0L) */
153# else /* !ULIMIT_MAXFDS */
154# if defined (NOFILE) /* Other systems use NOFILE */
155 return (NOFILE);
156# else /* !NOFILE */
157 return (20); /* XXX - traditional value is 20 */
158# endif /* !NOFILE */
159# endif /* !ULIMIT_MAXFDS */
160# endif /* ! (_POSIX_VERSION && _SC_OPEN_MAX) */
161}
162#endif /* !HAVE_GETDTABLESIZE */
163
164#if !defined (HAVE_BCOPY)
Jari Aaltob72432f1999-02-19 17:11:39 +0000165# if defined (bcopy)
166# undef bcopy
167# endif
Jari Aaltocce855b1998-04-17 19:52:44 +0000168void
169bcopy (s,d,n)
170 char *d, *s;
171 int n;
172{
173 FASTCOPY (s, d, n);
174}
175#endif /* !HAVE_BCOPY */
176
177#if !defined (HAVE_BZERO)
Jari Aaltob72432f1999-02-19 17:11:39 +0000178# if defined (bzero)
179# undef bzero
180# endif
Jari Aaltocce855b1998-04-17 19:52:44 +0000181void
182bzero (s, n)
183 char *s;
184 int n;
185{
186 register int i;
187 register char *r;
188
189 for (i = 0, r = s; i < n; i++)
190 *r++ = '\0';
191}
192#endif
193
194#if !defined (HAVE_GETHOSTNAME)
195# if defined (HAVE_UNAME)
196# include <sys/utsname.h>
197int
198gethostname (name, namelen)
199 char *name;
200 int namelen;
201{
202 int i;
203 struct utsname ut;
204
205 --namelen;
206
207 uname (&ut);
208 i = strlen (ut.nodename) + 1;
209 strncpy (name, ut.nodename, i < namelen ? i : namelen);
210 name[namelen] = '\0';
211 return (0);
212}
213# else /* !HAVE_UNAME */
214int
215gethostname (name, namelen)
Chet Ramey495aee42011-11-22 19:11:26 -0500216 char *name;
217 int namelen;
Jari Aaltocce855b1998-04-17 19:52:44 +0000218{
219 strncpy (name, "unknown", namelen);
220 name[namelen] = '\0';
221 return 0;
222}
223# endif /* !HAVE_UNAME */
224#endif /* !HAVE_GETHOSTNAME */
225
226#if !defined (HAVE_KILLPG)
227int
228killpg (pgrp, sig)
229 pid_t pgrp;
230 int sig;
231{
232 return (kill (-pgrp, sig));
233}
234#endif /* !HAVE_KILLPG */
235
236#if !defined (HAVE_MKFIFO) && defined (PROCESS_SUBSTITUTION)
237int
238mkfifo (path, mode)
239 char *path;
240 int mode;
241{
242#if defined (S_IFIFO)
243 return (mknod (path, (mode | S_IFIFO), 0));
244#else /* !S_IFIFO */
245 return (-1);
246#endif /* !S_IFIFO */
247}
248#endif /* !HAVE_MKFIFO && PROCESS_SUBSTITUTION */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000249
250#define DEFAULT_MAXGROUPS 64
251
252int
253getmaxgroups ()
254{
255 static int maxgroups = -1;
256
257 if (maxgroups > 0)
258 return maxgroups;
259
260#if defined (HAVE_SYSCONF) && defined (_SC_NGROUPS_MAX)
261 maxgroups = sysconf (_SC_NGROUPS_MAX);
262#else
263# if defined (NGROUPS_MAX)
264 maxgroups = NGROUPS_MAX;
265# else /* !NGROUPS_MAX */
266# if defined (NGROUPS)
267 maxgroups = NGROUPS;
268# else /* !NGROUPS */
269 maxgroups = DEFAULT_MAXGROUPS;
270# endif /* !NGROUPS */
271# endif /* !NGROUPS_MAX */
272#endif /* !HAVE_SYSCONF || !SC_NGROUPS_MAX */
273
274 if (maxgroups <= 0)
275 maxgroups = DEFAULT_MAXGROUPS;
276
277 return maxgroups;
278}
279
280long
281getmaxchild ()
282{
283 static long maxchild = -1L;
284
285 if (maxchild > 0)
286 return maxchild;
287
288#if defined (HAVE_SYSCONF) && defined (_SC_CHILD_MAX)
289 maxchild = sysconf (_SC_CHILD_MAX);
290#else
291# if defined (CHILD_MAX)
292 maxchild = CHILD_MAX;
293# else
294# if defined (MAXUPRC)
295 maxchild = MAXUPRC;
296# endif /* MAXUPRC */
297# endif /* CHILD_MAX */
298#endif /* !HAVE_SYSCONF || !_SC_CHILD_MAX */
299
300 return (maxchild);
301}