Imported from ../bash-2.05a.tar.gz.
[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 #include <posixstat.h>
33 #include <filecntl.h>
34 #include <bashansi.h>
35
36 #include <stdio.h>
37 #include <errno.h>
38 #include <chartypes.h>
39
40 #include <shell.h>
41
42 #if !defined (errno)
43 extern int errno;
44 #endif /* !errno */
45
46 /* Make the functions strchr and strrchr if they do not exist. */
47 #if !defined (HAVE_STRCHR)
48 char *
49 strchr (string, c)
50      char *string;
51      int c;
52 {
53   register char *s;
54
55   for (s = string; s && *s; s++)
56     if (*s == c)
57       return (s);
58
59   return ((char *) NULL);
60 }
61
62 char *
63 strrchr (string, c)
64      char *string;
65      int c;
66 {
67   register char *s, *t;
68
69   for (s = string, t = (char *)NULL; s && *s; s++)
70     if (*s == c)
71       t = s;
72   return (t);
73 }
74 #endif /* !HAVE_STRCHR */
75
76 #if !defined (HAVE_DUP2) || defined (DUP2_BROKEN)
77 /* Replacement for dup2 (), for those systems which either don't have it,
78    or supply one with broken behaviour. */
79 int
80 dup2 (fd1, fd2)
81      int fd1, fd2;
82 {
83   int saved_errno, r;
84
85   /* If FD1 is not a valid file descriptor, then return immediately with
86      an error. */
87   if (fcntl (fd1, F_GETFL, 0) == -1)
88     return (-1);
89
90   if (fd2 < 0 || fd2 >= getdtablesize ())
91     {
92       errno = EBADF;
93       return (-1);
94     }
95
96   if (fd1 == fd2)
97     return (0);
98
99   saved_errno = errno;
100
101   (void) close (fd2);
102   r = fcntl (fd1, F_DUPFD, fd2);
103
104   if (r >= 0)
105     errno = saved_errno;
106   else
107     if (errno == EINVAL)
108       errno = EBADF;
109
110   /* Force the new file descriptor to remain open across exec () calls. */
111   SET_OPEN_ON_EXEC (fd2);
112   return (r);
113 }
114 #endif /* !HAVE_DUP2 */
115
116 /*
117  * Return the total number of available file descriptors.
118  *
119  * On some systems, like 4.2BSD and its descendents, there is a system call
120  * that returns the size of the descriptor table: getdtablesize().  There are
121  * lots of ways to emulate this on non-BSD systems.
122  *
123  * On System V.3, this can be obtained via a call to ulimit:
124  *      return (ulimit(4, 0L));
125  *
126  * On other System V systems, NOFILE is defined in /usr/include/sys/param.h
127  * (this is what we assume below), so we can simply use it:
128  *      return (NOFILE);
129  *
130  * On POSIX systems, there are specific functions for retrieving various
131  * configuration parameters:
132  *      return (sysconf(_SC_OPEN_MAX));
133  *
134  */
135
136 #if !defined (HAVE_GETDTABLESIZE)
137 int
138 getdtablesize ()
139 {
140 #  if defined (_POSIX_VERSION) && defined (HAVE_SYSCONF) && defined (_SC_OPEN_MAX)
141   return (sysconf(_SC_OPEN_MAX));       /* Posix systems use sysconf */
142 #  else /* ! (_POSIX_VERSION && HAVE_SYSCONF && _SC_OPEN_MAX) */
143 #    if defined (ULIMIT_MAXFDS)
144   return (ulimit (4, 0L));      /* System V.3 systems use ulimit(4, 0L) */
145 #    else /* !ULIMIT_MAXFDS */
146 #      if defined (NOFILE)      /* Other systems use NOFILE */
147   return (NOFILE);
148 #      else /* !NOFILE */
149   return (20);                  /* XXX - traditional value is 20 */
150 #      endif /* !NOFILE */
151 #    endif /* !ULIMIT_MAXFDS */
152 #  endif /* ! (_POSIX_VERSION && _SC_OPEN_MAX) */
153 }
154 #endif /* !HAVE_GETDTABLESIZE */
155
156 #if !defined (HAVE_BCOPY)
157 #  if defined (bcopy)
158 #    undef bcopy
159 #  endif
160 void
161 bcopy (s,d,n)
162      char *d, *s;
163      int n;
164 {
165   FASTCOPY (s, d, n);
166 }
167 #endif /* !HAVE_BCOPY */
168
169 #if !defined (HAVE_BZERO)
170 #  if defined (bzero)
171 #    undef bzero
172 #  endif
173 void
174 bzero (s, n)
175      char *s;
176      int n;
177 {
178   register int i;
179   register char *r;
180
181   for (i = 0, r = s; i < n; i++)
182     *r++ = '\0';
183 }
184 #endif
185
186 #if !defined (HAVE_GETHOSTNAME)
187 #  if defined (HAVE_UNAME)
188 #    include <sys/utsname.h>
189 int
190 gethostname (name, namelen)
191      char *name;
192      int namelen;
193 {
194   int i;
195   struct utsname ut;
196
197   --namelen;
198
199   uname (&ut);
200   i = strlen (ut.nodename) + 1;
201   strncpy (name, ut.nodename, i < namelen ? i : namelen);
202   name[namelen] = '\0';
203   return (0);
204 }
205 #  else /* !HAVE_UNAME */
206 int
207 gethostname (name, namelen)
208      int name, namelen;
209 {
210   strncpy (name, "unknown", namelen);
211   name[namelen] = '\0';
212   return 0;
213 }
214 #  endif /* !HAVE_UNAME */
215 #endif /* !HAVE_GETHOSTNAME */
216
217 #if !defined (HAVE_KILLPG)
218 int
219 killpg (pgrp, sig)
220      pid_t pgrp;
221      int sig;
222 {
223   return (kill (-pgrp, sig));
224 }
225 #endif /* !HAVE_KILLPG */
226
227 #if !defined (HAVE_MKFIFO) && defined (PROCESS_SUBSTITUTION)
228 int
229 mkfifo (path, mode)
230      char *path;
231      int mode;
232 {
233 #if defined (S_IFIFO)
234   return (mknod (path, (mode | S_IFIFO), 0));
235 #else /* !S_IFIFO */
236   return (-1);
237 #endif /* !S_IFIFO */
238 }
239 #endif /* !HAVE_MKFIFO && PROCESS_SUBSTITUTION */