compat.c revision 20573
1/* Copyright 1988,1990,1993,1994 by Paul Vixie
2 * All rights reserved
3 *
4 * Distribute freely, except: don't remove my name from the source or
5 * documentation (don't take credit for my work), mark your changes (don't
6 * get me blamed for your possible bugs), don't alter or remove this
7 * notice.  May be sold if buildable source is provided to buyer.  No
8 * warrantee of any kind, express or implied, is included with this
9 * software; use at your own risk, responsibility for damages (if any) to
10 * anyone resulting from the use of this software rests entirely with the
11 * user.
12 *
13 * Send bug reports, bug fixes, enhancements, requests, flames, etc., and
14 * I'll try to keep a version up to date.  I can be reached as follows:
15 * Paul Vixie          <paul@vix.com>          uunet!decwrl!vixie!paul
16 */
17
18#if !defined(lint) && !defined(LINT)
19static char rcsid[] = "$Id: compat.c,v 1.2 1996/11/01 23:27:28 millert Exp $";
20#endif
21
22/* vix 30dec93 [broke this out of misc.c - see RCS log for history]
23 * vix 15jan87 [added TIOCNOTTY, thanks csg@pyramid]
24 */
25
26
27#include "cron.h"
28#ifdef NEED_GETDTABLESIZE
29# include <limits.h>
30#endif
31#if defined(NEED_SETSID) && defined(BSD)
32# include <sys/ioctl.h>
33#endif
34#include <errno.h>
35
36
37/* the code does not depend on any of vfork's
38 * side-effects; it just uses it as a quick
39 * fork-and-exec.
40 */
41#ifdef NEED_VFORK
42PID_T
43vfork() {
44	return (fork());
45}
46#endif
47
48
49#ifdef NEED_STRDUP
50char *
51strdup(str)
52	char	*str;
53{
54	char	*temp;
55
56	if ((temp = malloc(strlen(str) + 1)) == NULL) {
57		errno = ENOMEM;
58		return NULL;
59	}
60	(void) strcpy(temp, str);
61	return temp;
62}
63#endif
64
65
66#ifdef NEED_STRERROR
67char *
68strerror(error)
69	int error;
70{
71	extern char *sys_errlist[];
72	extern int sys_nerr;
73	static char buf[32];
74
75	if ((error <= sys_nerr) && (error > 0)) {
76		return sys_errlist[error];
77	}
78
79	sprintf(buf, "Unknown error: %d", error);
80	return buf;
81}
82#endif
83
84
85#ifdef NEED_STRCASECMP
86int
87strcasecmp(left, right)
88	char	*left;
89	char	*right;
90{
91	while (*left && (MkLower(*left) == MkLower(*right))) {
92		left++;
93		right++;
94	}
95	return MkLower(*left) - MkLower(*right);
96}
97#endif
98
99
100#ifdef NEED_SETSID
101int
102setsid()
103{
104	int	newpgrp;
105# if defined(BSD)
106	int	fd;
107#  if defined(POSIX)
108	newpgrp = setpgid((pid_t)0, getpid());
109#  else
110	newpgrp = setpgrp(0, getpid());
111#  endif
112	if ((fd = open("/dev/tty", 2)) >= 0)
113	{
114		(void) ioctl(fd, TIOCNOTTY, (char*)0);
115		(void) close(fd);
116	}
117# else /*BSD*/
118	newpgrp = setpgrp();
119
120	(void) close(STDIN);	(void) open("/dev/null", 0);
121	(void) close(STDOUT);	(void) open("/dev/null", 1);
122	(void) close(STDERR);	(void) open("/dev/null", 2);
123# endif /*BSD*/
124	return newpgrp;
125}
126#endif /*NEED_SETSID*/
127
128
129#ifdef NEED_GETDTABLESIZE
130int
131getdtablesize() {
132#ifdef _SC_OPEN_MAX
133	return sysconf(_SC_OPEN_MAX);
134#else
135	return _POSIX_OPEN_MAX;
136#endif
137}
138#endif
139
140
141#ifdef NEED_FLOCK
142/* The following flock() emulation snarfed intact *) from the HP-UX
143 * "BSD to HP-UX porting tricks" maintained by
144 * system@alchemy.chem.utoronto.ca (System Admin (Mike Peterson))
145 * from the version "last updated: 11-Jan-1993"
146 * Snarfage done by Jarkko Hietaniemi <Jarkko.Hietaniemi@hut.fi>
147 * *) well, almost, had to K&R the function entry, HPUX "cc"
148 * does not grok ANSI function prototypes */
149
150/*
151 * flock (fd, operation)
152 *
153 * This routine performs some file locking like the BSD 'flock'
154 * on the object described by the int file descriptor 'fd',
155 * which must already be open.
156 *
157 * The operations that are available are:
158 *
159 * LOCK_SH  -  get a shared lock.
160 * LOCK_EX  -  get an exclusive lock.
161 * LOCK_NB  -  don't block (must be ORed with LOCK_SH or LOCK_EX).
162 * LOCK_UN  -  release a lock.
163 *
164 * Return value: 0 if lock successful, -1 if failed.
165 *
166 * Note that whether the locks are enforced or advisory is
167 * controlled by the presence or absence of the SETGID bit on
168 * the executable.
169 *
170 * Note that there is no difference between shared and exclusive
171 * locks, since the 'lockf' system call in SYSV doesn't make any
172 * distinction.
173 *
174 * The file "<sys/file.h>" should be modified to contain the definitions
175 * of the available operations, which must be added manually (see below
176 * for the values).
177 */
178
179/* this code has been reformatted by vixie */
180
181int
182flock(fd, operation)
183	int fd;
184	int operation;
185{
186	int i;
187
188	switch (operation) {
189	case LOCK_SH:		/* get a shared lock */
190	case LOCK_EX:		/* get an exclusive lock */
191		i = lockf (fd, F_LOCK, 0);
192		break;
193
194	case LOCK_SH|LOCK_NB:	/* get a non-blocking shared lock */
195	case LOCK_EX|LOCK_NB:	/* get a non-blocking exclusive lock */
196		i = lockf (fd, F_TLOCK, 0);
197		if (i == -1)
198			if ((errno == EAGAIN) || (errno == EACCES))
199				errno = EWOULDBLOCK;
200		break;
201
202	case LOCK_UN:		/* unlock */
203		i = lockf (fd, F_ULOCK, 0);
204		break;
205
206	default:		/* can't decipher operation */
207		i = -1;
208		errno = EINVAL;
209		break;
210	}
211
212	return (i);
213}
214#endif /*NEED_FLOCK*/
215
216
217#ifdef NEED_SETENV
218int
219setenv(name, value, overwrite)
220	char *name, *value;
221	int overwrite;
222{
223	char *tmp;
224
225	if (overwrite && getenv(name))
226		return -1;
227
228	if (!(tmp = malloc(strlen(name) + strlen(value) + 2))) {
229		errno = ENOMEM;
230		return -1;
231	}
232
233	sprintf(tmp, "%s=%s", name, value);
234	return putenv(tmp);	/* intentionally orphan 'tmp' storage */
235}
236#endif
237