No specific user configuration
[platform/upstream/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 }