compat.c revision 2311
12311Sjkh/* Copyright 1988,1990,1993,1994 by Paul Vixie 22311Sjkh * All rights reserved 32311Sjkh * 42311Sjkh * Distribute freely, except: don't remove my name from the source or 52311Sjkh * documentation (don't take credit for my work), mark your changes (don't 62311Sjkh * get me blamed for your possible bugs), don't alter or remove this 72311Sjkh * notice. May be sold if buildable source is provided to buyer. No 82311Sjkh * warrantee of any kind, express or implied, is included with this 92311Sjkh * software; use at your own risk, responsibility for damages (if any) to 102311Sjkh * anyone resulting from the use of this software rests entirely with the 112311Sjkh * user. 122311Sjkh * 132311Sjkh * Send bug reports, bug fixes, enhancements, requests, flames, etc., and 142311Sjkh * I'll try to keep a version up to date. I can be reached as follows: 152311Sjkh * Paul Vixie <paul@vix.com> uunet!decwrl!vixie!paul 162311Sjkh */ 172311Sjkh 182311Sjkh#if !defined(lint) && !defined(LINT) 192311Sjkhstatic char rcsid[] = "$Id: compat.c,v 1.6 1994/01/15 20:43:43 vixie Exp $"; 202311Sjkh#endif 212311Sjkh 222311Sjkh/* vix 30dec93 [broke this out of misc.c - see RCS log for history] 232311Sjkh * vix 15jan87 [added TIOCNOTTY, thanks csg@pyramid] 242311Sjkh */ 252311Sjkh 262311Sjkh 272311Sjkh#include "cron.h" 282311Sjkh#ifdef NEED_GETDTABLESIZE 292311Sjkh# include <limits.h> 302311Sjkh#endif 312311Sjkh#if defined(NEED_SETSID) && defined(BSD) 322311Sjkh# include <sys/ioctl.h> 332311Sjkh#endif 342311Sjkh#include <errno.h> 352311Sjkh 362311Sjkh 372311Sjkh/* the code does not depend on any of vfork's 382311Sjkh * side-effects; it just uses it as a quick 392311Sjkh * fork-and-exec. 402311Sjkh */ 412311Sjkh#ifdef NEED_VFORK 422311SjkhPID_T 432311Sjkhvfork() { 442311Sjkh return (fork()); 452311Sjkh} 462311Sjkh#endif 472311Sjkh 482311Sjkh 492311Sjkh#ifdef NEED_STRDUP 502311Sjkhchar * 512311Sjkhstrdup(str) 522311Sjkh char *str; 532311Sjkh{ 542311Sjkh char *temp; 552311Sjkh 562311Sjkh temp = malloc(strlen(str) + 1); 572311Sjkh (void) strcpy(temp, str); 582311Sjkh return temp; 592311Sjkh} 602311Sjkh#endif 612311Sjkh 622311Sjkh 632311Sjkh#ifdef NEED_STRERROR 642311Sjkhchar * 652311Sjkhstrerror(error) 662311Sjkh int error; 672311Sjkh{ 682311Sjkh extern char *sys_errlist[]; 692311Sjkh extern int sys_nerr; 702311Sjkh static char buf[32]; 712311Sjkh 722311Sjkh if ((error <= sys_nerr) && (error > 0)) { 732311Sjkh return sys_errlist[error]; 742311Sjkh } 752311Sjkh 762311Sjkh sprintf(buf, "Unknown error: %d", error); 772311Sjkh return buf; 782311Sjkh} 792311Sjkh#endif 802311Sjkh 812311Sjkh 822311Sjkh#ifdef NEED_STRCASECMP 832311Sjkhint 842311Sjkhstrcasecmp(left, right) 852311Sjkh char *left; 862311Sjkh char *right; 872311Sjkh{ 882311Sjkh while (*left && (MkLower(*left) == MkLower(*right))) { 892311Sjkh left++; 902311Sjkh right++; 912311Sjkh } 922311Sjkh return MkLower(*left) - MkLower(*right); 932311Sjkh} 942311Sjkh#endif 952311Sjkh 962311Sjkh 972311Sjkh#ifdef NEED_SETSID 982311Sjkhint 992311Sjkhsetsid() 1002311Sjkh{ 1012311Sjkh int newpgrp; 1022311Sjkh# if defined(BSD) 1032311Sjkh int fd; 1042311Sjkh# if defined(POSIX) 1052311Sjkh newpgrp = setpgid((pid_t)0, getpid()); 1062311Sjkh# else 1072311Sjkh newpgrp = setpgrp(0, getpid()); 1082311Sjkh# endif 1092311Sjkh if ((fd = open("/dev/tty", 2)) >= 0) 1102311Sjkh { 1112311Sjkh (void) ioctl(fd, TIOCNOTTY, (char*)0); 1122311Sjkh (void) close(fd); 1132311Sjkh } 1142311Sjkh# else /*BSD*/ 1152311Sjkh newpgrp = setpgrp(); 1162311Sjkh 1172311Sjkh (void) close(STDIN); (void) open("/dev/null", 0); 1182311Sjkh (void) close(STDOUT); (void) open("/dev/null", 1); 1192311Sjkh (void) close(STDERR); (void) open("/dev/null", 2); 1202311Sjkh# endif /*BSD*/ 1212311Sjkh return newpgrp; 1222311Sjkh} 1232311Sjkh#endif /*NEED_SETSID*/ 1242311Sjkh 1252311Sjkh 1262311Sjkh#ifdef NEED_GETDTABLESIZE 1272311Sjkhint 1282311Sjkhgetdtablesize() { 1292311Sjkh#ifdef _SC_OPEN_MAX 1302311Sjkh return sysconf(_SC_OPEN_MAX); 1312311Sjkh#else 1322311Sjkh return _POSIX_OPEN_MAX; 1332311Sjkh#endif 1342311Sjkh} 1352311Sjkh#endif 1362311Sjkh 1372311Sjkh 1382311Sjkh#ifdef NEED_FLOCK 1392311Sjkh/* The following flock() emulation snarfed intact *) from the HP-UX 1402311Sjkh * "BSD to HP-UX porting tricks" maintained by 1412311Sjkh * system@alchemy.chem.utoronto.ca (System Admin (Mike Peterson)) 1422311Sjkh * from the version "last updated: 11-Jan-1993" 1432311Sjkh * Snarfage done by Jarkko Hietaniemi <Jarkko.Hietaniemi@hut.fi> 1442311Sjkh * *) well, almost, had to K&R the function entry, HPUX "cc" 1452311Sjkh * does not grok ANSI function prototypes */ 1462311Sjkh 1472311Sjkh/* 1482311Sjkh * flock (fd, operation) 1492311Sjkh * 1502311Sjkh * This routine performs some file locking like the BSD 'flock' 1512311Sjkh * on the object described by the int file descriptor 'fd', 1522311Sjkh * which must already be open. 1532311Sjkh * 1542311Sjkh * The operations that are available are: 1552311Sjkh * 1562311Sjkh * LOCK_SH - get a shared lock. 1572311Sjkh * LOCK_EX - get an exclusive lock. 1582311Sjkh * LOCK_NB - don't block (must be ORed with LOCK_SH or LOCK_EX). 1592311Sjkh * LOCK_UN - release a lock. 1602311Sjkh * 1612311Sjkh * Return value: 0 if lock successful, -1 if failed. 1622311Sjkh * 1632311Sjkh * Note that whether the locks are enforced or advisory is 1642311Sjkh * controlled by the presence or absence of the SETGID bit on 1652311Sjkh * the executable. 1662311Sjkh * 1672311Sjkh * Note that there is no difference between shared and exclusive 1682311Sjkh * locks, since the 'lockf' system call in SYSV doesn't make any 1692311Sjkh * distinction. 1702311Sjkh * 1712311Sjkh * The file "<sys/file.h>" should be modified to contain the definitions 1722311Sjkh * of the available operations, which must be added manually (see below 1732311Sjkh * for the values). 1742311Sjkh */ 1752311Sjkh 1762311Sjkh/* this code has been reformatted by vixie */ 1772311Sjkh 1782311Sjkhint 1792311Sjkhflock(fd, operation) 1802311Sjkh int fd; 1812311Sjkh int operation; 1822311Sjkh{ 1832311Sjkh int i; 1842311Sjkh 1852311Sjkh switch (operation) { 1862311Sjkh case LOCK_SH: /* get a shared lock */ 1872311Sjkh case LOCK_EX: /* get an exclusive lock */ 1882311Sjkh i = lockf (fd, F_LOCK, 0); 1892311Sjkh break; 1902311Sjkh 1912311Sjkh case LOCK_SH|LOCK_NB: /* get a non-blocking shared lock */ 1922311Sjkh case LOCK_EX|LOCK_NB: /* get a non-blocking exclusive lock */ 1932311Sjkh i = lockf (fd, F_TLOCK, 0); 1942311Sjkh if (i == -1) 1952311Sjkh if ((errno == EAGAIN) || (errno == EACCES)) 1962311Sjkh errno = EWOULDBLOCK; 1972311Sjkh break; 1982311Sjkh 1992311Sjkh case LOCK_UN: /* unlock */ 2002311Sjkh i = lockf (fd, F_ULOCK, 0); 2012311Sjkh break; 2022311Sjkh 2032311Sjkh default: /* can't decipher operation */ 2042311Sjkh i = -1; 2052311Sjkh errno = EINVAL; 2062311Sjkh break; 2072311Sjkh } 2082311Sjkh 2092311Sjkh return (i); 2102311Sjkh} 2112311Sjkh#endif /*NEED_FLOCK*/ 2122311Sjkh 2132311Sjkh 2142311Sjkh#ifdef NEED_SETENV 2152311Sjkhint 2162311Sjkhsetenv(name, value, overwrite) 2172311Sjkh char *name, *value; 2182311Sjkh int overwrite; 2192311Sjkh{ 2202311Sjkh char *tmp; 2212311Sjkh 2222311Sjkh if (overwrite && getenv(name)) 2232311Sjkh return -1; 2242311Sjkh 2252311Sjkh if (!(tmp = malloc(strlen(name) + strlen(value) + 2))) { 2262311Sjkh errno = ENOMEM; 2272311Sjkh return -1; 2282311Sjkh } 2292311Sjkh 2302311Sjkh sprintf("%s=%s", name, value); 2312311Sjkh return putenv(tmp); /* intentionally orphan 'tmp' storage */ 2322311Sjkh} 2332311Sjkh#endif 234