90d7be9a7fb39b3cd67ce64f88d463b99b700fec
[platform/upstream/bash.git] / lib / sh / oslib.c
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)
47 extern int errno;
48 #endif /* !errno */
49
50 /* Make the functions strchr and strrchr if they do not exist. */
51 #if !defined (HAVE_STRCHR)
52 char *
53 strchr (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
66 char *
67 strrchr (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. */
83 int
84 dup2 (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)
141 int
142 getdtablesize ()
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
164 void
165 bcopy (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
177 void
178 bzero (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>
193 int
194 gethostname (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 */
210 int
211 gethostname (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)
222 int
223 killpg (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)
232 int
233 mkfifo (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
247 int
248 getmaxgroups ()
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
275 long
276 getmaxchild ()
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 }