Mercurial > hg > xemacs-beta
comparison src/lstream.c @ 771:943eaba38521
[xemacs-hg @ 2002-03-13 08:51:24 by ben]
The big ben-mule-21-5 check-in!
Various files were added and deleted. See CHANGES-ben-mule.
There are still some test suite failures. No crashes, though.
Many of the failures have to do with problems in the test suite itself
rather than in the actual code. I'll be addressing these in the next
day or so -- none of the test suite failures are at all critical.
Meanwhile I'll be trying to address the biggest issues -- i.e. build
or run failures, which will almost certainly happen on various platforms.
All comments should be sent to ben@xemacs.org -- use a Cc: if necessary
when sending to mailing lists. There will be pre- and post- tags,
something like
pre-ben-mule-21-5-merge-in, and
post-ben-mule-21-5-merge-in.
author | ben |
---|---|
date | Wed, 13 Mar 2002 08:54:06 +0000 |
parents | fdefd0186b75 |
children | 026c5bf9c134 |
comparison
equal
deleted
inserted
replaced
770:336a418893b5 | 771:943eaba38521 |
---|---|
1 /* Generic stream implementation. | 1 /* Generic stream implementation. |
2 Copyright (C) 1995 Free Software Foundation, Inc. | 2 Copyright (C) 1995 Free Software Foundation, Inc. |
3 Copyright (C) 1995 Sun Microsystems, Inc. | 3 Copyright (C) 1995 Sun Microsystems, Inc. |
4 Copyright (C) 1996 Ben Wing. | 4 Copyright (C) 1996, 2001 Ben Wing. |
5 | 5 |
6 This file is part of XEmacs. | 6 This file is part of XEmacs. |
7 | 7 |
8 XEmacs is free software; you can redistribute it and/or modify it | 8 XEmacs is free software; you can redistribute it and/or modify it |
9 under the terms of the GNU General Public License as published by the | 9 under the terms of the GNU General Public License as published by the |
30 #include "buffer.h" | 30 #include "buffer.h" |
31 #include "insdel.h" | 31 #include "insdel.h" |
32 #include "lstream.h" | 32 #include "lstream.h" |
33 | 33 |
34 #include "sysfile.h" | 34 #include "sysfile.h" |
35 #include <errno.h> | 35 |
36 | 36 /* This module provides a generic buffering stream implementation. |
37 /* This function provides a generic buffering stream implementation. | |
38 Conceptually, you send data to the stream or read data from the | 37 Conceptually, you send data to the stream or read data from the |
39 stream, not caring what's on the other end of the stream. The | 38 stream, not caring what's on the other end of the stream. The |
40 other end could be another stream, a file descriptor, a stdio | 39 other end could be another stream, a file descriptor, a stdio |
41 stream, a fixed block of memory, a reallocating block of memory, | 40 stream, a fixed block of memory, a reallocating block of memory, |
42 etc. The main purpose of the stream is to provide a standard | 41 etc. The main purpose of the stream is to provide a standard |
43 interface and to do buffering. Macros are defined to read | 42 interface and to do buffering. Macros are defined to read |
44 or write characters, so the calling functions do not have to | 43 or write characters, so the calling functions do not have to |
45 worry about blocking data together in order to achieve efficiency. | 44 worry about blocking data together in order to achieve efficiency. |
46 */ | 45 |
47 | 46 Note that this object is called "stream" in Lisp but "lstream" |
48 /* Note that this object is called "stream" in Lisp but "lstream" | |
49 in C. The reason for this is that "stream" is too generic a name | 47 in C. The reason for this is that "stream" is too generic a name |
50 for C; too much likelihood of conflict/confusion with C++, etc. */ | 48 for C; too much likelihood of conflict/confusion with C++, etc. */ |
51 | |
52 /* Functions are as follows: | |
53 | |
54 Lstream *Lstream_new (Lstream_implementation *imp, const char *mode) | |
55 Allocate and return a new Lstream. This function is not | |
56 really meant to be called directly; rather, each stream type | |
57 should provide its own stream creation function, which | |
58 creates the stream and does any other necessary creation | |
59 stuff (e.g. opening a file). | |
60 | |
61 void Lstream_set_buffering (Lstream *lstr, Lstream_buffering buffering, | |
62 int buffering_size) | |
63 Change the buffering of a stream. See lstream.h. By default | |
64 the buffering is STREAM_BLOCK_BUFFERED. | |
65 | |
66 int Lstream_flush (Lstream *lstr) | |
67 Flush out any pending unwritten data in the stream. Clear | |
68 any buffered input data. Returns 0 on success, -1 on error. | |
69 | |
70 int Lstream_putc (Lstream *stream, int c) | |
71 Write out one byte to the stream. This is a macro and so | |
72 it is very efficient. The C argument is only evaluated once | |
73 but the STREAM argument is evaluated more than once. Returns | |
74 0 on success, -1 on error. | |
75 | |
76 int Lstream_getc (Lstream *stream) | |
77 Read one byte from the stream and returns it as an unsigned | |
78 char cast to an int, or EOF on end of file or error. | |
79 This is a macro and so it is very efficient. The STREAM | |
80 argument is evaluated more than once. | |
81 | |
82 void Lstream_ungetc (Lstream *stream, int c) | |
83 Push one byte back onto the input queue, cast to unsigned char. | |
84 This will be the next byte read from the stream. Any number | |
85 of bytes can be pushed back and will be read in the reverse | |
86 order they were pushed back -- most recent first. (This is | |
87 necessary for consistency -- if there are a number of bytes | |
88 that have been unread and I read and unread a byte, it needs | |
89 to be the first to be read again.) This is a macro and so it | |
90 is very efficient. The C argument is only evaluated once but | |
91 the STREAM argument is evaluated more than once. | |
92 | |
93 int Lstream_fputc (Lstream *stream, int c) | |
94 int Lstream_fgetc (Lstream *stream) | |
95 void Lstream_fungetc (Lstream *stream, int c) | |
96 Function equivalents of the above macros. | |
97 | |
98 Bytecount Lstream_read (Lstream *stream, void *data, | |
99 Bytecount size) | |
100 Read SIZE bytes of DATA from the stream. Return the number of | |
101 bytes read. 0 means EOF. -1 means an error occurred and no | |
102 bytes were read. | |
103 | |
104 Bytecount Lstream_write (Lstream *stream, void *data, | |
105 Bytecount size) | |
106 Write SIZE bytes of DATA to the stream. Return the number of | |
107 bytes written. -1 means an error occurred and no bytes were | |
108 written. | |
109 | |
110 void Lstream_unread (Lstream *stream, void *data, Bytecount size) | |
111 Push back SIZE bytes of DATA onto the input queue. The | |
112 next call to Lstream_read() with the same size will read the | |
113 same bytes back. Note that this will be the case even if | |
114 there is other pending unread data. | |
115 | |
116 int Lstream_delete (Lstream *stream) | |
117 Frees all memory associated with the stream is freed. Calling | |
118 this is not strictly necessary, but it is much more efficient | |
119 than having the Lstream be garbage-collected. | |
120 | |
121 int Lstream_close (Lstream *stream) | |
122 Close the stream. All data will be flushed out. | |
123 | |
124 void Lstream_reopen (Lstream *stream) | |
125 Reopen a closed stream. This enables I/O on it again. | |
126 This is not meant to be called except from a wrapper routine | |
127 that reinitializes variables and such -- the close routine | |
128 may well have freed some necessary storage structures, for | |
129 example. | |
130 | |
131 void Lstream_rewind (Lstream *stream) | |
132 Rewind the stream to the beginning. | |
133 */ | |
134 | 49 |
135 #define DEFAULT_BLOCK_BUFFERING_SIZE 512 | 50 #define DEFAULT_BLOCK_BUFFERING_SIZE 512 |
136 #define MAX_READ_SIZE 512 | 51 #define MAX_READ_SIZE 512 |
137 | 52 |
138 static Lisp_Object | 53 static Lisp_Object |
177 } | 92 } |
178 else | 93 else |
179 /* Just close. */ | 94 /* Just close. */ |
180 Lstream_close (lstr); | 95 Lstream_close (lstr); |
181 } | 96 } |
97 | |
98 if (!for_disksave) | |
99 { | |
100 if (lstr->imp->finalizer) | |
101 (lstr->imp->finalizer) (lstr); | |
102 } | |
182 } | 103 } |
183 | 104 |
184 inline static Bytecount | 105 inline static Bytecount |
185 aligned_sizeof_lstream (Bytecount lstream_type_specific_size) | 106 aligned_sizeof_lstream (Bytecount lstream_type_specific_size) |
186 { | 107 { |
197 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("stream", lstream, | 118 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("stream", lstream, |
198 mark_lstream, print_lstream, | 119 mark_lstream, print_lstream, |
199 finalize_lstream, 0, 0, 0, | 120 finalize_lstream, 0, 0, 0, |
200 sizeof_lstream, Lstream); | 121 sizeof_lstream, Lstream); |
201 | 122 |
123 | |
124 /* Change the buffering of a stream. See lstream.h. By default the | |
125 buffering is STREAM_BLOCK_BUFFERED. */ | |
126 | |
202 void | 127 void |
203 Lstream_set_buffering (Lstream *lstr, Lstream_buffering buffering, | 128 Lstream_set_buffering (Lstream *lstr, Lstream_buffering buffering, |
204 int buffering_size) | 129 int buffering_size) |
205 { | 130 { |
206 lstr->buffering = buffering; | 131 lstr->buffering = buffering; |
220 | 145 |
221 static const Lstream_implementation *lstream_types[32]; | 146 static const Lstream_implementation *lstream_types[32]; |
222 static Lisp_Object Vlstream_free_list[32]; | 147 static Lisp_Object Vlstream_free_list[32]; |
223 static int lstream_type_count; | 148 static int lstream_type_count; |
224 | 149 |
150 /* Allocate and return a new Lstream. This function is not really | |
151 meant to be called directly; rather, each stream type should | |
152 provide its own stream creation function, which creates the stream | |
153 and does any other necessary creation stuff (e.g. opening a | |
154 file). */ | |
155 | |
225 Lstream * | 156 Lstream * |
226 Lstream_new (const Lstream_implementation *imp, const char *mode) | 157 Lstream_new (const Lstream_implementation *imp, const char *mode) |
227 { | 158 { |
228 Lstream *p; | 159 Lstream *p; |
229 int i; | 160 int i; |
260 p->flags |= LSTREAM_FL_NO_PARTIAL_CHARS; | 191 p->flags |= LSTREAM_FL_NO_PARTIAL_CHARS; |
261 | 192 |
262 return p; | 193 return p; |
263 } | 194 } |
264 | 195 |
196 /* Set or unset "character mode" on the stream. The basic idea is that, | |
197 assuming valid internal-format data is passing through the stream and | |
198 we're processing the data character by character, we don't want partial | |
199 characters at the end of the data. (No partial characters at the | |
200 beginning happens naturally if we eliminate partial characters at the | |
201 end and the stream is implemented correctly.) | |
202 | |
203 Character mode actually has two somewhat different meanings, depending | |
204 on whether this is a read stream or write stream. If a read stream, | |
205 character mode means that data returned from calling Lstream_read() on | |
206 the stream will contain only full characters. If a write stream, | |
207 character mode means that data passed to the write method in the stream | |
208 implementation will contain only full characters. It's important to | |
209 note the non-parallelism in who should set this mode on the stream: The | |
210 *CALLER* sets character mode on read streams it creates; the *STREAM | |
211 ITSELF* sets character mode on write streams, typically at creation | |
212 time. */ | |
213 | |
265 void | 214 void |
266 Lstream_set_character_mode (Lstream *lstr) | 215 Lstream_set_character_mode (Lstream *lstr) |
267 { | 216 { |
268 lstr->flags |= LSTREAM_FL_NO_PARTIAL_CHARS; | 217 lstr->flags |= LSTREAM_FL_NO_PARTIAL_CHARS; |
269 } | 218 } |
219 | |
220 /* Unset character mode. See Lstream_set_character_mode(). */ | |
221 | |
222 void | |
223 Lstream_unset_character_mode (Lstream *lstr) | |
224 { | |
225 lstr->flags &= ~LSTREAM_FL_NO_PARTIAL_CHARS; | |
226 } | |
227 | |
228 /* Close the stream (if it's open), and free all memory associated with the | |
229 stream. Put the stream on a free list; later calls to create a new | |
230 stream of this type may reuse this stream. Calling this is not strictly | |
231 necessary, but it is much more efficient than having the Lstream be | |
232 garbage-collected. Be VERY VERY SURE there are no pointers to this | |
233 object hanging around anywhere where they might be used! When streams | |
234 are chained together, be VERY CAREFUL of the order in which you delete | |
235 them! (e.g. if the streams are in a singly-linked list, delete the head | |
236 first; this will close, and may send data down to the rest. Then | |
237 proceed to the rest, one by one. If the chains are in a doubly-linked | |
238 list, close all the streams first (again, from the head to the tail), | |
239 disconnect the back links, then delete starting from the head. In | |
240 general, it's a good idea to close everything before deleting | |
241 anything. | |
242 | |
243 NOTE: DO NOT CALL DURING GARBAGE COLLECTION (e.g. in a finalizer). You | |
244 will be aborted. See free_managed_lcrecord(). */ | |
270 | 245 |
271 void | 246 void |
272 Lstream_delete (Lstream *lstr) | 247 Lstream_delete (Lstream *lstr) |
273 { | 248 { |
274 int i; | 249 int i; |
288 } | 263 } |
289 | 264 |
290 #define Lstream_internal_error(reason, lstr) \ | 265 #define Lstream_internal_error(reason, lstr) \ |
291 signal_error (Qinternal_error, reason, wrap_lstream (lstr)) | 266 signal_error (Qinternal_error, reason, wrap_lstream (lstr)) |
292 | 267 |
268 /* Reopen a closed stream. This enables I/O on it again. This is not | |
269 meant to be called except from a wrapper routine that reinitializes | |
270 variables and such -- the close routine may well have freed some | |
271 necessary storage structures, for example. */ | |
272 | |
293 void | 273 void |
294 Lstream_reopen (Lstream *lstr) | 274 Lstream_reopen (Lstream *lstr) |
295 { | 275 { |
296 if (lstr->flags & LSTREAM_FL_IS_OPEN) | 276 if (lstr->flags & LSTREAM_FL_IS_OPEN) |
297 Lstream_internal_error ("lstream already open", lstr); | 277 Lstream_internal_error ("lstream already open", lstr); |
298 lstr->flags |= LSTREAM_FL_IS_OPEN; | 278 lstr->flags |= LSTREAM_FL_IS_OPEN; |
299 } | 279 } |
300 | 280 |
301 /* Attempt to flush out all of the buffered data for writing. */ | 281 /* Try to write as much of DATA as possible to the stream. Return the |
302 | 282 number of bytes written. */ |
303 int | 283 |
304 Lstream_flush_out (Lstream *lstr) | 284 static int |
285 Lstream_really_write (Lstream *lstr, const unsigned char *data, int size) | |
305 { | 286 { |
306 Bytecount num_written; | 287 Bytecount num_written; |
307 | 288 const unsigned char *orig_data = data; |
308 while (lstr->out_buffer_ind > 0) | 289 int error_occurred = 0; |
309 { | 290 |
310 Bytecount size = lstr->out_buffer_ind; | 291 while (size > 0) |
292 { | |
311 if (! (lstr->flags & LSTREAM_FL_IS_OPEN)) | 293 if (! (lstr->flags & LSTREAM_FL_IS_OPEN)) |
312 Lstream_internal_error ("lstream not open", lstr); | 294 Lstream_internal_error ("lstream not open", lstr); |
313 if (! (lstr->flags & LSTREAM_FL_WRITE)) | 295 if (! (lstr->flags & LSTREAM_FL_WRITE)) |
314 Lstream_internal_error ("lstream not open for writing", lstr); | 296 Lstream_internal_error ("lstream not open for writing", lstr); |
315 if (!lstr->imp->writer) | 297 if (!lstr->imp->writer) |
318 if (lstr->flags & LSTREAM_FL_NO_PARTIAL_CHARS) | 300 if (lstr->flags & LSTREAM_FL_NO_PARTIAL_CHARS) |
319 /* It's quite possible for us to get passed an incomplete | 301 /* It's quite possible for us to get passed an incomplete |
320 character at the end. We need to spit back that | 302 character at the end. We need to spit back that |
321 incomplete character. */ | 303 incomplete character. */ |
322 { | 304 { |
323 const unsigned char *data = lstr->out_buffer; | |
324 const unsigned char *dataend = data + size - 1; | 305 const unsigned char *dataend = data + size - 1; |
325 assert (size > 0); /* safety check ... */ | 306 assert (size > 0); /* safety check ... */ |
326 /* Optimize the most common case. */ | 307 /* Optimize the most common case. */ |
327 if (!BYTE_ASCII_P (*dataend)) | 308 if (!BYTE_ASCII_P (*dataend)) |
328 { | 309 { |
339 if (size == 0) | 320 if (size == 0) |
340 break; | 321 break; |
341 } | 322 } |
342 } | 323 } |
343 | 324 |
344 num_written = (lstr->imp->writer) (lstr, lstr->out_buffer, size); | 325 num_written = (lstr->imp->writer) (lstr, data, size); |
345 if (num_written == 0) | 326 if (num_written == 0) |
346 /* If nothing got written, then just hold the data. This may | 327 /* If nothing got written, then just hold the data. This may |
347 occur, for example, if this stream does non-blocking I/O; | 328 occur, for example, if this stream does non-blocking I/O; |
348 the attempt to write the data might have resulted in an | 329 the attempt to write the data might have resulted in an |
349 EWOULDBLOCK error. */ | 330 EWOULDBLOCK error. */ |
350 return 0; | 331 break; |
351 else if (num_written >= lstr->out_buffer_ind) | 332 else if (num_written > size) |
352 lstr->out_buffer_ind = 0; | 333 abort (); |
353 else if (num_written > 0) | 334 else if (num_written > 0) |
354 { | 335 { |
355 memmove (lstr->out_buffer, lstr->out_buffer + num_written, | 336 data += num_written; |
356 lstr->out_buffer_ind - num_written); | 337 size -= num_written; |
357 lstr->out_buffer_ind -= num_written; | |
358 } | 338 } |
359 else | 339 else |
360 /* If error, just hold the data, for similar reasons as above. */ | 340 { |
361 return -1; | 341 /* If error, just hold the data, for similar reasons as above. */ |
342 error_occurred = 1; | |
343 break; | |
344 } | |
362 } | 345 } |
363 | 346 |
364 if (lstr->imp->flusher) | 347 if (lstr->imp->flusher) |
365 return (lstr->imp->flusher) (lstr); | 348 error_occurred = (lstr->imp->flusher) (lstr) < 0; |
366 | 349 |
367 return 0; | 350 if (data == orig_data && error_occurred) |
368 } | 351 return -1; |
352 | |
353 return data - orig_data; | |
354 } | |
355 | |
356 /* Attempt to flush out all of the buffered data for writing. Leaves | |
357 whatever wasn't flushed sitting in the stream's buffers. Return -1 if | |
358 nothing written and error occurred, 0 otherwise. */ | |
359 | |
360 int | |
361 Lstream_flush_out (Lstream *lstr) | |
362 { | |
363 Bytecount num_written = | |
364 Lstream_really_write (lstr, lstr->out_buffer, lstr->out_buffer_ind); | |
365 if (num_written == lstr->out_buffer_ind) | |
366 { | |
367 lstr->out_buffer_ind = 0; | |
368 return 0; | |
369 } | |
370 else if (num_written > 0) | |
371 { | |
372 memmove (lstr->out_buffer, lstr->out_buffer + num_written, | |
373 lstr->out_buffer_ind - num_written); | |
374 lstr->out_buffer_ind -= num_written; | |
375 return 0; | |
376 } | |
377 else return num_written; | |
378 } | |
379 | |
380 /* Flush out any pending unwritten data in the stream. Clear any buffered | |
381 input data. This differs from Lstream_flush_out() in that it also | |
382 clears any unflushable buffered data. Returns 0 on success, -1 on | |
383 error. */ | |
369 | 384 |
370 int | 385 int |
371 Lstream_flush (Lstream *lstr) | 386 Lstream_flush (Lstream *lstr) |
372 { | 387 { |
373 if (Lstream_flush_out (lstr) < 0) | 388 if (Lstream_flush_out (lstr) < 0) |
386 actually write. If FORCE is set, ignore the buffering size | 401 actually write. If FORCE is set, ignore the buffering size |
387 and go ahead and make space for all the chars even if it exceeds | 402 and go ahead and make space for all the chars even if it exceeds |
388 the buffering size. (This is used to deal with the possibility | 403 the buffering size. (This is used to deal with the possibility |
389 that the stream writer might refuse to write any bytes now, e.g. | 404 that the stream writer might refuse to write any bytes now, e.g. |
390 if it's getting EWOULDBLOCK errors. We have to keep stocking them | 405 if it's getting EWOULDBLOCK errors. We have to keep stocking them |
391 up until they can be written, so as to avoid losing data. */ | 406 up until they can be written, so as to avoid losing data.) */ |
392 | 407 |
393 static Bytecount | 408 static Bytecount |
394 Lstream_adding (Lstream *lstr, Bytecount num, int force) | 409 Lstream_adding (Lstream *lstr, Bytecount num, int force) |
395 { | 410 { |
396 Bytecount size = num + lstr->out_buffer_ind; | 411 Bytecount size = num + lstr->out_buffer_ind; |
413 return size - lstr->out_buffer_ind; | 428 return size - lstr->out_buffer_ind; |
414 } | 429 } |
415 | 430 |
416 /* Like Lstream_write(), but does not handle line-buffering correctly. */ | 431 /* Like Lstream_write(), but does not handle line-buffering correctly. */ |
417 | 432 |
418 static Bytecount | 433 static int |
419 Lstream_write_1 (Lstream *lstr, const void *data, Bytecount size) | 434 Lstream_write_1 (Lstream *lstr, const void *data, Bytecount size) |
420 { | 435 { |
421 const unsigned char *p = (const unsigned char *) data; | 436 const unsigned char *p = (const unsigned char *) data; |
422 Bytecount off = 0; | 437 Bytecount off = 0; |
423 if (! (lstr->flags & LSTREAM_FL_IS_OPEN)) | 438 if (! (lstr->flags & LSTREAM_FL_IS_OPEN)) |
424 Lstream_internal_error ("lstream not open", lstr); | 439 Lstream_internal_error ("lstream not open", lstr); |
425 if (! (lstr->flags & LSTREAM_FL_WRITE)) | 440 if (! (lstr->flags & LSTREAM_FL_WRITE)) |
426 Lstream_internal_error ("lstream not open for writing", lstr); | 441 Lstream_internal_error ("lstream not open for writing", lstr); |
427 { | 442 |
428 int couldnt_write_last_time = 0; | 443 if (lstr->buffering == LSTREAM_UNBUFFERED) |
429 | 444 { |
430 while (1) | 445 /* If there is buffered data, it means we ran into blocking |
431 { | 446 errors the previous time and had to buffer our remaining |
432 /* Figure out how much we can add to the buffer */ | 447 data. Try to write it now. */ |
433 Bytecount chunk = Lstream_adding (lstr, size, 0); | 448 if (lstr->out_buffer_ind > 0) |
434 if (chunk == 0) | 449 { |
435 { | 450 if (Lstream_flush_out (lstr) < 0) |
436 if (couldnt_write_last_time) | 451 return -1; |
437 /* Ung, we ran out of space and tried to flush | 452 } |
438 the buffer, but it didn't work because the stream | 453 |
439 writer is refusing to accept any data. So we | 454 /* If not still blocked, try to write the new data */ |
440 just have to squirrel away all the rest of the | 455 if (lstr->out_buffer_ind == 0) |
441 stuff. */ | 456 { |
442 chunk = Lstream_adding (lstr, size, 1); | 457 /* we don't need to loop because Lstream_really_write does that |
443 else | 458 for us. */ |
444 couldnt_write_last_time = 1; | 459 Bytecount num_written = Lstream_really_write (lstr, p, size); |
445 } | 460 if (num_written < 0) |
446 /* Do it. */ | 461 return -1; |
447 if (chunk > 0) | 462 off += num_written; |
448 { | 463 } |
449 memcpy (lstr->out_buffer + lstr->out_buffer_ind, p + off, chunk); | 464 |
450 lstr->out_buffer_ind += chunk; | 465 /* squirrel away the rest of the data */ |
451 lstr->byte_count += chunk; | 466 if (off < size) |
452 size -= chunk; | 467 { |
453 off += chunk; | 468 Lstream_adding (lstr, size - off, 1); |
454 } | 469 memcpy (lstr->out_buffer + lstr->out_buffer_ind, p + off, |
455 /* If the buffer is full and we have more to add, flush it out. */ | 470 size - off); |
456 if (size > 0) | 471 lstr->out_buffer_ind += size - off; |
457 { | 472 } |
458 if (Lstream_flush_out (lstr) < 0) | 473 |
459 { | 474 lstr->byte_count += size; |
460 if (off == 0) | 475 return 0; |
461 return -1; | 476 } |
462 else | 477 else |
463 return off; | 478 { |
464 } | 479 int couldnt_write_last_time = 0; |
465 } | 480 |
466 else | 481 while (1) |
467 break; | 482 { |
468 } | 483 /* Figure out how much we can add to the buffer */ |
469 } | 484 Bytecount chunk = Lstream_adding (lstr, size, 0); |
470 return off; | 485 if (chunk == 0) |
471 } | 486 { |
472 | 487 if (couldnt_write_last_time) |
473 /* If the stream is not line-buffered, then we can just call | 488 /* Ung, we ran out of space and tried to flush |
474 Lstream_write_1(), which writes in chunks. Otherwise, we | 489 the buffer, but it didn't work because the stream |
475 repeatedly call Lstream_putc(), which knows how to handle | 490 writer is refusing to accept any data. So we |
476 line buffering. Returns number of bytes written. */ | 491 just have to squirrel away all the rest of the |
477 | 492 stuff. */ |
478 Bytecount | 493 chunk = Lstream_adding (lstr, size, 1); |
494 else | |
495 couldnt_write_last_time = 1; | |
496 } | |
497 /* Do it. */ | |
498 if (chunk > 0) | |
499 { | |
500 memcpy (lstr->out_buffer + lstr->out_buffer_ind, p + off, chunk); | |
501 lstr->out_buffer_ind += chunk; | |
502 lstr->byte_count += chunk; | |
503 size -= chunk; | |
504 off += chunk; | |
505 } | |
506 /* If the buffer is full and we have more to add, flush it out. */ | |
507 if (size > 0) | |
508 { | |
509 if (Lstream_flush_out (lstr) < 0) | |
510 { | |
511 if (off == 0) | |
512 return -1; | |
513 else | |
514 return 0; | |
515 } | |
516 } | |
517 else | |
518 break; | |
519 } | |
520 } | |
521 return 0; | |
522 } | |
523 | |
524 /* Write SIZE bytes of DATA to the stream. Return value is 0 on success, | |
525 -1 on error. -1 is only returned when no bytes could be written; if any | |
526 bytes could be written, then 0 is returned and any unwritten bytes are | |
527 buffered and the next call to Lstream_write() will try to write them | |
528 again. (This buffering happens even when the stream's buffering type is | |
529 LSTREAM_UNBUFFERED, and regardless of how much data is passed in or what | |
530 the stream's buffering size was set to. #### There should perhaps be a | |
531 way to control whether this happens.) */ | |
532 | |
533 int | |
479 Lstream_write (Lstream *lstr, const void *data, Bytecount size) | 534 Lstream_write (Lstream *lstr, const void *data, Bytecount size) |
480 { | 535 { |
481 Bytecount i; | 536 Bytecount i; |
482 const unsigned char *p = (const unsigned char *) data; | 537 const unsigned char *p = (const unsigned char *) data; |
483 | 538 |
539 /* If the stream is not line-buffered, then we can just call | |
540 Lstream_write_1(), which writes in chunks. Otherwise, we repeatedly | |
541 call Lstream_putc(), which knows how to handle line buffering. | |
542 Returns 0 on success, -1 on failure. */ | |
543 | |
484 if (size == 0) | 544 if (size == 0) |
485 return size; | 545 return 0; |
486 if (lstr->buffering != LSTREAM_LINE_BUFFERED) | 546 if (lstr->buffering != LSTREAM_LINE_BUFFERED) |
487 return Lstream_write_1 (lstr, data, size); | 547 return Lstream_write_1 (lstr, data, size); |
488 for (i = 0; i < size; i++) | 548 for (i = 0; i < size; i++) |
489 { | 549 { |
490 if (Lstream_putc (lstr, p[i]) < 0) | 550 if (Lstream_putc (lstr, p[i]) < 0) |
491 break; | 551 break; |
492 } | 552 } |
493 return i == 0 ? -1 : i; | 553 return i == 0 ? -1 : 0; |
494 } | 554 } |
495 | 555 |
496 int | 556 int |
497 Lstream_was_blocked_p (Lstream *lstr) | 557 Lstream_was_blocked_p (Lstream *lstr) |
498 { | 558 { |
534 lstr->in_buffer_current = max (0, size_gotten); | 594 lstr->in_buffer_current = max (0, size_gotten); |
535 lstr->in_buffer_ind = 0; | 595 lstr->in_buffer_ind = 0; |
536 return size_gotten < 0 ? -1 : size_gotten; | 596 return size_gotten < 0 ? -1 : size_gotten; |
537 } | 597 } |
538 | 598 |
599 /* Read SIZE bytes of DATA from the stream. Return the number of bytes | |
600 read. 0 means EOF (#### sometimes; it may simply indicate we can't read | |
601 any data at other times, particularly if SIZE is too small. this needs | |
602 to be fixed!). -1 means an error occurred and no bytes were read. */ | |
603 | |
539 Bytecount | 604 Bytecount |
540 Lstream_read (Lstream *lstr, void *data, Bytecount size) | 605 Lstream_read (Lstream *lstr, void *data, Bytecount size) |
541 { | 606 { |
542 unsigned char *p = (unsigned char *) data; | 607 unsigned char *p = (unsigned char *) data; |
543 Bytecount off = 0; | 608 Bytecount off = 0; |
558 size -= chunk; | 623 size -= chunk; |
559 } | 624 } |
560 | 625 |
561 while (size > 0) | 626 while (size > 0) |
562 { | 627 { |
563 /* Take whatever we can from the in buffer */ | 628 /* If unbuffered, then simply read directly into output buffer. |
564 chunk = min (size, lstr->in_buffer_current - lstr->in_buffer_ind); | 629 No need to copy. */ |
565 if (chunk > 0) | 630 if (lstr->buffering == LSTREAM_UNBUFFERED) |
566 { | 631 { |
567 memcpy (p + off, lstr->in_buffer + lstr->in_buffer_ind, chunk); | 632 chunk = Lstream_raw_read (lstr, p + off, size); |
568 lstr->in_buffer_ind += chunk; | 633 if (chunk < 0) |
569 lstr->byte_count += chunk; | 634 error_occurred = 1; |
635 if (chunk <= 0) | |
636 break; | |
637 lstr->byte_count += chunk; | |
570 size -= chunk; | 638 size -= chunk; |
571 off += chunk; | 639 off += chunk; |
572 } | 640 } |
573 | 641 else |
574 /* If we need some more, try to get some more from the stream's end */ | |
575 if (size > 0) | |
576 { | 642 { |
577 Bytecount retval = Lstream_read_more (lstr); | 643 /* Take whatever we can from the in buffer */ |
578 if (retval < 0) | 644 chunk = min (size, lstr->in_buffer_current - lstr->in_buffer_ind); |
579 error_occurred = 1; | 645 if (chunk > 0) |
580 if (retval <= 0) | 646 { |
581 break; | 647 memcpy (p + off, lstr->in_buffer + lstr->in_buffer_ind, chunk); |
648 lstr->in_buffer_ind += chunk; | |
649 lstr->byte_count += chunk; | |
650 size -= chunk; | |
651 off += chunk; | |
652 } | |
653 | |
654 /* If we need some more, try to get some more from the | |
655 stream's end */ | |
656 if (size > 0) | |
657 { | |
658 Bytecount retval = Lstream_read_more (lstr); | |
659 if (retval < 0) | |
660 error_occurred = 1; | |
661 if (retval <= 0) | |
662 break; | |
663 } | |
582 } | 664 } |
583 } | 665 } |
584 | 666 |
585 /* #### Beware of OFF ending up 0. */ | 667 if (lstr->flags & LSTREAM_FL_NO_PARTIAL_CHARS) |
586 if ((lstr->flags & LSTREAM_FL_NO_PARTIAL_CHARS) && off > 0) | |
587 { | 668 { |
588 /* It's quite possible for us to get passed an incomplete | 669 /* It's quite possible for us to get passed an incomplete |
589 character at the end. We need to spit back that | 670 character at the end. We need to spit back that |
590 incomplete character. */ | 671 incomplete character. */ |
591 const unsigned char *dataend = p + off - 1; | 672 Bytecount newoff = validate_intbyte_string_backward (p, off); |
592 /* Optimize the most common case. */ | 673 if (newoff < off) |
593 if (!BYTE_ASCII_P (*dataend)) | |
594 { | 674 { |
595 /* Go back to the beginning of the last (and possibly partial) | 675 Lstream_unread (lstr, p + newoff, off - newoff); |
596 character, and bump forward to see if the character is | 676 off = newoff; |
597 complete. */ | |
598 VALIDATE_CHARPTR_BACKWARD (dataend); | |
599 if (dataend + REP_BYTES_BY_FIRST_BYTE (*dataend) != p + off) | |
600 { | |
601 Bytecount newoff = dataend - p; | |
602 /* If not, chop the size down to ignore the last char | |
603 and stash it away for next time. */ | |
604 Lstream_unread (lstr, dataend, off - newoff); | |
605 off = newoff; | |
606 } | |
607 } | 677 } |
608 } | 678 } |
609 | 679 |
610 return off == 0 && error_occurred ? -1 : off; | 680 return off == 0 && error_occurred ? -1 : off; |
611 } | 681 } |
682 | |
683 /* Push back SIZE bytes of DATA onto the input queue. The next call | |
684 to Lstream_read() with the same size will read the same bytes back. | |
685 Note that this will be the case even if there is other pending | |
686 unread data. */ | |
612 | 687 |
613 void | 688 void |
614 Lstream_unread (Lstream *lstr, const void *data, Bytecount size) | 689 Lstream_unread (Lstream *lstr, const void *data, Bytecount size) |
615 { | 690 { |
616 const unsigned char *p = (const unsigned char *) data; | 691 const unsigned char *p = (const unsigned char *) data; |
624 /* Bytes have to go on in reverse order -- they are reversed | 699 /* Bytes have to go on in reverse order -- they are reversed |
625 again when read back. */ | 700 again when read back. */ |
626 while (size--) | 701 while (size--) |
627 lstr->unget_buffer[lstr->unget_buffer_ind++] = p[size]; | 702 lstr->unget_buffer[lstr->unget_buffer_ind++] = p[size]; |
628 } | 703 } |
704 | |
705 /* Rewind the stream to the beginning. */ | |
629 | 706 |
630 int | 707 int |
631 Lstream_rewind (Lstream *lstr) | 708 Lstream_rewind (Lstream *lstr) |
632 { | 709 { |
633 if (!lstr->imp->rewinder) | 710 if (!lstr->imp->rewinder) |
655 Lstream_internal_error ("lstream is not open", lstr); | 732 Lstream_internal_error ("lstream is not open", lstr); |
656 | 733 |
657 /* don't check errors here -- best not to risk file descriptor loss */ | 734 /* don't check errors here -- best not to risk file descriptor loss */ |
658 return Lstream_flush (lstr); | 735 return Lstream_flush (lstr); |
659 } | 736 } |
737 | |
738 /* Close the stream. All data will be flushed out. If the stream is | |
739 already closed, nothing happens. Note that, even if all data has | |
740 already been flushed out, the act of closing a stream may generate more | |
741 data -- for example, if the stream implements some sort of conversion, | |
742 such as gzip, there may be special "end-data" that need to be written | |
743 out when the file is closed. */ | |
660 | 744 |
661 int | 745 int |
662 Lstream_close (Lstream *lstr) | 746 Lstream_close (Lstream *lstr) |
663 { | 747 { |
664 int rc = 0; | 748 int rc = 0; |
724 } | 808 } |
725 | 809 |
726 return rc; | 810 return rc; |
727 } | 811 } |
728 | 812 |
813 | |
814 /* Function equivalent of Lstream_putc(). */ | |
815 | |
729 int | 816 int |
730 Lstream_fputc (Lstream *lstr, int c) | 817 Lstream_fputc (Lstream *lstr, int c) |
731 { | 818 { |
732 unsigned char ch = (unsigned char) c; | 819 unsigned char ch = (unsigned char) c; |
733 Bytecount retval = Lstream_write_1 (lstr, &ch, 1); | 820 int retval = Lstream_write_1 (lstr, &ch, 1); |
734 if (retval >= 0 && lstr->buffering == LSTREAM_LINE_BUFFERED && ch == '\n') | 821 if (retval == 0 && lstr->buffering == LSTREAM_LINE_BUFFERED && ch == '\n') |
735 return Lstream_flush_out (lstr); | 822 return Lstream_flush_out (lstr); |
736 return retval < 0 ? -1 : 0; | 823 return retval; |
737 } | 824 } |
825 | |
826 /* Function equivalent of Lstream_getc(). */ | |
738 | 827 |
739 int | 828 int |
740 Lstream_fgetc (Lstream *lstr) | 829 Lstream_fgetc (Lstream *lstr) |
741 { | 830 { |
742 unsigned char ch; | 831 unsigned char ch; |
743 if (Lstream_read (lstr, &ch, 1) <= 0) | 832 if (Lstream_read (lstr, &ch, 1) <= 0) |
744 return -1; | 833 return -1; |
745 return ch; | 834 return ch; |
746 } | 835 } |
747 | 836 |
837 /* Function equivalent of Lstream_ungetc(). */ | |
838 | |
748 void | 839 void |
749 Lstream_fungetc (Lstream *lstr, int c) | 840 Lstream_fungetc (Lstream *lstr, int c) |
750 { | 841 { |
751 unsigned char ch = (unsigned char) c; | 842 unsigned char ch = (unsigned char) c; |
752 Lstream_unread (lstr, &ch, 1); | 843 Lstream_unread (lstr, &ch, 1); |
763 int closing; | 854 int closing; |
764 }; | 855 }; |
765 | 856 |
766 #define STDIO_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, stdio) | 857 #define STDIO_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, stdio) |
767 | 858 |
768 DEFINE_LSTREAM_IMPLEMENTATION ("stdio", lstream_stdio, | 859 DEFINE_LSTREAM_IMPLEMENTATION ("stdio", stdio); |
769 sizeof (struct stdio_stream)); | |
770 | 860 |
771 static Lisp_Object | 861 static Lisp_Object |
772 make_stdio_stream_1 (FILE *stream, int flags, const char *mode) | 862 make_stdio_stream_1 (FILE *stream, int flags, const char *mode) |
773 { | 863 { |
774 Lisp_Object obj; | 864 Lisp_Object obj; |
797 want stdio_reader() to be completely correct, we should check for | 887 want stdio_reader() to be completely correct, we should check for |
798 0 < val < size and if so, check to see if an error has occurred. | 888 0 < val < size and if so, check to see if an error has occurred. |
799 If an error has occurred, but val is non-zero, we should go ahead | 889 If an error has occurred, but val is non-zero, we should go ahead |
800 and act as if the read was successful, but remember in some fashion | 890 and act as if the read was successful, but remember in some fashion |
801 or other, that an error has occurred, and report that on the next | 891 or other, that an error has occurred, and report that on the next |
802 call to stdio_reader instead of calling fread() again. | 892 call to stdio_reader instead of calling retry_fread() again. |
803 | 893 |
804 Currently, in such a case, we end up calling fread() twice and we | 894 Currently, in such a case, we end up calling retry_fread() twice and we |
805 assume that | 895 assume that |
806 | 896 |
807 1) this is not harmful, and | 897 1) this is not harmful, and |
808 2) the error will still be reported on the second read. | 898 2) the error will still be reported on the second read. |
809 | 899 |
810 This is probably reasonable, so I don't think we should change this | 900 This is probably reasonable, so I don't think we should change this |
811 code (it could even be argued that the error might have fixed | 901 code (it could even be argued that the error might have fixed |
812 itself, so we should do the fread() again. */ | 902 itself, so we should do the retry_fread() again. */ |
813 | 903 |
814 static Bytecount | 904 static Bytecount |
815 stdio_reader (Lstream *stream, unsigned char *data, Bytecount size) | 905 stdio_reader (Lstream *stream, unsigned char *data, Bytecount size) |
816 { | 906 { |
817 struct stdio_stream *str = STDIO_STREAM_DATA (stream); | 907 struct stdio_stream *str = STDIO_STREAM_DATA (stream); |
818 Bytecount val = fread (data, 1, size, str->file); | 908 Bytecount val = retry_fread (data, 1, size, str->file); |
819 if (!val && ferror (str->file)) | 909 if (!val) |
820 return -1; | 910 { |
911 if (ferror (str->file)) | |
912 return LSTREAM_ERROR; | |
913 if (feof (str->file)) | |
914 return 0; /* LSTREAM_EOF; */ | |
915 } | |
821 return val; | 916 return val; |
822 } | 917 } |
823 | 918 |
824 static Bytecount | 919 static Bytecount |
825 stdio_writer (Lstream *stream, const unsigned char *data, | 920 stdio_writer (Lstream *stream, const unsigned char *data, |
826 Bytecount size) | 921 Bytecount size) |
827 { | 922 { |
828 struct stdio_stream *str = STDIO_STREAM_DATA (stream); | 923 struct stdio_stream *str = STDIO_STREAM_DATA (stream); |
829 Bytecount val = fwrite (data, 1, size, str->file); | 924 Bytecount val = retry_fwrite (data, 1, size, str->file); |
830 if (!val && ferror (str->file)) | 925 if (!val && ferror (str->file)) |
831 return -1; | 926 return LSTREAM_ERROR; |
832 return val; | 927 return val; |
833 } | 928 } |
834 | 929 |
835 static int | 930 static int |
836 stdio_rewinder (Lstream *stream) | 931 stdio_rewinder (Lstream *stream) |
843 stdio_seekable_p (Lstream *stream) | 938 stdio_seekable_p (Lstream *stream) |
844 { | 939 { |
845 struct stat lestat; | 940 struct stat lestat; |
846 struct stdio_stream *str = STDIO_STREAM_DATA (stream); | 941 struct stdio_stream *str = STDIO_STREAM_DATA (stream); |
847 | 942 |
848 if (fstat (fileno (str->file), &lestat) < 0) | 943 if (qxe_fstat (fileno (str->file), &lestat) < 0) |
849 return 0; | 944 return 0; |
850 return S_ISREG (lestat.st_mode); | 945 return S_ISREG (lestat.st_mode); |
851 } | 946 } |
852 | 947 |
853 static int | 948 static int |
863 static int | 958 static int |
864 stdio_closer (Lstream *stream) | 959 stdio_closer (Lstream *stream) |
865 { | 960 { |
866 struct stdio_stream *str = STDIO_STREAM_DATA (stream); | 961 struct stdio_stream *str = STDIO_STREAM_DATA (stream); |
867 if (str->closing) | 962 if (str->closing) |
868 return fclose (str->file); | 963 return retry_fclose (str->file); |
869 else | 964 else |
870 if (stream->flags & LSTREAM_FL_WRITE) | 965 if (stream->flags & LSTREAM_FL_WRITE) |
871 return fflush (str->file); | 966 return fflush (str->file); |
872 else | 967 else |
873 return 0; | 968 return 0; |
891 unsigned int blocking_error_p :1; | 986 unsigned int blocking_error_p :1; |
892 }; | 987 }; |
893 | 988 |
894 #define FILEDESC_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, filedesc) | 989 #define FILEDESC_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, filedesc) |
895 | 990 |
896 DEFINE_LSTREAM_IMPLEMENTATION ("filedesc", lstream_filedesc, | 991 DEFINE_LSTREAM_IMPLEMENTATION ("filedesc", filedesc); |
897 sizeof (struct filedesc_stream)); | |
898 | 992 |
899 /* Make a stream that reads from or writes to a file descriptor FILEDESC. | 993 /* Make a stream that reads from or writes to a file descriptor FILEDESC. |
900 OFFSET is the offset from the *current* file pointer that the reading | 994 OFFSET is the offset from the *current* file pointer that the reading |
901 should start at. COUNT is the number of bytes to be read (it is | 995 should start at. COUNT is the number of bytes to be read (it is |
902 ignored when writing); -1 for unlimited. */ | 996 ignored when writing); -1 for unlimited. */ |
944 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream); | 1038 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream); |
945 if (str->end_pos >= 0) | 1039 if (str->end_pos >= 0) |
946 size = min (size, (Bytecount) (str->end_pos - str->current_pos)); | 1040 size = min (size, (Bytecount) (str->end_pos - str->current_pos)); |
947 nread = str->allow_quit ? | 1041 nread = str->allow_quit ? |
948 read_allowing_quit (str->fd, data, size) : | 1042 read_allowing_quit (str->fd, data, size) : |
949 read (str->fd, data, size); | 1043 retry_read (str->fd, data, size); |
950 if (nread > 0) | 1044 if (nread > 0) |
951 str->current_pos += nread; | 1045 str->current_pos += nread; |
1046 if (nread == 0) | |
1047 return 0; /* LSTREAM_EOF; */ | |
1048 if (nread < 0) | |
1049 return LSTREAM_ERROR; | |
952 return nread; | 1050 return nread; |
953 } | 1051 } |
954 | 1052 |
955 static int | 1053 static int |
956 errno_would_block_p (int val) | 1054 errno_would_block_p (int val) |
1000 | 1098 |
1001 /**** start of non-PTY-crap ****/ | 1099 /**** start of non-PTY-crap ****/ |
1002 if (size > 0) | 1100 if (size > 0) |
1003 retval = str->allow_quit ? | 1101 retval = str->allow_quit ? |
1004 write_allowing_quit (str->fd, data, size) : | 1102 write_allowing_quit (str->fd, data, size) : |
1005 write (str->fd, data, size); | 1103 retry_write (str->fd, data, size); |
1006 else | 1104 else |
1007 retval = 0; | 1105 retval = 0; |
1008 if (retval < 0 && errno_would_block_p (errno) && str->blocked_ok) | 1106 if (retval < 0 && errno_would_block_p (errno) && str->blocked_ok) |
1009 { | 1107 { |
1010 str->blocking_error_p = 1; | 1108 str->blocking_error_p = 1; |
1011 return 0; | 1109 return 0; |
1012 } | 1110 } |
1013 str->blocking_error_p = 0; | 1111 str->blocking_error_p = 0; |
1014 if (retval < 0) | 1112 if (retval < 0) |
1015 return retval; | 1113 return LSTREAM_ERROR; |
1016 /**** end non-PTY-crap ****/ | 1114 /**** end non-PTY-crap ****/ |
1017 | 1115 |
1018 if (str->pty_flushing) | 1116 if (str->pty_flushing) |
1019 { | 1117 { |
1020 str->chars_sans_newline += retval; | 1118 str->chars_sans_newline += retval; |
1025 out for EWOULDBLOCK. */ | 1123 out for EWOULDBLOCK. */ |
1026 if (str->chars_sans_newline >= str->pty_max_bytes) | 1124 if (str->chars_sans_newline >= str->pty_max_bytes) |
1027 { | 1125 { |
1028 Bytecount retval2 = str->allow_quit ? | 1126 Bytecount retval2 = str->allow_quit ? |
1029 write_allowing_quit (str->fd, &str->eof_char, 1) : | 1127 write_allowing_quit (str->fd, &str->eof_char, 1) : |
1030 write (str->fd, &str->eof_char, 1); | 1128 retry_write (str->fd, &str->eof_char, 1); |
1031 | 1129 |
1032 if (retval2 > 0) | 1130 if (retval2 > 0) |
1033 str->chars_sans_newline = 0; | 1131 str->chars_sans_newline = 0; |
1034 else if (retval2 < 0) | 1132 else if (retval2 < 0) |
1035 { | 1133 { |
1042 { | 1140 { |
1043 str->blocking_error_p = 1; | 1141 str->blocking_error_p = 1; |
1044 return 0; | 1142 return 0; |
1045 } | 1143 } |
1046 else | 1144 else |
1047 return retval2; | 1145 return LSTREAM_ERROR; |
1048 } | 1146 } |
1049 else | 1147 else |
1050 return retval; | 1148 return retval; |
1051 } | 1149 } |
1052 } | 1150 } |
1058 if (need_newline) | 1156 if (need_newline) |
1059 { | 1157 { |
1060 Intbyte nl = '\n'; | 1158 Intbyte nl = '\n'; |
1061 Bytecount retval2 = str->allow_quit ? | 1159 Bytecount retval2 = str->allow_quit ? |
1062 write_allowing_quit (str->fd, &nl, 1) : | 1160 write_allowing_quit (str->fd, &nl, 1) : |
1063 write (str->fd, &nl, 1); | 1161 retry_write (str->fd, &nl, 1); |
1064 | 1162 |
1065 if (retval2 > 0) | 1163 if (retval2 > 0) |
1066 { | 1164 { |
1067 str->chars_sans_newline = 0; | 1165 str->chars_sans_newline = 0; |
1068 retval++; | 1166 retval++; |
1078 { | 1176 { |
1079 str->blocking_error_p = 1; | 1177 str->blocking_error_p = 1; |
1080 return 0; | 1178 return 0; |
1081 } | 1179 } |
1082 else | 1180 else |
1083 return retval2; | 1181 return LSTREAM_ERROR; |
1084 } | 1182 } |
1085 else | 1183 else |
1086 return retval; | 1184 return retval; |
1087 } | 1185 } |
1088 } | 1186 } |
1113 return 0; | 1211 return 0; |
1114 else | 1212 else |
1115 { | 1213 { |
1116 struct stat lestat; | 1214 struct stat lestat; |
1117 | 1215 |
1118 if (fstat (str->fd, &lestat) < 0) | 1216 if (qxe_fstat (str->fd, &lestat) < 0) |
1119 return 0; | 1217 return 0; |
1120 return S_ISREG (lestat.st_mode); | 1218 return S_ISREG (lestat.st_mode); |
1121 } | 1219 } |
1122 } | 1220 } |
1123 | 1221 |
1124 static int | 1222 static int |
1125 filedesc_closer (Lstream *stream) | 1223 filedesc_closer (Lstream *stream) |
1126 { | 1224 { |
1127 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream); | 1225 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream); |
1128 if (str->closing) | 1226 if (str->closing) |
1129 return close (str->fd); | 1227 return retry_close (str->fd); |
1130 else | 1228 else |
1131 return 0; | 1229 return 0; |
1132 } | 1230 } |
1133 | 1231 |
1134 static int | 1232 static int |
1164 Lisp_Object obj; | 1262 Lisp_Object obj; |
1165 Bytecount init_offset; | 1263 Bytecount init_offset; |
1166 Bytecount offset, end; | 1264 Bytecount offset, end; |
1167 }; | 1265 }; |
1168 | 1266 |
1169 DEFINE_LSTREAM_IMPLEMENTATION ("lisp-string", lstream_lisp_string, | 1267 DEFINE_LSTREAM_IMPLEMENTATION ("lisp-string", lisp_string); |
1170 sizeof (struct lisp_string_stream)); | |
1171 | 1268 |
1172 Lisp_Object | 1269 Lisp_Object |
1173 make_lisp_string_input_stream (Lisp_Object string, Bytecount offset, | 1270 make_lisp_string_input_stream (Lisp_Object string, Bytecount offset, |
1174 Bytecount len) | 1271 Bytecount len) |
1175 { | 1272 { |
1256 unsigned char *outbuf; | 1353 unsigned char *outbuf; |
1257 Bytecount size; | 1354 Bytecount size; |
1258 Bytecount offset; | 1355 Bytecount offset; |
1259 }; | 1356 }; |
1260 | 1357 |
1261 DEFINE_LSTREAM_IMPLEMENTATION ("fixed-buffer", lstream_fixed_buffer, | 1358 DEFINE_LSTREAM_IMPLEMENTATION ("fixed-buffer", fixed_buffer); |
1262 sizeof (struct fixed_buffer_stream)); | |
1263 | 1359 |
1264 Lisp_Object | 1360 Lisp_Object |
1265 make_fixed_buffer_input_stream (const void *buf, Bytecount size) | 1361 make_fixed_buffer_input_stream (const void *buf, Bytecount size) |
1266 { | 1362 { |
1267 Lisp_Object obj; | 1363 Lisp_Object obj; |
1346 Bytecount allocked; | 1442 Bytecount allocked; |
1347 int max_stored; | 1443 int max_stored; |
1348 int stored; | 1444 int stored; |
1349 }; | 1445 }; |
1350 | 1446 |
1351 DEFINE_LSTREAM_IMPLEMENTATION ("resizing-buffer", lstream_resizing_buffer, | 1447 DEFINE_LSTREAM_IMPLEMENTATION ("resizing-buffer", resizing_buffer); |
1352 sizeof (struct resizing_buffer_stream)); | |
1353 | 1448 |
1354 Lisp_Object | 1449 Lisp_Object |
1355 make_resizing_buffer_output_stream (void) | 1450 make_resizing_buffer_output_stream (void) |
1356 { | 1451 { |
1357 Lisp_Object obj; | 1452 Lisp_Object obj; |
1408 struct dynarr_stream | 1503 struct dynarr_stream |
1409 { | 1504 { |
1410 unsigned_char_dynarr *dyn; | 1505 unsigned_char_dynarr *dyn; |
1411 }; | 1506 }; |
1412 | 1507 |
1413 DEFINE_LSTREAM_IMPLEMENTATION ("dynarr", lstream_dynarr, | 1508 DEFINE_LSTREAM_IMPLEMENTATION ("dynarr", dynarr); |
1414 sizeof (struct dynarr_stream)); | |
1415 | 1509 |
1416 Lisp_Object | 1510 Lisp_Object |
1417 make_dynarr_output_stream (unsigned_char_dynarr *dyn) | 1511 make_dynarr_output_stream (unsigned_char_dynarr *dyn) |
1418 { | 1512 { |
1419 Lisp_Object obj; | 1513 Lisp_Object obj; |
1460 /* we use markers to properly deal with insertion/deletion */ | 1554 /* we use markers to properly deal with insertion/deletion */ |
1461 Lisp_Object start, end; | 1555 Lisp_Object start, end; |
1462 int flags; | 1556 int flags; |
1463 }; | 1557 }; |
1464 | 1558 |
1465 DEFINE_LSTREAM_IMPLEMENTATION ("lisp-buffer", lstream_lisp_buffer, | 1559 DEFINE_LSTREAM_IMPLEMENTATION ("lisp-buffer", lisp_buffer); |
1466 sizeof (struct lisp_buffer_stream)); | |
1467 | 1560 |
1468 static Lisp_Object | 1561 static Lisp_Object |
1469 make_lisp_buffer_stream_1 (struct buffer *buf, Charbpos start, Charbpos end, | 1562 make_lisp_buffer_stream_1 (struct buffer *buf, Charbpos start, Charbpos end, |
1470 int flags, const char *mode) | 1563 int flags, const char *mode) |
1471 { | 1564 { |