]> git.ipfire.org Git - thirdparty/bash.git/blob - lib/sh/oslib.c
Bash-4.3 distribution sources and documentation
[thirdparty/bash.git] / lib / sh / oslib.c
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 getmaxgroups ()
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
280 long
281 getmaxchild ()
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 }