home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume8 / jove / part03 / fp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-02-02  |  5.0 KB  |  267 lines

  1. /************************************************************************
  2.  * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
  3.  * provided to you without charge, and with no warranty.  You may give  *
  4.  * away copies of JOVE, including sources, provided that this notice is *
  5.  * included in all the files.                                           *
  6.  ************************************************************************/
  7.  
  8. #include "jove.h"
  9. #include "io.h"
  10. #include "termcap.h"
  11. #include <sys/stat.h>
  12. #include <sys/file.h>
  13. #include <errno.h>
  14.  
  15. #define MAXFILES    20    /* good enough for my purposes */
  16.  
  17. static File    _openfiles[MAXFILES] = {0};
  18.  
  19. static File *
  20. f_alloc(name, flags, fd, buffer, buf_size)
  21. char    *name,
  22.     *buffer;
  23. {
  24.     register File    *fp;
  25.     register int    i;
  26.  
  27.     for (fp = _openfiles, i = 0; i < MAXFILES; i++, fp++)
  28.         if (fp->f_flags == 0)
  29.             break;
  30.     if (i == MAXFILES)
  31.         complain("[Too many open files!]");
  32.     fp->f_bufsize = buf_size;
  33.     fp->f_cnt = 0;
  34.     fp->f_fd = fd;
  35.     fp->f_flags = flags;
  36.     if (buffer == 0) {
  37.         buffer = emalloc(buf_size);
  38.         fp->f_flags |= F_MYBUF;
  39.     }
  40.     fp->f_base = fp->f_ptr = buffer;
  41.     fp->f_name = copystr(name);
  42.  
  43.     return fp;
  44. }
  45.  
  46. gc_openfiles()
  47. {
  48.     register File    *fp;
  49.  
  50.     for (fp = _openfiles; fp < &_openfiles[MAXFILES]; fp++)
  51.         if (fp->f_flags != 0 && (fp->f_flags & F_LOCKED) == 0)
  52.             f_close(fp);
  53. }
  54.  
  55. File *
  56. fd_open(name, flags, fd, buffer, bsize)
  57. char    *name,
  58.     *buffer;
  59. {
  60.     return f_alloc(name, flags, fd, buffer, bsize);
  61. }
  62.  
  63. File *
  64. f_open(name, flags, buffer, buf_size)
  65. char    *name,
  66.     *buffer;
  67. {
  68.     register int    fd;
  69.     int    mode = F_MODE(flags);
  70.  
  71.     if (mode == F_READ)
  72.         fd = open(name, 0);
  73.     if (mode == F_APPEND) {
  74.         fd = open(name, 1);
  75.         if (fd == -1)
  76.             mode = F_WRITE;
  77.         else
  78.             (void) lseek(fd, 0L, 2);
  79.     }
  80.     if (mode == F_WRITE)
  81.         fd = creat(name, CreatMode);
  82.     if (fd == -1)
  83.         return NIL;
  84.     return f_alloc(name, flags, fd, buffer, buf_size);
  85. }
  86.  
  87. f_close(fp)
  88. File    *fp;
  89. {
  90.     flush(fp);
  91. #ifdef BSD4_2 
  92.     if (fp->f_flags & (F_WRITE|F_APPEND))
  93.         (void) fsync(fp->f_fd);
  94. #endif 
  95.     (void) close(fp->f_fd);
  96.     if (fp->f_flags & F_MYBUF)
  97.         free(fp->f_base);
  98.     free(fp->f_name);
  99.     fp->f_flags = 0;    /* indicates that we're available */
  100. }
  101.  
  102. filbuf(fp)
  103. File    *fp;
  104. {
  105.     if (fp->f_flags & (F_EOF|F_ERR))
  106.         return EOF;
  107.     fp->f_ptr = fp->f_base;
  108.     fp->f_cnt = read(fp->f_fd, fp->f_base, fp->f_bufsize);
  109.     if (fp->f_cnt == -1) {
  110.         printf("[Read error %d]", errno);
  111.         fp->f_flags |= F_ERR;
  112.     }
  113.     if (fp->f_cnt == 0) {
  114.         fp->f_flags |= F_EOF;
  115.         return EOF;
  116.     }
  117.     io_chars += fp->f_cnt;
  118.     return getc(fp);
  119. }
  120.  
  121. putstr(s)
  122. register char    *s;
  123. {
  124.     register int    c;
  125.  
  126.     while (c = *s++)
  127.         putchar(c);
  128. }
  129.  
  130. fputnchar(s, n, fp)
  131. register char    *s;
  132. register int    n;
  133. register File    *fp;
  134. {
  135.     while (--n >= 0)
  136.         putc(*s++, fp);
  137. }
  138.  
  139. flusho()
  140. {
  141.     _flush(EOF, stdout);
  142. }
  143.  
  144. flush(fp)
  145. File    *fp;
  146. {
  147.     _flush(EOF, fp);
  148. }
  149.  
  150. _flush(c, fp)
  151. register File    *fp;
  152. {
  153.     register int    n;
  154.  
  155.     if (fp->f_flags & (F_READ | F_STRING | F_ERR))
  156.         return;
  157.     if (((n = (fp->f_ptr - fp->f_base)) > 0) &&
  158.         (write(fp->f_fd, fp->f_base, n) != n) &&
  159.         (fp != stdout)) {
  160.             fp->f_flags |= F_ERR;
  161.         error("[I/O error(%d); file = %s, fd = %d]",
  162.             errno, fp->f_name, fp->f_fd);
  163.     }
  164.  
  165.     if (fp == stdout)
  166.         OkayAbort = YES;
  167.     fp->f_cnt = fp->f_bufsize;
  168.     fp->f_ptr = fp->f_base;
  169.     if (c != EOF)
  170.         putc(c, fp);
  171. }
  172.  
  173. f_gets(fp, buf, max)
  174. register File    *fp;
  175. char    *buf;
  176. {
  177.     register char    *cp = buf;
  178.     register int    c;
  179.     char    *endp = buf + max - 1;
  180.  
  181.     if (fp->f_flags & F_EOF)
  182.         return EOF;
  183.     while (((c = getc(fp)) != EOF) && (c != '\n')) {
  184.         if (c == NULL)
  185.             continue;    /* sorry we don't read nulls */
  186.         if (cp >= endp) {
  187.             add_mess(" [Line too long]");
  188.             rbell();
  189.             return EOF;
  190.         }
  191.         *cp++ = c;
  192.     }
  193.     *cp = '\0';
  194.     if (c == EOF) {
  195.         if (cp != buf)
  196.             add_mess(" [Incomplete last line]");
  197.         fp->f_flags |= F_EOF;
  198.         return EOF;
  199.     }
  200.     io_lines++;
  201.     return NIL;    /* this means okay */
  202. }
  203.  
  204. /* Deals with output to the terminal, setting up the amount of characters
  205.    to be buffered depending on the output baud rate.  Why it's in a 
  206.    separate file I don't know ... */
  207.  
  208. static char    one_buf;
  209.  
  210. int    BufSize = 1;
  211.  
  212. static File    _stdout = {1, 1, 1, F_WRITE, &one_buf, &one_buf};
  213. File    *stdout = &_stdout;
  214.  
  215. /* put a string with padding */
  216.  
  217. tputc(c)
  218. {
  219.     putchar(c);
  220. }
  221.  
  222. #undef putchar        /* for files which forget to include io.h,
  223.                here's a real putchar procedure. */
  224. putchar(c)
  225. {
  226.     putc(c, stdout);
  227. }
  228.  
  229. putpad(str, lines)
  230. char    *str;
  231. {
  232.     if (str)
  233.         tputs(str, lines, tputc);
  234. }
  235.  
  236. /* Determine the number of characters to buffer at each baud rate.  The
  237.    lower the number, the quicker the response when new input arrives.  Of
  238.    course the lower the number, the more prone the program is to stop in
  239.    output.  Decide what matters most to you. This sets BufSize to the right
  240.    number or chars, and initiaizes `stdout'.  */
  241.  
  242. settout(ttbuf)
  243. char    *ttbuf;
  244. {
  245.     static int speeds[] = {
  246.         1,    /* 0    */
  247.         1,    /* 50    */
  248.         1,    /* 75    */
  249.         1,    /* 110    */
  250.         1,    /* 134    */
  251.         1,    /* 150    */
  252.         1,    /* 200    */
  253.         2,    /* 300    */
  254.         4,    /* 600    */
  255.         8,    /* 1200 */
  256.         16,    /* 1800    */
  257.         32,    /* 2400    */
  258.         128,    /* 4800    */
  259.         256,    /* 9600    */
  260.         512,    /* EXTA    */
  261.         512    /* EXT    */
  262.     };
  263.     BufSize = min(512, (speeds[ospeed] * max(LI / 24, 1)));
  264.     stdout = fd_open("/dev/tty", F_WRITE|F_LOCKED, 1, ttbuf, BufSize);
  265. }
  266.  
  267.