1/* 2 * compat.c 3 * 4 * Compatibility functions for different OSes 5 * 6 * $Id: compat.c,v 1.6 2005/08/22 00:48:34 quozl Exp $ 7 */ 8 9#if HAVE_CONFIG_H 10#include "config.h" 11#endif 12 13#include "compat.h" 14 15#ifndef HAVE_STRLCPY 16#include <string.h> 17#include <stdio.h> 18 19void strlcpy(char *dst, const char *src, size_t size) 20{ 21 strncpy(dst, src, size - 1); 22 dst[size - 1] = '\0'; 23} 24#endif 25 26#ifndef HAVE_MEMMOVE 27void *memmove(void *dst, const void *src, size_t size) 28{ 29 bcopy(src, dst, size); 30 return dst; 31} 32#endif 33 34#ifndef HAVE_OPENPTY 35/* 36 * Finds a free PTY/TTY pair. 37 * 38 * This is derived from C.S. Ananian's pty.c that was with his pptp client. 39 * 40 ************************************************************************* 41 * pty.c - find a free pty/tty pair. 42 * inspired by the xterm source. 43 * NOTE: This is very likely to be highly non-portable. 44 * C. Scott Ananian <cananian@alumni.princeton.edu> 45 * 46 * Heavily modified to chage from getpseudopty() to openpty(). 47 */ 48 49#include <sys/types.h> 50#include <sys/stat.h> 51#include <fcntl.h> 52#if HAVE_SYSLOG_H 53#include <syslog.h> 54#else 55#include "our_syslog.h" 56#endif 57 58int openpty(int *master, int *slave, char *name, void *unused1, void *unused2) 59{ 60 int devindex = 0, letter = 0; 61 int fd1, fd2; 62 char ttydev[PTYMAX], ptydev[TTYMAX]; 63 64 syslog(LOG_DEBUG, "CTRL: Allocating pty/tty pair"); 65 strcpy(ttydev, TTYDEV); 66 strcpy(ptydev, PTYDEV); 67 while (PTYCHAR1[letter]) { 68 ttydev[TTYMAX - 3] = ptydev[PTYMAX - 3] = PTYCHAR1[letter]; 69 while (PTYCHAR2[devindex]) { 70 ttydev[TTYMAX - 2] = ptydev[PTYMAX - 2] = PTYCHAR2[devindex]; 71 if ((fd1 = open(ptydev, O_RDWR)) >= 0) { 72 if ((fd2 = open(ttydev, O_RDWR)) >= 0) { 73 goto out; 74 } else { 75 close(fd1); 76 } 77 } 78 devindex++; 79 } 80 devindex = 0; 81 letter++; 82 } 83 syslog(LOG_ERR, "CTRL: Failed to allocate pty"); 84 return -1; /* Unable to allocate pty */ 85 86 out: 87 syslog(LOG_INFO, "CTRL: Allocated pty/tty pair (%s,%s)", ptydev, ttydev); 88 if (master) 89 *master = fd1; 90 if (slave) 91 *slave = fd2; 92 if (name) 93 strcpy(name, ttydev); /* no way to bounds check */ 94 return 0; 95} 96#endif 97 98#ifndef HAVE_STRERROR 99char *strerror(int errnum) { 100 static char buf[16]; 101 sprintf(buf, "Error %d", errnum); 102 return buf; 103} 104#endif 105 106#ifndef HAVE_SETPROCTITLE 107#include "inststr.h" 108#endif 109 110#define __USE_BSD 1 111#include <stdarg.h> 112#include <stdio.h> 113 114void my_setproctitle(int argc, char **argv, const char *format, ...) { 115 char proctitle[64]; 116 va_list parms; 117 va_start(parms, format); 118 vsnprintf(proctitle, sizeof(proctitle), format, parms); 119 120#ifndef HAVE_SETPROCTITLE 121 inststr(argc, argv, proctitle); 122#else 123 setproctitle(proctitle); 124#endif 125 va_end(parms); 126} 127 128/* signal to pipe delivery implementation */ 129#include <unistd.h> 130#include <fcntl.h> 131#include <signal.h> 132 133/* pipe private to process */ 134static int sigpipe[2]; 135 136/* create a signal pipe, returns 0 for success, -1 with errno for failure */ 137int sigpipe_create() 138{ 139 int rc; 140 141 rc = pipe(sigpipe); 142 if (rc < 0) return rc; 143 144 fcntl(sigpipe[0], F_SETFD, FD_CLOEXEC); 145 fcntl(sigpipe[1], F_SETFD, FD_CLOEXEC); 146 147#ifdef O_NONBLOCK 148#define FLAG_TO_SET O_NONBLOCK 149#else 150#ifdef SYSV 151#define FLAG_TO_SET O_NDELAY 152#else /* BSD */ 153#define FLAG_TO_SET FNDELAY 154#endif 155#endif 156 157 rc = fcntl(sigpipe[1], F_GETFL); 158 if (rc != -1) 159 rc = fcntl(sigpipe[1], F_SETFL, rc | FLAG_TO_SET); 160 if (rc < 0) return rc; 161 return 0; 162#undef FLAG_TO_SET 163} 164 165/* generic handler for signals, writes signal number to pipe */ 166void sigpipe_handler(int signum) 167{ 168 write(sigpipe[1], &signum, sizeof(signum)); 169 signal(signum, sigpipe_handler); 170} 171 172/* assign a signal number to the pipe */ 173void sigpipe_assign(int signum) 174{ 175 struct sigaction sa; 176 177 memset(&sa, 0, sizeof(sa)); 178 sa.sa_handler = sigpipe_handler; 179 sigaction(signum, &sa, NULL); 180} 181 182/* return the signal pipe read file descriptor for select(2) */ 183int sigpipe_fd() 184{ 185 return sigpipe[0]; 186} 187 188/* read and return the pending signal from the pipe */ 189int sigpipe_read() 190{ 191 int signum; 192 read(sigpipe[0], &signum, sizeof(signum)); 193 return signum; 194} 195 196void sigpipe_close() 197{ 198 close(sigpipe[0]); 199 close(sigpipe[1]); 200} 201 202