Line data Source code
1 : /* oslib.c - functions present only in some unix versions. */
2 :
3 : /* Copyright (C) 1995,2010 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
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.
11 :
12 : 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.
16 :
17 : 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 : */
20 :
21 : #include <config.h>
22 :
23 : #include <bashtypes.h>
24 : #if defined (HAVE_SYS_PARAM_H)
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 : #if !defined (HAVE_KILLPG)
41 : # include <signal.h>
42 : #endif
43 :
44 : #include <stdio.h>
45 : #include <errno.h>
46 : #include <chartypes.h>
47 :
48 : #include <shell.h>
49 :
50 : #if !defined (errno)
51 : extern int errno;
52 : #endif /* !errno */
53 :
54 : /* Make the functions strchr and strrchr if they do not exist. */
55 : #if !defined (HAVE_STRCHR)
56 : char *
57 : strchr (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 :
70 : char *
71 : strrchr (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. */
87 : int
88 : dup2 (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 : *
127 : * On some systems, like 4.2BSD and its descendants, there is a system call
128 : * 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)
145 : int
146 : getdtablesize ()
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)
165 : # if defined (bcopy)
166 : # undef bcopy
167 : # endif
168 : void
169 : bcopy (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)
178 : # if defined (bzero)
179 : # undef bzero
180 : # endif
181 : void
182 : bzero (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>
197 : int
198 : gethostname (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 */
214 : int
215 : gethostname (name, namelen)
216 : char *name;
217 : int namelen;
218 : {
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)
227 : int
228 : killpg (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)
237 : int
238 : mkfifo (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 */
249 :
250 : #define DEFAULT_MAXGROUPS 64
251 :
252 : int
253 0 : getmaxgroups ()
254 : {
255 0 : static int maxgroups = -1;
256 :
257 0 : if (maxgroups > 0)
258 : return maxgroups;
259 :
260 : #if defined (HAVE_SYSCONF) && defined (_SC_NGROUPS_MAX)
261 0 : 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 0 : if (maxgroups <= 0)
275 0 : maxgroups = DEFAULT_MAXGROUPS;
276 :
277 0 : return maxgroups;
278 : }
279 :
280 : long
281 9143267 : getmaxchild ()
282 : {
283 9143267 : static long maxchild = -1L;
284 :
285 9143267 : if (maxchild > 0)
286 : return maxchild;
287 :
288 : #if defined (HAVE_SYSCONF) && defined (_SC_CHILD_MAX)
289 9143258 : 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 9143258 : return (maxchild);
301 : }
|