home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / pdksh-4.9-src.tgz / tar.out / contrib / pdksh / sh / io.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  4KB  |  247 lines

  1. /*
  2.  * shell buffered IO and formatted output
  3.  */
  4.  
  5. #ifndef lint
  6. static char *RCSid = "$Id: io.c,v 1.6 93/05/08 16:00:02 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 amigaos
  102.     if (fd <= 2)
  103. #if defined(__386BSD__) || defined(_BSDI)
  104.         /* Chris Torek's stdio replacement */
  105.         __sF[fd]._flags = 0;
  106. #else
  107. #ifdef _MINIX
  108.         /* ? */;
  109. #else
  110. #ifdef __STDC__
  111.         __iob[fd]._flag = 0; /* re-use stdin, stdout, stderr */
  112. #else
  113.         _iob[fd]._flag = 0; /* re-use stdin, stdout, stderr */
  114. #endif
  115. #endif
  116. #endif
  117. #else
  118.     if (fd <= 2)
  119.       shf[fd] = (fd == 0) ? __sF[0] : (fd == 1 ? __sF[1] : __sF[2]);
  120.     else
  121. #endif
  122.  
  123.     /* "r+" is too lazy.. modern stdio implementation don't allow you
  124.        to open a O_RDONLY file this way, nor a O_WRONLY one... */
  125. #ifdef amigaos
  126.     {
  127.       int mode = fcntl (fd, F_GETFL, 0);
  128.       
  129.       if (mode >= 0)
  130.         switch (mode & 3)
  131.           {
  132.           case 0:
  133.             shf[fd] = fdopen (fd, "r");
  134.             break;
  135.             
  136.           case 1:
  137.             shf[fd] = fdopen (fd, "w");
  138.             break;
  139.             
  140.           case 2:
  141.             shf[fd] = fdopen (fd, "r+");
  142.             break;
  143.           }
  144.       else
  145.         shf[fd] = 0;
  146.     }
  147. #else
  148.     shf[fd] = fdopen(fd, "r+");
  149. #endif
  150.     if (shf[fd] == NULL)
  151.         return;
  152.     setvbuf(shf[fd], (char*)NULL, _IOFBF, (size_t)BUFSIZ);
  153. }
  154.  
  155. /* flush stream assoc with fd */
  156. /* this must invalidate input and output buffers */
  157. void
  158. flushshf(fd)
  159.     int fd;
  160. {
  161.     if (shf[fd] != NULL) {
  162. #if !defined(__386BSD__) && !defined(_BSDI) && !defined(__amigaos__)
  163.         /* Chris Torek's stdio replacement */
  164.         fseek(shf[fd], 0L, 1); /* V7 derived */
  165. #endif
  166.         fflush(shf[fd]);    /* standard C */
  167.     }
  168. }
  169.  
  170. /*
  171.  * move fd from user space (0<=fd<10) to shell space (fd>=10)
  172.  */
  173. int
  174. savefd(fd)
  175.     int fd;
  176. {
  177.     int nfd;
  178.  
  179.     if (fd < FDBASE) {
  180.         flushshf(fd);
  181.         nfd = fcntl(fd, F_DUPFD, FDBASE);
  182.         if (nfd < 0)
  183.             if (errno == EBADF)
  184.                 return -1;
  185.             else
  186.                 errorf("too many files open in shell\n");
  187.         (void) fd_clexec(ttyfd);
  188.         close(fd);
  189.     } else
  190.         nfd = fd;
  191.     return nfd;
  192. }
  193.  
  194. void
  195. restfd(fd, ofd)
  196.     int fd, ofd;
  197. {
  198.     if (ofd == 0)        /* not saved (e.savefd) */
  199.         return;
  200.     flushshf(fd);
  201.     close(fd);
  202.     if (ofd < 0)        /* original fd closed */
  203.         return;
  204.     (void) fcntl(ofd, F_DUPFD, fd);
  205.     close(ofd);
  206. }
  207.  
  208. void
  209. openpipe(pv)
  210.     register int *pv;
  211. {
  212.     if (pipe(pv) < 0)
  213.         errorf("can't create pipe - try again\n");
  214.     pv[0] = savefd(pv[0]);
  215.     pv[1] = savefd(pv[1]);
  216. }
  217.  
  218. void
  219. closepipe(pv)
  220.     register int *pv;
  221. {
  222.     close(pv[0]);
  223.     close(pv[1]);
  224. }
  225.  
  226. /*
  227.  * temporary files
  228.  */
  229.  
  230. struct temp *
  231. maketemp(ap)
  232.     Area *ap;
  233. {
  234.     register struct temp *tp;
  235.     static unsigned int inc = 0;
  236.     char path [PATH];
  237.  
  238.     sprintf(path, "/tmp/sh%05u%02u", (unsigned)getpid(), inc++);
  239. #if defined(_SYSV) || defined(_BSD)
  240.     close(creat(path, 0600));    /* to get appropriate permissions */
  241. #endif
  242.     tp = (struct temp *) alloc(sizeof(struct temp), ap);
  243.     tp->next = NULL;
  244.     tp->name = strsave(path, ap);
  245.     return tp;
  246. }
  247.