[project @ 1998-11-26 09:17:22 by sof]
[ghc-hetmet.git] / ghc / lib / std / cbits / fileObject.lc
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1998
3 %
4 \subsection[fileObject.lc]{Managing file objects}
5
6 \begin{code}
7
8 #include "rtsdefs.h"
9 #include "stgio.h"
10 #include "fileObject.h"
11
12 void
13 setBufFlags(fo, flg)
14 StgForeignObj fo;
15 StgInt flg;
16 {
17   ((IOFileObject*)fo)->flags = flg;
18   return;
19 }
20
21 void
22 setBufWPtr(fo, len)
23 StgForeignObj fo;
24 StgInt len;
25 {
26   ((IOFileObject*)fo)->bufWPtr = len;
27   return;
28 }
29
30 StgInt
31 getBufWPtr(fo)
32 StgForeignObj fo;
33 {
34   return (((IOFileObject*)fo)->bufWPtr);
35 }
36
37 StgInt
38 getBufSize(fo)
39 StgForeignObj fo;
40 {
41   return (((IOFileObject*)fo)->bufSize);
42 }
43
44 void
45 setBuf(fo, buf,sz)
46 StgForeignObj fo;
47 StgAddr buf;
48 StgInt sz;
49 {
50   ((IOFileObject*)fo)->buf     = buf;
51   ((IOFileObject*)fo)->bufSize = sz;
52   return;
53 }
54
55 StgAddr
56 getBuf(fo)
57 StgForeignObj fo;
58 { return (((IOFileObject*)fo)->buf); }
59
60 StgAddr
61 getWriteableBuf(ptr)
62 StgForeignObj ptr;
63
64    /* getWriteableBuf() is called prior to starting to pack
65       a Haskell string into the IOFileObject buffer. It takes
66       care of flushing the (input) buffer in the case we're
67       dealing with a RW handle.
68    */
69    IOFileObject* fo = (IOFileObject*)ptr;
70
71    if ( FILEOBJ_READABLE(fo) && FILEOBJ_JUST_READ(fo) ) {
72       flushReadBuffer(ptr);  /* ignoring return code */
73       /* Ahead of time really, but indicate that we're (just about to) write */
74    }
75    fo->flags = (fo->flags & ~FILEOBJ_RW_READ) | FILEOBJ_RW_WRITE;
76    return (fo->buf);
77 }
78
79 StgAddr
80 getBufStart(fo,count)
81 StgForeignObj fo;
82 StgInt count;
83 { return ((char*)((IOFileObject*)fo)->buf + (((IOFileObject*)fo)->bufRPtr) - count); }
84
85 StgInt
86 getFileFd(fo)
87 StgForeignObj fo;
88 { return (((IOFileObject*)fo)->fd); }
89
90 StgInt
91 getConnFileFd(fo)
92 StgForeignObj fo;
93 { return (((IOFileObject*)fo)->connectedTo->fd); }
94
95
96 void
97 setFd(fo,fp)
98 StgForeignObj fo;
99 StgInt fp;
100 { ((IOFileObject*)fo)->fd = fp;
101   return;
102 }
103
104 void
105 setConnectedTo(fo, fw, flg)
106 StgForeignObj fo;
107 StgForeignObj fw;
108 StgInt flg;
109 {
110   if( flg && (! isatty(((IOFileObject*)fo)->fd) || !isatty(((IOFileObject*)fw)->fd)) ) {
111       return;
112   }
113  ((IOFileObject*)fo)->connectedTo = (IOFileObject*)fw;
114   return;
115 }
116
117 static int __pushback_buf_size__ = 2;
118
119 void
120 setPushbackBufSize(i)
121 StgInt i;
122 { __pushback_buf_size__ = (i > 0 ? i : 0); }
123
124 StgInt
125 getPushbackBufSize()
126 { return (__pushback_buf_size__); }
127
128 void
129 clearNonBlockingIOFlag__ (ptr)
130 StgForeignObj ptr;
131 { ((IOFileObject*)ptr)->flags &= ~FILEOBJ_NONBLOCKING_IO; }
132
133 void
134 setNonBlockingIOFlag__ (ptr)
135 StgForeignObj ptr;
136 { ((IOFileObject*)ptr)->flags |= FILEOBJ_NONBLOCKING_IO; }
137
138 void
139 clearConnNonBlockingIOFlag__ (ptr)
140 StgForeignObj ptr;
141 { ((IOFileObject*)ptr)->connectedTo->flags &= ~FILEOBJ_NONBLOCKING_IO; }
142
143 void
144 setConnNonBlockingIOFlag__ (ptr)
145 StgForeignObj ptr;
146
147   if ( ((IOFileObject*)ptr)->connectedTo != NULL )  {
148     ((IOFileObject*)ptr)->connectedTo->flags |= FILEOBJ_NONBLOCKING_IO;
149   }
150   return;
151 }
152
153
154 /* Only ever called on line-buffered file objects */
155 StgInt
156 fill_up_line_buffer(fo)
157 IOFileObject* fo;
158 {
159   int count,len, ipos;
160   unsigned char* p;
161
162   /* ToDo: deal with buffer overflow (i.e., realloc buffer if this happens) */
163  
164   if ( fo->bufRPtr == fo->bufWPtr ) { /* There's nothing in the buffer, reset */
165       fo->bufRPtr=0;
166       fo->bufWPtr=0;
167   }
168   ipos = fo->bufWPtr;
169   len = fo->bufSize - fo->bufWPtr + 1;
170   p   = (unsigned char*)fo->buf + fo->bufWPtr;
171
172   if ( fo->flags & FILEOBJ_NONBLOCKING_IO && inputReady ((StgForeignObj)fo,0) != 1 )
173      return FILEOBJ_BLOCKED_READ;
174
175   if ((count = read(fo->fd, p, len)) <= 0) {
176       if (count == 0) {
177          ghc_errtype = ERR_EOF;
178          ghc_errstr = "";
179          FILEOBJ_SET_EOF(fo);
180          return -1;
181       } else if ( count == -1 && errno == EAGAIN) {
182          errno = 0;
183          return FILEOBJ_BLOCKED_READ;
184       } else if ( count == -1 && errno != EINTR ) {
185          cvtErrno();
186          stdErrno();
187          return -1;
188       }
189   }
190   fo->bufWPtr += count;
191   return (fo->bufWPtr - ipos);
192 }
193
194
195
196 \end{code}