home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mitsch75.zip / scheme-7_5_17-src.zip / scheme-7.5.17 / src / microcode / ux.c < prev    next >
C/C++ Source or Header  |  2000-12-05  |  14KB  |  670 lines

  1. /* -*-C-*-
  2.  
  3. $Id: ux.c,v 1.20 2000/12/05 21:23:48 cph Exp $
  4.  
  5. Copyright (c) 1990-2000 Massachusetts Institute of Technology
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or (at
  10. your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful, but
  13. WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15. General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21.  
  22. #include "ux.h"
  23.  
  24. void
  25. DEFUN (UX_prim_check_errno, (name), enum syscall_names name)
  26. {
  27.   if (errno != EINTR)
  28.     error_system_call (errno, name);
  29.   deliver_pending_interrupts ();
  30. }
  31.  
  32. #ifdef HAVE_TERMIOS_H
  33.  
  34. int
  35. DEFUN (UX_terminal_get_state, (fd, s), int fd AND Ttty_state * s)
  36. {
  37.   return
  38.     ((((tcgetattr (fd, (& (s -> tio)))) < 0)
  39. #ifdef __HPUX__
  40.       || ((UX_ioctl (fd, TIOCGLTC, (& (s -> ltc)))) < 0)
  41. #endif
  42.       ) ? (-1) : 0);
  43. }
  44.  
  45. int
  46. DEFUN (UX_terminal_set_state, (fd, s), int fd AND Ttty_state * s)
  47. {
  48.   return
  49.     ((((tcsetattr (fd, TCSANOW, (& (s -> tio)))) < 0)
  50. #ifdef __HPUX__
  51.       || ((UX_ioctl (fd, TIOCSLTC, (& (s -> ltc)))) < 0)
  52. #endif
  53.       ) ? (-1) : 0);
  54. }
  55.  
  56. #else /* not HAVE_TERMIOS_H */
  57. #ifdef HAVE_TERMIO_H
  58.  
  59. int
  60. DEFUN (UX_terminal_get_state, (fd, s), int fd AND Ttty_state * s)
  61. {
  62.   return
  63.     ((((UX_ioctl (fd, TCGETA, (& (s -> tio)))) < 0)
  64. #ifdef HAVE_STRUCT_LTCHARS
  65.       || ((UX_ioctl (fd, TIOCGLTC, (& (s -> ltc)))) < 0)
  66. #endif
  67.       ) ? (-1) : 0);
  68. }
  69.  
  70. int
  71. DEFUN (UX_terminal_set_state, (fd, s), int fd AND Ttty_state * s)
  72. {
  73.   return
  74.     ((((UX_ioctl (fd, TCSETA, (& (s -> tio)))) < 0)
  75. #ifdef HAVE_STRUCT_LTCHARS
  76.       || ((UX_ioctl (fd, TIOCSLTC, (& (s -> ltc)))) < 0)
  77. #endif
  78.       ) ? (-1) : 0);
  79. }
  80.  
  81. int
  82. DEFUN (UX_tcdrain, (fd), int fd)
  83. {
  84.   return (UX_ioctl (fd, TCSBRK, 1));
  85. }
  86.  
  87. int
  88. DEFUN (UX_tcflush, (fd, queue_selector), int fd AND int queue_selector)
  89. {
  90.   return (UX_ioctl (fd, TCFLSH, queue_selector));
  91. }
  92.  
  93. #else /* not HAVE_TERMIO_H */
  94.  
  95. #ifdef HAVE_SGTTY_H
  96.  
  97. int
  98. DEFUN (UX_terminal_get_state, (fd, s), int fd AND Ttty_state * s)
  99. {
  100.   return
  101.     ((((UX_ioctl (fd, TIOCGETP, (& (s -> sg)))) < 0)
  102.       || ((UX_ioctl (fd, TIOCGETC, (& (s -> tc)))) < 0)
  103. #ifdef HAVE_STRUCT_LTCHARS
  104.       || ((UX_ioctl (fd, TIOCGLTC, (& (s -> ltc)))) < 0)
  105. #endif
  106.       || ((UX_ioctl (fd, TIOCLGET, (& (s -> lmode)))) < 0))
  107.      ? (-1) : 0);
  108. }
  109.  
  110. int
  111. DEFUN (UX_terminal_set_state, (fd, s), int fd AND Ttty_state * s)
  112. {
  113.   return
  114.     ((((UX_ioctl (fd, TIOCSETN, (& (s -> sg)))) < 0)
  115.       || ((UX_ioctl (fd, TIOCSETC, (& (s -> tc)))) < 0)
  116. #ifdef HAVE_STRUCT_LTCHARS
  117.       || ((UX_ioctl (fd, TIOCSLTC, (& (s -> ltc)))) < 0)
  118. #endif
  119.       || ((UX_ioctl (fd, TIOCLSET, (& (s -> lmode)))) < 0))
  120.      ? (-1) : 0);
  121. }
  122.  
  123. int
  124. DEFUN (UX_tcdrain, (fd), int fd)
  125. {
  126.   /* BSD provides no such feature -- pretend it worked. */
  127.   return (0);
  128. }
  129.  
  130. int
  131. DEFUN (UX_tcflush, (fd, queue_selector), int fd AND int queue_selector)
  132. {
  133.   /* Losing BSD always flushes input and output together. */
  134.   int zero = 0;
  135.   return (UX_ioctl (fd, TIOCFLUSH, (&zero)));
  136. }
  137.  
  138. #endif /* HAVE_SGTTY_H */
  139. #endif /* HAVE_TERMIO_H */
  140. #endif /* HAVE_TERMIOS_H */
  141.  
  142. #ifdef SLAVE_PTY_P
  143. int
  144. DEFUN (UX_setup_slave_pty, (fd), int fd)
  145. {
  146.   return
  147.     (((ioctl (fd, I_PUSH, "ptem")) == 0)
  148.      && ((ioctl (fd, I_PUSH, "ldterm")) == 0)
  149. #if !defined(sgi) && !defined(__sgi)
  150.      && (((ioctl (fd, I_FIND, "ttcompat")) != 0)
  151.      || ((ioctl (fd, I_PUSH, "ttcompat")) == 0))
  152. #endif
  153.      );
  154. }
  155. #endif
  156.  
  157. #ifdef EMULATE_GETPGRP
  158. pid_t
  159. DEFUN_VOID (UX_getpgrp)
  160. {
  161.   return (getpgrp (getpid ()));
  162. }
  163. #endif
  164.  
  165. #ifdef EMULATE_SETSID
  166. pid_t
  167. DEFUN_VOID (UX_setsid)
  168. {
  169. #ifdef TIOCNOTTY
  170.   int fd = (UX_open ("/dev/tty", O_RDWR, 0));
  171.   if (fd >= 0)
  172.     {
  173.       UX_ioctl (fd, TIOCNOTTY, 0);
  174.       UX_close (fd);
  175.     }
  176. #endif
  177.   return (setpgrp (0, 0));
  178. }
  179. #endif
  180.  
  181. #ifdef EMULATE_SETPGID
  182. int
  183. DEFUN (UX_setpgid, (pid, pgid), pid_t pid AND pid_t pgid)
  184. {
  185.   errno = ENOSYS;
  186.   return (-1);
  187. }
  188. #endif
  189.  
  190. #ifdef EMULATE_CTERMID
  191. char *
  192. DEFUN (UX_ctermid, (s), char * s)
  193. {
  194.   static char result [] = "/dev/tty";
  195.   if (s == 0)
  196.     return (result);
  197.   strcpy (s, result);
  198.   return (s);
  199. }
  200. #endif
  201.  
  202. #ifdef EMULATE_KILL
  203. int
  204. DEFUN (UX_kill, (pid, sig), pid_t pid AND int sig)
  205. {
  206.   return ((pid >= 0) ? (kill (pid, sig)) : (killpg ((-pid), sig)));
  207. }
  208. #endif
  209.  
  210. #ifdef EMULATE_TCGETPGRP
  211. pid_t
  212. DEFUN (UX_tcgetpgrp, (fd), int fd)
  213. {
  214. #ifdef TIOCGPGRP
  215.   pid_t pgrp_id;
  216.   return (((UX_ioctl (fd, TIOCGPGRP, (&pgrp_id))) < 0) ? (-1) : pgrp_id);
  217. #else
  218.   errno = ENOSYS;
  219.   return (-1);
  220. #endif
  221. }
  222. #endif
  223.  
  224. #ifdef EMULATE_TCSETPGRP
  225. int
  226. DEFUN (UX_tcsetpgrp, (fd, pgrp_id),
  227.        int fd AND
  228.        pid_t pgrp_id)
  229. {
  230. #ifdef TIOCSPGRP
  231.   return (UX_ioctl (fd, TIOCSPGRP, (&pgrp_id)));
  232. #else
  233.   errno = ENOSYS;
  234.   return (-1);
  235. #endif
  236. }
  237. #endif
  238.  
  239. #ifdef EMULATE_GETCWD
  240. char *
  241. DEFUN (UX_getcwd, (buffer, length),
  242.        char * buffer AND
  243.        size_t length)
  244. {
  245.   char internal_buffer [MAXPATHLEN + 2];
  246.   char * collection_buffer;
  247.   size_t collection_length;
  248.   if (length <= 0)
  249.     {
  250.       errno = EINVAL;
  251.       return (0);
  252.     }
  253.   /* Allocate the buffer if needed. */
  254.   if (buffer == 0)
  255.     {
  256.       buffer = (UX_malloc (length));
  257.       if (buffer == 0)
  258.     {
  259.       errno = ENOMEM;
  260.       return (0);
  261.     }
  262.     }
  263.   if (length >= (sizeof (internal_buffer)))
  264.     {
  265.       collection_buffer = buffer;
  266.       collection_length = length;
  267.     }
  268.   else
  269.     {
  270.       collection_buffer = internal_buffer;
  271.       collection_length = (sizeof (internal_buffer));
  272.     }
  273. #ifdef HAVE_GETWD
  274.   if ((getwd (collection_buffer)) == 0)
  275.     {
  276.       errno = EACCES;
  277.       return (0);
  278.     }
  279. #else /* not HAVE_GETWD */
  280.   {
  281.     /* Invoke `pwd' and fill the buffer with its output. */
  282.     FILE * stream = (popen ("pwd", "r"));
  283.     char * scan_buffer = collection_buffer;
  284.     if (stream == 0)
  285.       {
  286.     errno = EACCES;
  287.     return (0);
  288.       }
  289.     fgets (collection_buffer, collection_length, stream);
  290.     pclose (stream);
  291.     while (1)
  292.       {
  293.     int c = (*scan_buffer++);
  294.     if (c == '\0')
  295.       break;
  296.     else if (c == '\n')
  297.       {
  298.         (*--scan_buffer) = '\0'; /* remove extraneous newline */
  299.         break;
  300.       }
  301.       }
  302.   }
  303. #endif /* not HAVE_GETWD */
  304.   if (collection_buffer == internal_buffer)
  305.     {
  306.       if (length <= (strlen (internal_buffer)))
  307.     {
  308.       errno = ERANGE;
  309.       return (0);
  310.     }
  311.       strcpy (buffer, internal_buffer);
  312.     }
  313.   return (buffer);
  314. }
  315. #endif /* EMULATE_GETCWD */
  316.  
  317. #ifdef EMULATE_WAITPID
  318. int
  319. DEFUN (UX_waitpid, (pid, stat_loc, options),
  320.        pid_t pid AND
  321.        int * stat_loc AND
  322.        int options)
  323. {
  324.   if (pid == (-1))
  325.     return (wait3 (stat_loc, options, 0));
  326. #ifdef HAVE_WAIT4
  327.   else if (pid > 0)
  328.     return (wait4 (pid, stat_loc, options, 0));
  329. #endif
  330.   errno = EINVAL;
  331.   return (-1);
  332. }
  333. #endif
  334.  
  335. #ifdef EMULATE_DUP2
  336. int
  337. DEFUN (UX_dup2, (fd, fd2), int fd AND int fd2)
  338. {
  339.   if (fd != fd2)
  340.     UX_close (fd2);
  341.   {
  342.     int result = (UX_fcntl (fd, F_DUPFD, fd2));
  343.     if ((result < 0) && (errno == EINVAL))
  344.       errno = EBADF;
  345.     return (result);
  346.   }
  347. }
  348. #endif
  349.  
  350. #ifdef EMULATE_RENAME
  351. int
  352. DEFUN (UX_rename, (from_name, to_name),
  353.        CONST char * from_name AND
  354.        CONST char * to_name)
  355. {
  356.   int result;
  357.   if ((result = (UX_access (from_name, 0))) < 0)
  358.     return (result);
  359.   {
  360.     struct stat fs;
  361.     struct stat ts;
  362.     if (((UX_stat (from_name, (&fs))) == 0) &&
  363.     ((UX_lstat (to_name, (&ts))) == 0))
  364.       {
  365.     if (((fs . st_dev) == (ts . st_dev)) &&
  366.         ((fs . st_ino) == (ts . st_ino)))
  367.       return (0);
  368.     UX_unlink (to_name);
  369.       }
  370.   }
  371.   return
  372.     (((result = (UX_link (from_name, to_name))) < 0)
  373.      ? result
  374.      : (UX_unlink (from_name)));
  375. }
  376. #endif
  377.  
  378. #ifdef EMULATE_MKDIR
  379. int
  380. DEFUN (UX_mkdir, (name, mode),
  381.        CONST char * name AND
  382.        mode_t mode)
  383. {
  384.   return (UX_mknod (name, ((mode & MODE_DIR) | S_IFDIR), ((dev_t) 0)));
  385. }
  386. #endif
  387.  
  388. #ifdef _POSIX_VERSION
  389.  
  390. cc_t
  391. DEFUN (UX_PC_VDISABLE, (fildes), int fildes)
  392. {
  393. #ifdef _POSIX_VDISABLE
  394.   return ((cc_t) _POSIX_VDISABLE);
  395. #else
  396.   long result = (fpathconf (fildes, _PC_VDISABLE));
  397.   return ((cc_t) ((result < 0) ? '\377' : result));
  398. #endif
  399. }
  400.  
  401. static clock_t memoized_clk_tck = 0;
  402.  
  403. clock_t
  404. DEFUN_VOID (UX_SC_CLK_TCK)
  405. {
  406.   if (memoized_clk_tck == 0)
  407.     memoized_clk_tck = ((clock_t) (sysconf (_SC_CLK_TCK)));
  408.   return (memoized_clk_tck);
  409. }
  410.  
  411. #endif /* _POSIX_VERSION */
  412.  
  413. #ifndef HAVE_SIGACTION
  414.  
  415. int
  416. DEFUN (UX_sigemptyset, (set), sigset_t * set)
  417. {
  418.   (*set) = 0;
  419.   return (0);
  420. }
  421.  
  422. int
  423. DEFUN (UX_sigfillset, (set), sigset_t * set)
  424. {
  425.   (*set) = (-1);
  426.   return (0);
  427. }
  428.  
  429. int
  430. DEFUN (UX_sigaddset, (set, signo), sigset_t * set AND int signo)
  431. {
  432.   if (signo <= 0)
  433.     return (-1);
  434.   {
  435.     int mask = (1 << (signo - 1));
  436.     if (mask == 0)
  437.       return (-1);
  438.     (*set) |= mask;
  439.     return (0);
  440.   }
  441. }
  442.  
  443. int
  444. DEFUN (UX_sigdelset, (set, signo), sigset_t * set AND int signo)
  445. {
  446.   if (signo <= 0)
  447.     return (-1);
  448.   {
  449.     int mask = (1 << (signo - 1));
  450.     if (mask == 0)
  451.       return (-1);
  452.     (*set) &=~ mask;
  453.     return (0);
  454.   }
  455. }
  456.  
  457. int
  458. DEFUN (UX_sigismember, (set, signo), CONST sigset_t * set AND int signo)
  459. {
  460.   if (signo <= 0)
  461.     return (-1);
  462.   {
  463.     int mask = (1 << (signo - 1));
  464.     if (mask == 0)
  465.       return (-1);
  466.     return (((*set) & mask) != 0);
  467.   }
  468. }
  469.  
  470. #ifdef HAVE_SIGVEC
  471.  
  472. #ifndef SV_INTERRUPT
  473. #  define SV_INTERRUPT 0
  474. #endif
  475.  
  476. int
  477. DEFUN (UX_sigaction, (signo, act, oact),
  478.        int signo AND
  479.        CONST struct sigaction * act AND
  480.        struct sigaction * oact)
  481. {
  482.   struct sigvec svec;
  483.   struct sigvec sovec;
  484.   struct sigvec * vec = ((act != 0) ? (&svec) : 0);
  485.   struct sigvec * ovec = ((oact != 0) ? (&sovec) : 0);
  486.   if (act != 0)
  487.     {
  488.       (vec -> sv_handler) = (act -> sa_handler);
  489.       (vec -> sv_mask) = (act -> sa_mask);
  490.       (vec -> sv_flags) = SV_INTERRUPT;
  491.     }
  492.   if ((UX_sigvec (signo, vec, ovec)) < 0)
  493.     return (-1);
  494.   if (oact != 0)
  495.     {
  496.       (oact -> sa_handler) = (ovec -> sv_handler);
  497.       (oact -> sa_mask) = (ovec -> sv_mask);
  498.       (oact -> sa_flags) = 0;
  499.     }
  500.   return (0);
  501. }
  502.  
  503. int
  504. DEFUN (UX_sigprocmask, (how, set, oset),
  505.        int how AND
  506.        CONST sigset_t * set AND
  507.        sigset_t * oset)
  508. {
  509.   long omask;
  510.   if (set == 0)
  511.     omask = (sigblock (0));
  512.   else
  513.     switch (how)
  514.       {
  515.       case SIG_BLOCK:
  516.     omask = (sigblock (*set));
  517.     break;
  518.       case SIG_UNBLOCK:
  519.     omask = (sigblock (0));
  520.     if (omask < 0) return (-1);
  521.     omask = (sigsetmask (omask &~ (*set)));
  522.     break;
  523.       case SIG_SETMASK:
  524.     omask = (sigsetmask (*set));
  525.     break;
  526.       default:
  527.     errno = EINVAL;
  528.     return (-1);
  529.       }
  530.   if (omask < 0) return (-1);
  531.   if (oset != 0) (*oset) = omask;
  532.   return (0);
  533. }
  534.  
  535. int
  536. DEFUN (UX_sigsuspend, (set), CONST sigset_t * set)
  537. {
  538.   return (sigpause (*set));
  539. }
  540.  
  541. #endif /* HAVE_SIGVEC */
  542. #endif /* not _POSIX_VERSION */
  543.  
  544. #ifdef EMULATE_SYSCONF
  545. long
  546. DEFUN (sysconf, (parameter), int parameter)
  547. {
  548.   switch (parameter)
  549.   {
  550.     case _SC_CLK_TCK:
  551. #ifdef CLK_TCK
  552.       return ((long) (CLK_TCK));
  553. #else
  554. #ifdef HZ
  555.       return ((long) HZ);
  556. #else
  557.       return (60);
  558. #endif /* HZ */
  559. #endif /* CLK_TCK */
  560.  
  561.     case _SC_OPEN_MAX:
  562. #ifdef OPEN_MAX
  563.       return ((long) OPEN_MAX);
  564. #else
  565. #ifdef _NFILE
  566.       return ((long) _NFILE);
  567. #else
  568.       return ((long) 16);
  569. #endif /* _NFILE */
  570. #endif /* OPEN_MAX */
  571.  
  572.     case _SC_CHILD_MAX:
  573. #ifdef CHILD_MAX
  574.       return ((long) CHILD_MAX);
  575. #else
  576.       return ((long) 6);
  577. #endif /* CHILD_MAX */
  578.  
  579.     case _SC_JOB_CONTROL:
  580. #ifdef TIOCGPGRP
  581.       return ((long) 1);
  582. #else
  583.       return ((long) 0);
  584. #endif
  585.  
  586.     default:
  587.       errno = EINVAL;
  588.       return ((long) (-1));
  589.   }
  590. }
  591. #endif /* EMULATE_SYSCONF */
  592.  
  593. #ifdef EMULATE_FPATHCONF
  594. long
  595. DEFUN (fpathconf, (filedes, parameter), int filedes AND int parameter)
  596. {
  597.   switch (parameter)
  598.   {
  599.     case _PC_VDISABLE:
  600.       return ((long) '\377');
  601.  
  602.     default:
  603.       errno = EINVAL;
  604.       return ((long) (-1));
  605.   }
  606. }
  607. #endif /* EMULATE_FPATHCONF */
  608.  
  609. void *
  610. DEFUN (OS_malloc, (size), unsigned int size)
  611. {
  612.   void * result = (UX_malloc (size));
  613.   if (result == 0)
  614.     error_system_call (ENOMEM, syscall_malloc);
  615.   return (result);
  616. }
  617.  
  618. void *
  619. DEFUN (OS_realloc, (ptr, size), void * ptr AND unsigned int size)
  620. {
  621.   void * result = (UX_realloc (ptr, size));
  622.   if (result == 0)
  623.     error_system_call (ENOMEM, syscall_realloc);
  624.   return (result);
  625. }
  626.  
  627. void
  628. DEFUN (OS_free, (ptr), void * ptr)
  629. {
  630.   UX_free (ptr);
  631. }
  632.  
  633. #ifdef __linux__
  634.  
  635. #include <sys/mman.h>
  636.  
  637. void *
  638. linux_heap_malloc (unsigned long requested_length)
  639. {
  640.   unsigned long ps = (getpagesize ());
  641.   void * addr
  642.     = (mmap (((void *) ps),
  643.          (((requested_length + (ps - 1)) / ps) * ps),
  644.          (PROT_EXEC | PROT_READ | PROT_WRITE),
  645.          (MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED),
  646.          0, 0));
  647.   return ((addr == ((void *) (-1))) ? 0 : addr);
  648. }
  649.  
  650. #endif /* __linux__ */
  651.  
  652. #ifdef __FreeBSD__
  653.  
  654. #include <sys/mman.h>
  655.  
  656. void *
  657. freebsd_heap_malloc (unsigned long requested_length)
  658. {
  659.   unsigned long ps = (getpagesize ());
  660.   void * addr
  661.     = (mmap (((void *) ps),
  662.          (((requested_length + (ps - 1)) / ps) * ps),
  663.          (PROT_EXEC | PROT_READ | PROT_WRITE),
  664.          (MAP_PRIVATE | MAP_ANON | MAP_FIXED),
  665.          (-1), 0));
  666.   return ((addr == MAP_FAILED) ? 0 : addr);
  667. }
  668.  
  669. #endif /* __FreeBSD__ */
  670.