home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / gnu / pdksh-src.lha / src / amiga / pdksh / sh / io.c < prev    next >
C/C++ Source or Header  |  1993-12-01  |  4KB  |  244 lines

  1. /*
  2.  * shell buffered IO and formatted output
  3.  */
  4.  
  5. #ifndef lint
  6. static char *RCSid = "$Id: io.c,v 1.2 1992/04/25 08:33:28 sjg Exp $";
  7. #endif
  8.  
  9. #include "stdh.h"
  10. #include <errno.h>
  11. #include <unistd.h>
  12. #include <fcntl.h>
  13. #include <signal.h>
  14. #include <setjmp.h>
  15. #ifdef __STDC__
  16. #include <stdarg.h>
  17. #else
  18. #include <varargs.h>
  19. #endif
  20. #include "sh.h"
  21.  
  22. #if 0
  23. /* fputc with ^ escaping */
  24. static void
  25. fzotc(c, f)
  26.     register int c;
  27.     register FILE *f;
  28. {
  29.     if ((c&0x60) == 0) {        /* C0|C1 */
  30.         putc((c&0x80) ? '$' : '^', f);
  31.         putc((c&0x7F|0x40), f);
  32.     } else if ((c&0x7F) == 0x7F) {    /* DEL */
  33.         putc((c&0x80) ? '$' : '^', f);
  34.         putc('?', f);
  35.     } else
  36.         putc(c, f);
  37. }
  38. #endif
  39.  
  40. /*
  41.  * formatted output functions
  42.  */
  43.  
  44. /* shellf(...); error() */
  45. int
  46. #ifdef __STDC__
  47. errorf(const char *fmt, ...) {
  48. #else
  49. errorf(va_alist) va_dcl
  50. {
  51.     char *fmt;
  52. #endif
  53.     va_list va;
  54.  
  55. #ifdef __STDC__
  56.     va_start(va, fmt);
  57. #else
  58.     va_start(va);
  59.     fmt = va_arg(va, char *);
  60. #endif
  61.     vfprintf(shlout, fmt, va);
  62.     va_end(va);
  63.     /*fflush(shlout);*/
  64.     error();
  65. }
  66.  
  67. /* printf to shlout (stderr) */
  68. int
  69. #ifdef __STDC__
  70. shellf(const char *fmt, ...) {
  71. #else
  72. shellf(va_alist) va_dcl
  73. {
  74.     char *fmt;
  75. #endif
  76.     va_list va;
  77.  
  78. #ifdef __STDC__
  79.     va_start(va, fmt);
  80. #else
  81.     va_start(va);
  82.     fmt = va_arg(va, char *);
  83. #endif
  84.     vfprintf(shlout, fmt, va);
  85.     va_end(va);
  86.     return 0;
  87. }
  88.  
  89. /*
  90.  * We have a stdio stream for any open shell file descriptors (0-9)
  91.  */
  92. FILE *    shf [NUFILE];        /* map shell fd to FILE * */
  93.  
  94. /* open stream for shell fd */
  95. void
  96. fopenshf(fd)
  97.     int fd;
  98. {
  99.     if (shf[fd] != NULL)
  100.         return;
  101. #ifndef amigados
  102.     if (fd <= 2)
  103. #ifdef _MINIX
  104.         /* ? */;
  105. #else
  106.         _iob[fd]._flag = 0; /* re-use stdin, stdout, stderr */
  107. #endif
  108. #else
  109.     if (fd <= 2)
  110.       shf[fd] = (fd == 0) ? __sF[0] : (fd == 1 ? __sF[1] : __sF[2]);
  111.     else
  112. #endif
  113.  
  114.     /* "r+" is too lazy.. modern stdio implementation don't allow you
  115.        to open a O_RDONLY file this way, nor a O_WRONLY one... */
  116. #ifdef amigados
  117.     {
  118.       int mode = fcntl (fd, F_GETFL, 0);
  119.       
  120.       if (mode >= 0)
  121.         switch (mode & 3)
  122.           {
  123.           case 0:
  124.             shf[fd] = fdopen (fd, "r");
  125.             break;
  126.             
  127.           case 1:
  128.             shf[fd] = fdopen (fd, "w");
  129.             break;
  130.             
  131.           case 2:
  132.             shf[fd] = fdopen (fd, "r+");
  133.             break;
  134.           }
  135.       else
  136.         shf[fd] = 0;
  137.     }
  138. #else
  139.     shf[fd] = fdopen(fd, "r+");
  140. #endif
  141.     if (shf[fd] == NULL)
  142.         return;
  143.     setvbuf(shf[fd], (char*)NULL, _IOFBF, (size_t)BUFSIZ);
  144. }
  145.  
  146. /* flush stream assoc with fd */
  147. /* this must invalidate input and output buffers */
  148. void
  149. flushshf(fd)
  150.     int fd;
  151. {
  152.     if (shf[fd] != NULL) {
  153. #ifndef amigados
  154.         /* if you do this with BSD4.4 stdio, weird things start
  155.            to happen to your output.. don't know why, that's just
  156.            the way it is ;-(( */
  157.         fseek(shf[fd], 0L, 1); /* V7 derived */
  158. #endif
  159.         fflush(shf[fd]);    /* standard C */
  160.     }
  161. }
  162.  
  163. /*
  164.  * move fd from user space (0<=fd<10) to shell space (fd>=10)
  165.  */
  166. int
  167. savefd(fd)
  168.     int fd;
  169. {
  170.     int nfd;
  171.  
  172.     if (fd < FDBASE) {
  173.         flushshf(fd);
  174.         nfd = fcntl(fd, F_DUPFD, FDBASE);
  175.         if (nfd < 0)
  176.             if (errno == EBADF)
  177.                 return -1;
  178.             else
  179.                 errorf("too many files open in shell\n");
  180. #ifdef F_SETFD
  181.         (void) fcntl(nfd, F_SETFD, 1);
  182. #else
  183.         (void) fd_clexec(ttyfd);
  184. #endif
  185.         close(fd);
  186.     } else
  187.         nfd = fd;
  188.     return nfd;
  189. }
  190.  
  191. void
  192. restfd(fd, ofd)
  193.     int fd, ofd;
  194. {
  195.     if (ofd == 0)        /* not saved (e.savefd) */
  196.         return;
  197.     flushshf(fd);
  198.     close(fd);
  199.     if (ofd < 0)        /* original fd closed */
  200.         return;
  201.     (void) fcntl(ofd, F_DUPFD, fd);
  202.     close(ofd);
  203. }
  204.  
  205. void
  206. openpipe(pv)
  207.     register int *pv;
  208. {
  209.     if (pipe(pv) < 0)
  210.         errorf("can't create pipe - try again\n");
  211.     pv[0] = savefd(pv[0]);
  212.     pv[1] = savefd(pv[1]);
  213. }
  214.  
  215. void
  216. closepipe(pv)
  217.     register int *pv;
  218. {
  219.     close(pv[0]);
  220.     close(pv[1]);
  221. }
  222.  
  223. /*
  224.  * temporary files
  225.  */
  226.  
  227. struct temp *
  228. maketemp(ap)
  229.     Area *ap;
  230. {
  231.     register struct temp *tp;
  232.     static unsigned int inc = 0;
  233.     char path [PATH];
  234.  
  235.     sprintf(path, "/tmp/sh%05u%02u", (unsigned)getpid(), inc++);
  236. #if defined(_SYSV) || defined(_BSD)
  237.     close(creat(path, 0600));    /* to get appropriate permissions */
  238. #endif
  239.     tp = (struct temp *) alloc(sizeof(struct temp), ap);
  240.     tp->next = NULL;
  241.     tp->name = strsave(path, ap);
  242.     return tp;
  243. }
  244.