[project @ 1996-07-25 20:43:49 by partain]
[ghc-hetmet.git] / ghc / lib / cbits / setBuffering.lc
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1994
3 %
4 \subsection[setBuffering.lc]{hSetBuffering Runtime Support}
5
6 \begin{code}
7
8 #include "rtsdefs.h"
9 #include "stgio.h"
10
11 #ifdef HAVE_SYS_TYPES_H
12 #include <sys/types.h>
13 #endif
14
15 #ifdef HAVE_SYS_STAT_H
16 #include <sys/stat.h>
17 #endif
18
19 #ifdef HAVE_TERMIOS_H
20 #include <termios.h>
21 #endif
22
23 #ifdef HAVE_FCNTL_H
24 #include <fcntl.h>
25 #endif
26
27 #define SB_NB (0)
28 #define SB_LB (-1)
29 #define SB_BB (-2)
30
31 StgInt
32 setBuffering(fp, size)
33 StgAddr fp;
34 StgInt size;
35 {
36     int flags;
37     int input;
38     struct termios tio;
39
40     while ((flags = fcntl(fileno((FILE *) fp), F_GETFL)) < 0) {
41         if (errno != EINTR) {
42             cvtErrno();
43             stdErrno();
44             return -1;
45         }
46     }
47     flags &= O_ACCMODE;
48     input = flags == O_RDONLY || flags == O_RDWR;
49
50     switch (size) {
51     case SB_NB:
52         if (setvbuf((FILE *) fp, NULL, _IONBF, 0L) != 0) {
53             cvtErrno();
54             stdErrno();
55             return -1;
56         }
57         if (input && isatty(fileno((FILE *) fp))) {
58
59             /*
60              * Try to switch to CBREAK mode, or whatever they call it these days.
61              */
62
63             if (tcgetattr(fileno((FILE *) fp), &tio) < 0) {
64                 cvtErrno();
65                 stdErrno();
66                 return -1;
67             }
68             tio.c_lflag &= ~ICANON;
69             tio.c_cc[VMIN] = 1;
70             tio.c_cc[VTIME] = 0;
71             if (tcsetattr(fileno((FILE *) fp), TCSANOW, &tio) < 0) {
72                 cvtErrno();
73                 stdErrno();
74                 return -1;
75             }
76         }
77         return 0;
78         break;
79     case SB_LB:
80         if (setvbuf((FILE *) fp, NULL, _IOLBF, BUFSIZ) != 0) {
81             cvtErrno();
82             stdErrno();
83             return -1;
84         }
85         break;
86     case SB_BB:
87
88         /*
89          * We should actually peek at the buffer size in the stat struct, if there
90          * is one.  Something to occupy us later, when we're bored.
91          */
92         size = BUFSIZ;
93         /* fall through */
94     default:
95         if (setvbuf((FILE *) fp, NULL, _IOFBF, size) != 0) {
96             cvtErrno();
97             stdErrno();
98             return -1;
99         }
100         break;
101     }
102     if (input && isatty(fileno((FILE *) fp))) {
103
104         /*
105          * Try to switch back to cooked mode.
106          */
107
108         if (tcgetattr(fileno((FILE *) fp), &tio) < 0) {
109             cvtErrno();
110             stdErrno();
111             return -1;
112         }
113         tio.c_lflag |= ICANON;
114         if (tcsetattr(fileno((FILE *) fp), TCSANOW, &tio) < 0) {
115             cvtErrno();
116             stdErrno();
117             return -1;
118         }
119     }
120     return 0;
121 }
122
123 \end{code}