compat.c 4.6 KB

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