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 * $FreeBSD: src/usr.sbin/cron/lib/compat.c,v 1.6.2.1 2000/12/11 01:03:31 obrien Exp $ 18 * $DragonFly: src/usr.sbin/cron/lib/compat.c,v 1.4 2004/12/18 22:48:03 swildner Exp $ 19 */ 20 21 /* vix 30dec93 [broke this out of misc.c - see RCS log for history] 22 * vix 15jan87 [added TIOCNOTTY, thanks csg@pyramid] 23 */ 24 25 26 #include "cron.h" 27 #ifdef NEED_GETDTABLESIZE 28 # include <limits.h> 29 #endif 30 #if defined(NEED_SETSID) && defined(BSD) 31 # include <sys/ioctl.h> 32 #endif 33 #include <errno.h> 34 #include <paths.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 42 PID_T 43 vfork(void) 44 { 45 return (fork()); 46 } 47 #endif 48 49 50 #ifdef NEED_STRDUP 51 char * 52 strdup(char *str) 53 { 54 char *temp; 55 56 if ((temp = malloc(strlen(str) + 1)) == NULL) { 57 errno = ENOMEM; 58 return NULL; 59 } 60 strcpy(temp, str); 61 return temp; 62 } 63 #endif 64 65 66 #ifdef NEED_STRERROR 67 char * 68 strerror(int error) 69 { 70 extern char *sys_errlist[]; 71 extern int sys_nerr; 72 static char buf[32]; 73 74 if ((error <= sys_nerr) && (error > 0)) { 75 return sys_errlist[error]; 76 } 77 78 sprintf(buf, "Unknown error: %d", error); 79 return buf; 80 } 81 #endif 82 83 84 #ifdef NEED_STRCASECMP 85 int 86 strcasecmp(char *left, char *right) 87 { 88 while (*left && (MkLower(*left) == MkLower(*right))) { 89 left++; 90 right++; 91 } 92 return MkLower(*left) - MkLower(*right); 93 } 94 #endif 95 96 97 #ifdef NEED_SETSID 98 int 99 setsid(void) 100 { 101 int newpgrp; 102 # if defined(BSD) 103 int fd; 104 # if defined(POSIX) 105 newpgrp = setpgid((pid_t)0, getpid()); 106 # else 107 newpgrp = setpgrp(0, getpid()); 108 # endif 109 if ((fd = open(_PATH_TTY, 2)) >= 0) 110 { 111 ioctl(fd, TIOCNOTTY, NULL); 112 close(fd); 113 } 114 # else /*BSD*/ 115 newpgrp = setpgrp(); 116 117 close(STDIN); open(_PATH_DEVNULL, 0); 118 close(STDOUT); open(_PATH_DEVNULL, 1); 119 close(STDERR); open(_PATH_DEVNULL, 2); 120 # endif /*BSD*/ 121 return newpgrp; 122 } 123 #endif /*NEED_SETSID*/ 124 125 126 #ifdef NEED_GETDTABLESIZE 127 int 128 getdtablesize(void) 129 { 130 #ifdef _SC_OPEN_MAX 131 return sysconf(_SC_OPEN_MAX); 132 #else 133 return _POSIX_OPEN_MAX; 134 #endif 135 } 136 #endif 137 138 139 #ifdef NEED_FLOCK 140 /* The following flock() emulation snarfed intact *) from the HP-UX 141 * "BSD to HP-UX porting tricks" maintained by 142 * system@alchemy.chem.utoronto.ca (System Admin (Mike Peterson)) 143 * from the version "last updated: 11-Jan-1993" 144 * Snarfage done by Jarkko Hietaniemi <Jarkko.Hietaniemi@hut.fi> 145 * *) well, almost, had to K&R the function entry, HPUX "cc" 146 * does not grok ANSI function prototypes */ 147 148 /* 149 * flock (fd, operation) 150 * 151 * This routine performs some file locking like the BSD 'flock' 152 * on the object described by the int file descriptor 'fd', 153 * which must already be open. 154 * 155 * The operations that are available are: 156 * 157 * LOCK_SH - get a shared lock. 158 * LOCK_EX - get an exclusive lock. 159 * LOCK_NB - don't block (must be ORed with LOCK_SH or LOCK_EX). 160 * LOCK_UN - release a lock. 161 * 162 * Return value: 0 if lock successful, -1 if failed. 163 * 164 * Note that whether the locks are enforced or advisory is 165 * controlled by the presence or absence of the SETGID bit on 166 * the executable. 167 * 168 * Note that there is no difference between shared and exclusive 169 * locks, since the 'lockf' system call in SYSV doesn't make any 170 * distinction. 171 * 172 * The file "<sys/file.h>" should be modified to contain the definitions 173 * of the available operations, which must be added manually (see below 174 * for the values). 175 */ 176 177 /* this code has been reformatted by vixie */ 178 179 int 180 flock(int fd, int operation) 181 { 182 int i; 183 184 switch (operation) { 185 case LOCK_SH: /* get a shared lock */ 186 case LOCK_EX: /* get an exclusive lock */ 187 i = lockf (fd, F_LOCK, 0); 188 break; 189 190 case LOCK_SH|LOCK_NB: /* get a non-blocking shared lock */ 191 case LOCK_EX|LOCK_NB: /* get a non-blocking exclusive lock */ 192 i = lockf (fd, F_TLOCK, 0); 193 if (i == -1) 194 if ((errno == EAGAIN) || (errno == EACCES)) 195 errno = EWOULDBLOCK; 196 break; 197 198 case LOCK_UN: /* unlock */ 199 i = lockf (fd, F_ULOCK, 0); 200 break; 201 202 default: /* can't decipher operation */ 203 i = -1; 204 errno = EINVAL; 205 break; 206 } 207 208 return (i); 209 } 210 #endif /*NEED_FLOCK*/ 211 212 213 #ifdef NEED_SETENV 214 int 215 setenv(char *name, char *value, int overwrite) 216 { 217 char *tmp; 218 219 if (overwrite && getenv(name)) 220 return -1; 221 222 if (!(tmp = malloc(strlen(name) + strlen(value) + 2))) { 223 errno = ENOMEM; 224 return -1; 225 } 226 227 sprintf(tmp, "%s=%s", name, value); 228 return putenv(tmp); /* intentionally orphan 'tmp' storage */ 229 } 230 #endif 231