Merge branch 'merges'
[sxemacs] / src / lstream.c
1 /* Generic stream implementation.
2    Copyright (C) 1995 Free Software Foundation, Inc.
3    Copyright (C) 1995 Sun Microsystems, Inc.
4    Copyright (C) 1996 Ben Wing.
5
6 This file is part of SXEmacs
7
8 SXEmacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 SXEmacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program.  If not, see <http://www.gnu.org/licenses/>. */
20
21
22 /* Synched up with: Not in FSF. */
23
24 /* Written by Ben Wing. */
25
26 #include <config.h>
27 #include "lisp.h"
28
29 #include "buffer.h"
30 #include "ui/insdel.h"
31 #include "lstream.h"
32
33 #include "sysfile.h"
34 #include <errno.h>
35
36 /*! \page lstream Lstream
37  *
38  * <P>
39  * A lot to tell here ...
40  * </P>
41  */
42
43 /* This function provides a generic buffering stream implementation.
44    Conceptually, you send data to the stream or read data from the
45    stream, not caring what's on the other end of the stream.  The
46    other end could be another stream, a file descriptor, a stdio
47    stream, a fixed block of memory, a reallocating block of memory,
48    etc.  The main purpose of the stream is to provide a standard
49    interface and to do buffering.  Macros are defined to read
50    or write characters, so the calling functions do not have to
51    worry about blocking data together in order to achieve efficiency.
52    */
53
54 /* Note that this object is called "stream" in Lisp but "lstream"
55    in C.  The reason for this is that "stream" is too generic a name
56    for C; too much likelihood of conflict/confusion with C++, etc. */
57
58 /* Functions are as follows:
59
60 Lstream *Lstream_new (Lstream_implementation *imp, const char *mode)
61         Allocate and return a new Lstream.  This function is not
62         really meant to be called directly; rather, each stream type
63         should provide its own stream creation function, which
64         creates the stream and does any other necessary creation
65         stuff (e.g. opening a file).
66
67 void Lstream_set_buffering (Lstream *lstr, Lstream_buffering buffering,
68                             int buffering_size)
69         Change the buffering of a stream.  See lstream.h.  By default
70         the buffering is STREAM_BLOCK_BUFFERED.
71
72 int Lstream_flush (Lstream *lstr)
73         Flush out any pending unwritten data in the stream.  Clear
74         any buffered input data.  Returns 0 on success, -1 on error.
75
76 int Lstream_putc (Lstream *stream, int c)
77         Write out one byte to the stream.  This is a macro and so
78         it is very efficient.  The C argument is only evaluated once
79         but the STREAM argument is evaluated more than once.  Returns
80         0 on success, -1 on error.
81
82 int Lstream_getc (Lstream *stream)
83         Read one byte from the stream and returns it as an unsigned
84         char cast to an int, or EOF on end of file or error.
85         This is a macro and so it is very efficient.  The STREAM
86         argument is evaluated more than once.
87
88 void Lstream_ungetc (Lstream *stream, int c)
89         Push one byte back onto the input queue, cast to unsigned char.
90         This will be the next byte read from the stream.  Any number
91         of bytes can be pushed back and will be read in the reverse
92         order they were pushed back -- most recent first. (This is
93         necessary for consistency -- if there are a number of bytes
94         that have been unread and I read and unread a byte, it needs
95         to be the first to be read again.) This is a macro and so it
96         is very efficient.  The C argument is only evaluated once but
97         the STREAM argument is evaluated more than once.
98
99 int Lstream_fputc (Lstream *stream, int c)
100 int Lstream_fgetc (Lstream *stream)
101 void Lstream_fungetc (Lstream *stream, int c)
102         Function equivalents of the above macros.
103
104 Lstream_data_count Lstream_read (Lstream *stream, void *data,
105                                  Lstream_data_count size)
106         Read SIZE bytes of DATA from the stream.  Return the number of
107         bytes read.  0 means EOF. -1 means an error occurred and no
108         bytes were read.
109
110 Lstream_data_count Lstream_write (Lstream *stream, void *data,
111                                   Lstream_data_count size)
112         Write SIZE bytes of DATA to the stream.  Return the number of
113         bytes written.  -1 means an error occurred and no bytes were
114         written.
115
116 void Lstream_unread (Lstream *stream, void *data, Lstream_data_count size)
117         Push back SIZE bytes of DATA onto the input queue.  The
118         next call to Lstream_read() with the same size will read the
119         same bytes back.  Note that this will be the case even if
120         there is other pending unread data.
121
122 int Lstream_delete (Lstream *stream)
123         Frees all memory associated with the stream is freed.  Calling
124         this is not strictly necessary, but it is much more efficient
125         than having the Lstream be garbage-collected.
126
127 int Lstream_close (Lstream *stream)
128         Close the stream.  All data will be flushed out.
129
130 int Lstream_get_fd (Lstream *stream)
131         Return the underlying filedescriptor or -1.
132
133 void Lstream_reopen (Lstream *stream)
134         Reopen a closed stream.  This enables I/O on it again.
135         This is not meant to be called except from a wrapper routine
136         that reinitializes variables and such -- the close routine
137         may well have freed some necessary storage structures, for
138         example.
139
140 void Lstream_rewind (Lstream *stream)
141         Rewind the stream to the beginning.
142 */
143
144 #define DEFAULT_BLOCK_BUFFERING_SIZE 512
145 #define MAX_READ_SIZE 512
146
147 static Lisp_Object mark_lstream(Lisp_Object obj)
148 {
149         lstream_t lstr = XLSTREAM(obj);
150         return lstr->imp->marker ? (lstr->imp->marker) (obj) : Qnil;
151 }
152
153 static void
154 print_lstream(Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
155 {
156         lstream_t lstr = XLSTREAM(obj);
157         char buf[200];
158
159         sprintf(buf, "#<INTERNAL OBJECT (SXEmacs bug?) (%s lstream) 0x%lx>",
160                 lstr->imp->name, (long)lstr);
161         write_c_string(buf, printcharfun);
162 }
163
164 static void finalize_lstream(void *header, int for_disksave)
165 {
166         /* WARNING WARNING WARNING.  This function (and all finalize functions)
167            may get called more than once on the same object, and may get called
168            (at dump time) on objects that are not being released. */
169         lstream_t lstr = header;
170
171 #if 0                           /* this may cause weird Broken Pipes? */
172         if (for_disksave) {
173                 Lstream_pseudo_close(lstr);
174                 return;
175         }
176 #endif
177         if (lstr->flags & LSTREAM_FL_IS_OPEN) {
178                 if (for_disksave) {
179                         if (lstr->flags & LSTREAM_FL_CLOSE_AT_DISKSAVE)
180                                 Lstream_close(lstr);
181                 } else
182                         /* Just close. */
183                         Lstream_close(lstr);
184         }
185 }
186
187 static inline size_t
188 aligned_sizeof_lstream(size_t lstream_type_specific_size)
189 {
190         return ALIGN_SIZE(offsetof(struct lstream_s, data) +
191                           lstream_type_specific_size,
192                           ALIGNOF(max_align_t));
193 }
194
195 static inline size_t
196 sizeof_lstream(const void *header)
197 {
198         REGISTER size_t imp_size = ((const struct lstream_s*)header)->imp->size;
199         return aligned_sizeof_lstream(imp_size);
200 }
201
202 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION("stream", lstream,
203                                        mark_lstream, print_lstream,
204                                        finalize_lstream, 0, 0, 0,
205                                        sizeof_lstream, struct lstream_s);
206
207 /**
208  * Replaces DO_REALLOC from lisp.h. */
209 #define LSTR_ALLOC_TO   DO_REALLOC_ATOMIC
210
211 \f
212 void
213 Lstream_set_buffering(lstream_t lstr, Lstream_buffering buffering, int bsz)
214 {
215         lstr->buffering = buffering;
216         switch (buffering) {
217         case LSTREAM_UNBUFFERED:
218                 lstr->buffering_size = 0;
219                 break;
220         case LSTREAM_BLOCK_BUFFERED:
221                 lstr->buffering_size = DEFAULT_BLOCK_BUFFERING_SIZE;
222                 break;
223         case LSTREAM_BLOCKN_BUFFERED:
224                 lstr->buffering_size = bsz;
225                 break;
226         case LSTREAM_LINE_BUFFERED:
227         case LSTREAM_UNLIMITED:
228                 lstr->buffering_size = INT_MAX;
229                 break;
230         default:
231                 break;
232         }
233 }
234
235 #if !defined HAVE_BDWGC || !defined EF_USE_BDWGC
236 static const Lstream_implementation *lstream_types[32];
237 static Lisp_Object Vlstream_free_list[32];
238 static int lstream_type_count;
239 #endif  /* !BDWGC */
240
241 #if defined HAVE_BDWGC && defined EF_USE_BDWGC
242 static void
243 lstr_finaliser(void *obj, void *UNUSED(data))
244 {
245         finalize_lstream(obj, 0);
246         return;
247 }
248 #endif  /* BDWGC */
249
250 lstream_t
251 Lstream_new(const Lstream_implementation *imp, const char *mode)
252 {
253         lstream_t p;
254
255 #if defined HAVE_BDWGC && defined EF_USE_BDWGC
256         GC_finalization_proc *foo = NULL;
257         void **bar = NULL;
258
259         p = xmalloc(aligned_sizeof_lstream(imp->size));
260         set_lheader_implementation(&p->header.lheader, &lrecord_lstream);
261
262         GC_REGISTER_FINALIZER(p, lstr_finaliser, NULL, foo, bar);
263 #else  /* !BDWGC */
264         int i;
265         Lisp_Object tmp;
266
267         for (i = 0; i < lstream_type_count; i++) {
268                 if (lstream_types[i] == imp)
269                         break;
270         }
271
272         if (i == lstream_type_count) {
273                 assert(lstream_type_count < countof(lstream_types));
274                 lstream_types[lstream_type_count] = imp;
275                 Vlstream_free_list[lstream_type_count] =
276                         make_lcrecord_list(aligned_sizeof_lstream(imp->size),
277                                            &lrecord_lstream);
278                 lstream_type_count++;
279         }
280
281         tmp = allocate_managed_lcrecord(Vlstream_free_list[i]);
282         p = XLSTREAM(tmp);
283         /* Zero it out, except the header. */
284         memset((char *)p + sizeof(p->header), '\0',
285                aligned_sizeof_lstream(imp->size) - sizeof(p->header));
286 #endif  /* BDWCG */
287
288         p->imp = imp;
289         Lstream_set_buffering(p, LSTREAM_BLOCK_BUFFERED, 0);
290         p->flags = LSTREAM_FL_IS_OPEN;
291
292         /* convert mode (one of "r", "w", "rc", "wc") to p->flags */
293         assert(mode[0] == 'r' || mode[0] == 'w');
294         assert(mode[1] == 'c' || mode[1] == '\0');
295         p->flags |= (mode[0] == 'r' ? LSTREAM_FL_READ : LSTREAM_FL_WRITE);
296         if (mode[1] == 'c') {
297                 p->flags |= LSTREAM_FL_NO_PARTIAL_CHARS;
298         }
299         return p;
300 }
301
302 void
303 Lstream_set_character_mode(lstream_t lstr)
304 {
305         lstr->flags |= LSTREAM_FL_NO_PARTIAL_CHARS;
306 }
307
308 void
309 Lstream_delete(lstream_t lstr)
310 {
311 #if defined HAVE_BDWGC && defined EF_USE_BDWGC
312         xfree(lstr);
313         return;
314
315 #else  /* !BDWGC */
316         Lisp_Object val;
317
318         XSETLSTREAM(val, lstr);
319         for (int i = 0; i < lstream_type_count; i++) {
320                 if (lstream_types[i] == lstr->imp) {
321                         free_managed_lcrecord(Vlstream_free_list[i], val);
322                         return;
323                 }
324         }
325
326         abort();
327 #endif  /* BDWGC */
328 }
329
330 #define Lstream_internal_error(reason, lstr)                            \
331         Lstream_signal_simple_error(lstr, "Internal error: " reason)
332
333 static void
334 Lstream_signal_simple_error(lstream_t lstr, const char *reason)
335 {
336         Lisp_Object obj;
337         XSETLSTREAM(obj, lstr);
338         signal_simple_error(reason, obj);
339 }
340
341 void
342 Lstream_reopen(lstream_t lstr)
343 {
344         if (lstr->flags & LSTREAM_FL_IS_OPEN) {
345                 Lstream_internal_error("lstream already open", lstr);
346         }
347         lstr->flags |= LSTREAM_FL_IS_OPEN;
348 }
349
350 /* Attempt to flush out all of the buffered data for writing. */
351
352 int
353 Lstream_flush_out(lstream_t lstr)
354 {
355         Lstream_data_count num_written;
356
357         while (lstr->out_buffer_ind > 0) {
358                 Lstream_data_count size = lstr->out_buffer_ind;
359                 if (!(lstr->flags & LSTREAM_FL_IS_OPEN)) {
360                         Lstream_internal_error("lstream not open", lstr);
361                 }
362                 if (!(lstr->flags & LSTREAM_FL_WRITE)) {
363                         Lstream_internal_error("lstream not open for writing",
364                                                lstr);
365                 }
366                 if (!lstr->imp->writer) {
367                         Lstream_internal_error("lstream has no writer", lstr);
368                 }
369                 if (lstr->flags & LSTREAM_FL_NO_PARTIAL_CHARS)
370                         /* It's quite possible for us to get passed an
371                            incomplete character at the end.  We need to spit
372                            back that incomplete character. */
373                 {
374                         const unsigned char *data = lstr->out_buffer;
375                         const unsigned char *dataend = data + size - 1;
376                         assert(size > 0);       /* safety check ... */
377                         /* Optimize the most common case. */
378                         if (!BYTE_ASCII_P(*dataend)) {
379                                 /* Go back to the beginning of the last (and
380                                    possibly partial) character, and bump forward
381                                    to see if the character is complete. */
382                                 VALIDATE_CHARPTR_BACKWARD(dataend);
383                                 if (dataend +
384                                     REP_BYTES_BY_FIRST_BYTE(*dataend) !=
385                                     data + size) {
386                                         /* If not, chop the size down to ignore
387                                            the last char and stash it away for
388                                            next time. */
389                                         size = dataend - data;
390                                 }
391                                 /* If we don't even have one character to write,
392                                    then just skip out. */
393                                 if (size == 0) {
394                                         break;
395                                 }
396                         }
397                 }
398
399                 num_written = lstr->imp->writer(lstr, lstr->out_buffer, size);
400                 if (num_written == 0) {
401                         /* If nothing got written, then just hold the data.
402                            This may occur, for example, if this stream does
403                            non-blocking I/O; the attempt to write the data might
404                            have resulted in an EWOULDBLOCK error. */
405                         return 0;
406                 } else if (num_written >= lstr->out_buffer_ind) {
407                         lstr->out_buffer_ind = 0;
408                 } else if (num_written > 0) {
409                         memmove(lstr->out_buffer,
410                                 lstr->out_buffer + num_written,
411                                 lstr->out_buffer_ind - num_written);
412                         lstr->out_buffer_ind -= num_written;
413                 } else {
414                         /* If error, just hold the data, for similar reasons as
415                            above. */
416                         return -1;
417                 }
418         }
419
420         if (lstr->imp->flusher) {
421                 return (lstr->imp->flusher) (lstr);
422         }
423         return 0;
424 }
425
426 int
427 Lstream_flush(lstream_t lstr)
428 {
429         if (Lstream_flush_out(lstr) < 0) {
430                 return -1;
431         }
432         /* clear out buffered data */
433         lstr->in_buffer_current = lstr->in_buffer_ind = 0;
434         lstr->unget_buffer_ind = 0;
435
436         return 0;
437 }
438
439 /* We want to add NUM characters.  This function ensures that the
440    buffer is large enough for this (per the buffering size specified
441    in the stream) and returns the number of characters we can
442    actually write.  If FORCE is set, ignore the buffering size
443    and go ahead and make space for all the chars even if it exceeds
444    the buffering size. (This is used to deal with the possibility
445    that the stream writer might refuse to write any bytes now, e.g.
446    if it's getting EWOULDBLOCK errors.   We have to keep stocking them
447    up until they can be written, so as to avoid losing data. */
448
449 static Lstream_data_count
450 Lstream_adding(lstream_t lstr, Lstream_data_count num, int force)
451 {
452         Lstream_data_count size = num + lstr->out_buffer_ind;
453
454         if (size <= lstr->out_buffer_size) {
455                 return num;
456         }
457         /* Maybe chop it down so that we don't buffer more characters
458            than our advertised buffering size. */
459         if ((size > lstr->buffering_size) && !force) {
460                 size = lstr->buffering_size;
461                 /* There might be more data buffered than the buffering size. */
462                 if (size <= lstr->out_buffer_ind) {
463                         return 0;
464                 }
465         }
466
467         LSTR_ALLOC_TO(lstr->out_buffer,
468                       lstr->out_buffer_size, size, unsigned char);
469
470         return size - lstr->out_buffer_ind;
471 }
472
473 /* Like Lstream_write(), but does not handle line-buffering correctly. */
474
475 static Lstream_data_count
476 Lstream_write_1(lstream_t lstr, const void *data, Lstream_data_count size)
477 {
478         const unsigned char *p = data;
479         Lstream_data_count off = 0;
480         if (!(lstr->flags & LSTREAM_FL_IS_OPEN)) {
481                 Lstream_internal_error("lstream not open", lstr);
482         }
483         if (!(lstr->flags & LSTREAM_FL_WRITE)) {
484                 Lstream_internal_error("lstream not open for writing", lstr);
485         }
486         {
487                 bool couldnt_write_last_time = false;
488
489                 while (1) {
490                         /* Figure out how much we can add to the buffer */
491                         Lstream_data_count chunk =
492                                 Lstream_adding(lstr, size, 0);
493                         if (chunk == 0) {
494                                 if (couldnt_write_last_time) {
495                                         /* Ung, we ran out of space and tried to
496                                            flush the buffer, but it didn't work
497                                            because the stream writer is refusing
498                                            to accept any data.  So we just have
499                                            to squirrel away all the rest of the
500                                            stuff. */
501                                         chunk = Lstream_adding(lstr, size, 1);
502                                 } else {
503                                         couldnt_write_last_time = true;
504                                 }
505                         }
506                         /* Do it. */
507                         if (chunk > 0) {
508                                 memcpy(lstr->out_buffer + lstr->out_buffer_ind,
509                                        p + off, chunk);
510                                 lstr->out_buffer_ind += chunk;
511                                 lstr->byte_count += chunk;
512                                 size -= chunk;
513                                 off += chunk;
514                         }
515                         /* If the buffer is full and we have more to add, flush
516                            it out. */
517                         if (size > 0) {
518                                 if (Lstream_flush_out(lstr) < 0) {
519                                         if (off == 0) {
520                                                 return -1;
521                                         } else {
522                                                 return off;
523                                         }
524                                 }
525                         } else {
526                                 break;
527                         }
528                 }
529         }
530         return off;
531 }
532
533 /* If the stream is not line-buffered, then we can just call
534    Lstream_write_1(), which writes in chunks.  Otherwise, we
535    repeatedly call Lstream_putc(), which knows how to handle
536    line buffering.  Returns number of bytes written. */
537
538 Lstream_data_count
539 Lstream_write(lstream_t lstr, const void *data, Lstream_data_count size)
540 {
541         Lstream_data_count i;
542         const unsigned char *p = data;
543
544         if (size == 0) {
545                 return size;
546         }
547         if (lstr->buffering != LSTREAM_LINE_BUFFERED) {
548                 return Lstream_write_1(lstr, data, size);
549         }
550         for (i = 0; i < size; i++) {
551                 if (Lstream_putc(lstr, p[i]) < 0) {
552                         break;
553                 }
554         }
555         return i == 0 ? -1 : i;
556 }
557
558 int
559 Lstream_was_blocked_p(lstream_t lstr)
560 {
561         return lstr->imp->was_blocked_p ? lstr->imp->was_blocked_p(lstr) : 0;
562 }
563
564 static Lstream_data_count
565 Lstream_raw_read(lstream_t lstr, unsigned char *buffer, Lstream_data_count size)
566 {
567         if (!(lstr->flags & LSTREAM_FL_IS_OPEN)) {
568                 Lstream_internal_error("lstream not open", lstr);
569         }
570         if (!(lstr->flags & LSTREAM_FL_READ)) {
571                 Lstream_internal_error("lstream not open for reading", lstr);
572         }
573         if (!lstr->imp->reader) {
574                 Lstream_internal_error("lstream has no reader", lstr);
575         }
576         return lstr->imp->reader(lstr, buffer, size);
577 }
578
579 /* Assuming the buffer is empty, fill it up again. */
580
581 static Lstream_data_count
582 Lstream_read_more(lstream_t lstr)
583 {
584         /* If someone requested a larger buffer size, so be it! */
585         Lstream_data_count size_needed = max(1, lstr->buffering_size);
586         Lstream_data_count size_gotten;
587
588         LSTR_ALLOC_TO(lstr->in_buffer, lstr->in_buffer_size,
589                       size_needed, unsigned char);
590         size_gotten = Lstream_raw_read(lstr, lstr->in_buffer, size_needed);
591         lstr->in_buffer_current = max(0, size_gotten);
592         lstr->in_buffer_ind = 0;
593         return size_gotten < 0 ? -1 : size_gotten;
594 }
595
596 Lstream_data_count
597 Lstream_read(lstream_t lstr, void *data, Lstream_data_count size)
598 {
599         unsigned char *p = data;
600         Lstream_data_count off = 0;
601         Lstream_data_count chunk;
602         int error_occurred = 0;
603
604         /* trivial cases first */
605         if (UNLIKELY(size == 0)) {
606                 return 0;
607         }
608
609         /* First try to get some data from the unget buffer */
610         chunk = min(size, lstr->unget_buffer_ind);
611         if (chunk > 0) {
612                 /* The bytes come back in reverse order. */
613                 for (; off < chunk; off++) {
614                         p[off] = lstr->unget_buffer[--lstr->unget_buffer_ind];
615                 }
616                 lstr->byte_count += chunk;
617                 size -= chunk;
618         }
619
620         while (size > 0) {
621                 /* Take whatever we can from the in buffer */
622                 chunk = min(size,
623                             lstr->in_buffer_current - lstr->in_buffer_ind);
624                 if (chunk > 0) {
625                         memcpy(p + off, lstr->in_buffer + lstr->in_buffer_ind,
626                                chunk);
627                         lstr->in_buffer_ind += chunk;
628                         lstr->byte_count += chunk;
629                         size -= chunk;
630                         off += chunk;
631                 }
632
633                 /* If we need some more, try to get some more from the stream's
634                    end */
635                 if (size > 0) {
636                         Lstream_data_count retval = Lstream_read_more(lstr);
637                         if (retval < 0) {
638                                 error_occurred = 1;
639                         }
640                         if (retval <= 0) {
641                                 break;
642                         }
643                 }
644         }
645
646         /* #### Beware of OFF ending up 0. */
647         if ((lstr->flags & LSTREAM_FL_NO_PARTIAL_CHARS) && off > 0) {
648                 /* It's quite possible for us to get passed an incomplete
649                    character at the end.  We need to spit back that
650                    incomplete character. */
651                 const unsigned char *dataend = p + off - 1;
652                 /* Optimize the most common case. */
653                 if (!BYTE_ASCII_P(*dataend)) {
654                         /* Go back to the beginning of the last (and possibly
655                            partial) character, and bump forward to see if the
656                            character is complete. */
657                         VALIDATE_CHARPTR_BACKWARD(dataend);
658                         if (dataend + REP_BYTES_BY_FIRST_BYTE(*dataend) !=
659                             p + off) {
660                                 Lstream_data_count newoff = dataend - p;
661                                 /* If not, chop the size down to ignore the last
662                                    char and stash it away for next time. */
663                                 Lstream_unread(lstr, dataend, off - newoff);
664                                 off = newoff;
665                         }
666                 }
667         }
668
669         return off == 0 && error_occurred ? -1 : off;
670 }
671
672 void
673 Lstream_unread(lstream_t lstr, const void *data, Lstream_data_count size)
674 {
675         const unsigned char *p = data;
676
677         /* Make sure buffer is big enough */
678         LSTR_ALLOC_TO(lstr->unget_buffer, lstr->unget_buffer_size,
679                       lstr->unget_buffer_ind + size, unsigned char);
680
681         lstr->byte_count -= size;
682
683         /* Bytes have to go on in reverse order -- they are reversed
684            again when read back. */
685         while (size--) {
686                 lstr->unget_buffer[lstr->unget_buffer_ind++] = p[size];
687         }
688         return;
689 }
690
691 int
692 Lstream_rewind(lstream_t lstr)
693 {
694         if (!lstr->imp->rewinder) {
695                 Lstream_internal_error("lstream has no rewinder", lstr);
696         }
697         if (Lstream_flush(lstr) < 0) {
698                 return -1;
699         }
700         lstr->byte_count = 0;
701         return lstr->imp->rewinder(lstr);
702 }
703
704 int
705 Lstream_seekable_p(lstream_t lstr)
706 {
707         if (!lstr->imp->rewinder) {
708                 return 0;
709         }
710         if (!lstr->imp->seekable_p) {
711                 return 1;
712         }
713         return lstr->imp->seekable_p(lstr);
714 }
715
716 static int
717 Lstream_pseudo_close(lstream_t lstr)
718 {
719         if (!(lstr->flags & LSTREAM_FL_IS_OPEN)) {
720                 Lstream_internal_error("lstream is not open", lstr);
721         }
722         /* don't check errors here -- best not to risk file descriptor loss */
723         return Lstream_flush(lstr);
724 }
725
726 int
727 Lstream_close(lstream_t lstr)
728 {
729         int rc = 0;
730
731         if (lstr->flags & LSTREAM_FL_IS_OPEN) {
732                 rc = Lstream_pseudo_close(lstr);
733                 /*
734                  * We used to return immediately if the closer method reported
735                  * failure, leaving the stream open.  But this is no good, for
736                  * the following reasons.
737                  *
738                  * 1. The finalizer method used in GC makes no provision for
739                  *    failure, so we must not return without freeing buffer
740                  *    memory.
741                  *
742                  * 2. The closer method may have already freed some memory
743                  *    used for I/O in this stream.  E.g. encoding_closer frees
744                  *    ENCODING_STREAM_DATA(stream)->runoff.  If a writer method
745                  *    tries to use this buffer later, it will write into memory
746                  *    that may have been allocated elsewhere.  Sometime later
747                  *    you will see a sign that says "Welcome to Crash City."
748                  *
749                  * 3. The closer can report failure if a flush fails in the
750                  *    other stream in a MULE encoding/decoding stream pair.
751                  *    The other stream in the pair is closed, but returning
752                  *    early leaves the current stream open.  If we try to
753                  *    flush the current stream later, we will crash when the
754                  *    flusher notices that the other end stream is closed.
755                  *
756                  * So, we no longer abort the close if the closer method
757                  * reports some kind of failure.  We still report the failure
758                  * to the caller.
759                  */
760                 if (lstr->imp->closer) {
761                         if ((lstr->imp->closer) (lstr) < 0) {
762                                 rc = -1;
763                         }
764                 }
765         }
766
767         lstr->flags &= ~LSTREAM_FL_IS_OPEN;
768         lstr->byte_count = 0;
769         /* Note that Lstream_flush() reset all the buffer indices.  That way,
770            the next call to Lstream_putc(), Lstream_getc(), or Lstream_ungetc()
771            on a closed stream will call into the function equivalents, which
772            will cause an error. */
773
774         /* We set the pointers to 0 so that we don't lose when this function is
775            called more than once on the same object */
776         if (lstr->out_buffer) {
777                 xfree(lstr->out_buffer);
778                 lstr->out_buffer = 0;
779         }
780         if (lstr->in_buffer) {
781                 xfree(lstr->in_buffer);
782                 lstr->in_buffer = 0;
783         }
784         if (lstr->unget_buffer) {
785                 xfree(lstr->unget_buffer);
786                 lstr->unget_buffer = 0;
787         }
788
789         return rc;
790 }
791
792 int
793 Lstream_fputc(lstream_t lstr, int c)
794 {
795         unsigned char ch = (unsigned char)c;
796         Lstream_data_count retval = Lstream_write_1(lstr, &ch, 1);
797         if (retval >= 0 && lstr->buffering == LSTREAM_LINE_BUFFERED
798             && ch == '\n') {
799                 return Lstream_flush_out(lstr);
800         }
801         return retval < 0 ? -1 : 0;
802 }
803
804 int
805 Lstream_fgetc(lstream_t lstr)
806 {
807         unsigned char ch;
808         if (Lstream_read(lstr, &ch, 1) <= 0) {
809                 return -1;
810         }
811         return ch;
812 }
813
814 void
815 Lstream_fungetc(lstream_t lstr, int c)
816 {
817         unsigned char ch = (unsigned char)c;
818         Lstream_unread(lstr, &ch, 1);
819 }
820
821 int
822 Lstream_get_fd(lstream_t lstr)
823 {
824         int rc = -1;
825
826         if (lstr->imp->get_fd && (rc = (lstr->imp->get_fd)(lstr)) < 0) {
827                 rc = -1;
828         }
829         return rc;
830 }
831 \f
832 /************************ some stream implementations *********************/
833
834 /*********** a stdio stream ***********/
835
836 typedef struct stdio_stream_s *stdio_stream_t;
837 struct stdio_stream_s {
838         FILE *file;
839         int closing;
840 };
841
842 #define STDIO_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, stdio)
843
844 DEFINE_LSTREAM_IMPLEMENTATION("stdio", lstream_stdio,
845                               sizeof(struct stdio_stream_s));
846
847 static Lisp_Object
848 make_stdio_stream_1(FILE * stream, int flags, const char *mode)
849 {
850         Lisp_Object obj;
851         lstream_t lstr = Lstream_new(lstream_stdio, mode);
852         stdio_stream_t str = STDIO_STREAM_DATA(lstr);
853         str->file = stream;
854         str->closing = flags & LSTR_CLOSING;
855         lstr->flags |= LSTREAM_FL_CLOSE_AT_DISKSAVE;
856         XSETLSTREAM(obj, lstr);
857         return obj;
858 }
859
860 Lisp_Object make_stdio_input_stream(FILE * stream, int flags)
861 {
862         return make_stdio_stream_1(stream, flags, "r");
863 }
864
865 Lisp_Object make_stdio_output_stream(FILE * stream, int flags)
866 {
867         return make_stdio_stream_1(stream, flags, "w");
868 }
869
870 /* #### From reading the Unix 98 specification, it appears that if we
871    want stdio_reader() to be completely correct, we should check for
872    0 < val < size and if so, check to see if an error has occurred.
873    If an error has occurred, but val is non-zero, we should go ahead
874    and act as if the read was successful, but remember in some fashion
875    or other, that an error has occurred, and report that on the next
876    call to stdio_reader instead of calling fread() again.
877
878    Currently, in such a case, we end up calling fread() twice and we
879    assume that
880
881    1) this is not harmful, and
882    2) the error will still be reported on the second read.
883
884    This is probably reasonable, so I don't think we should change this
885    code (it could even be argued that the error might have fixed
886    itself, so we should do the fread() again.  */
887
888 static Lstream_data_count
889 stdio_reader(lstream_t stream, unsigned char *data, Lstream_data_count size)
890 {
891         stdio_stream_t str = STDIO_STREAM_DATA(stream);
892         Lstream_data_count val = fread(data, 1, size, str->file);
893         if (!val && ferror(str->file)) {
894                 return -1;
895         }
896         return val;
897 }
898
899 static Lstream_data_count
900 stdio_writer(lstream_t stream, const unsigned char *data,
901              Lstream_data_count size)
902 {
903         stdio_stream_t str = STDIO_STREAM_DATA(stream);
904         Lstream_data_count val = fwrite(data, 1, size, str->file);
905         if (!val && ferror(str->file)) {
906                 return -1;
907         }
908         return val;
909 }
910
911 static int
912 stdio_rewinder(lstream_t stream)
913 {
914         stdio_stream_t p = STDIO_STREAM_DATA(stream);
915         rewind(p->file);
916         return 0;
917 }
918
919 static int
920 stdio_seekable_p(lstream_t stream)
921 {
922         struct stat lestat;
923         stdio_stream_t str = STDIO_STREAM_DATA(stream);
924
925         if (fstat(fileno(str->file), &lestat) < 0) {
926                 return 0;
927         }
928         return S_ISREG(lestat.st_mode);
929 }
930
931 static int
932 stdio_flusher(lstream_t stream)
933 {
934         stdio_stream_t str = STDIO_STREAM_DATA(stream);
935
936         if (stream->flags & LSTREAM_FL_WRITE) {
937                 return fflush(str->file);
938         } else {
939                 return 0;
940         }
941 }
942
943 static int
944 stdio_closer(lstream_t stream)
945 {
946         stdio_stream_t str = STDIO_STREAM_DATA(stream);
947
948         if (str->closing) {
949                 return fclose(str->file);
950         } else if (stream->flags & LSTREAM_FL_WRITE) {
951                 return fflush(str->file);
952         } else {
953                 return 0;
954         }
955 }
956
957 /*********** a file descriptor ***********/
958
959 typedef struct filedesc_stream_s *filedesc_stream_t;
960 struct filedesc_stream_s {
961         int fd;
962         int pty_max_bytes;
963         Bufbyte eof_char;
964         int starting_pos;
965         int current_pos;
966         int end_pos;
967         int chars_sans_newline;
968         bool closing:1;
969         bool allow_quit:1;
970         bool blocked_ok:1;
971         bool pty_flushing:1;
972         bool blocking_error_p:1;
973 };
974
975 #define FILEDESC_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, filedesc)
976
977 DEFINE_LSTREAM_IMPLEMENTATION("filedesc", lstream_filedesc,
978                               sizeof(struct filedesc_stream_s));
979
980 /* Make a stream that reads from or writes to a file descriptor FILEDESC.
981    OFFSET is the offset from the *current* file pointer that the reading
982    should start at.  COUNT is the number of bytes to be read (it is
983    ignored when writing); -1 for unlimited. */
984 static Lisp_Object
985 make_filedesc_stream_1(int filedesc, int offset, int count, int flags,
986                        const char *mode)
987 {
988         Lisp_Object obj;
989         if (filedesc < 0)
990                 return obj;
991         lstream_t lstr = Lstream_new(lstream_filedesc, mode);
992         filedesc_stream_t fstr = FILEDESC_STREAM_DATA(lstr);
993
994         fstr->fd = filedesc;
995         fstr->closing = !!(flags & LSTR_CLOSING);
996         fstr->allow_quit = !!(flags & LSTR_ALLOW_QUIT);
997         fstr->blocked_ok = !!(flags & LSTR_BLOCKED_OK);
998         fstr->pty_flushing = !!(flags & LSTR_PTY_FLUSHING);
999         fstr->blocking_error_p = 0;
1000         fstr->chars_sans_newline = 0;
1001         fstr->starting_pos = lseek(filedesc, offset, SEEK_CUR);
1002         fstr->current_pos = max(fstr->starting_pos, 0);
1003
1004         if (count < 0) {
1005                 fstr->end_pos = -1;
1006         } else {
1007                 fstr->end_pos = fstr->starting_pos + count;
1008         }
1009         lstr->flags |= LSTREAM_FL_CLOSE_AT_DISKSAVE;
1010         XSETLSTREAM(obj, lstr);
1011         return obj;
1012 }
1013
1014 Lisp_Object
1015 make_filedesc_input_stream(int filedesc, int offset, int count, int flags)
1016 {
1017         return make_filedesc_stream_1(filedesc, offset, count, flags, "r");
1018 }
1019
1020 Lisp_Object
1021 make_filedesc_output_stream(int filedesc, int offset, int count, int flags)
1022 {
1023         return make_filedesc_stream_1(filedesc, offset, count, flags, "w");
1024 }
1025
1026 static Lstream_data_count
1027 filedesc_reader(lstream_t stream, unsigned char *data, Lstream_data_count size)
1028 {
1029         Lstream_data_count nread;
1030         filedesc_stream_t str = FILEDESC_STREAM_DATA(stream);
1031
1032         if (str->end_pos >= 0) {
1033                 size = min(size,
1034                            (Lstream_data_count)
1035                            (str->end_pos - str->current_pos));
1036         }
1037         nread = str->allow_quit
1038                 ? read_allowing_quit(str->fd, data, size)
1039                 : read(str->fd, data, size);
1040         if (nread > 0) {
1041                 str->current_pos += nread;
1042         }
1043         return nread;
1044 }
1045
1046 static int
1047 errno_would_block_p(int val)
1048 {
1049 #ifdef EWOULDBLOCK
1050         if (val == EWOULDBLOCK) {
1051                 return 1;
1052         }
1053 #endif
1054 #ifdef EAGAIN
1055         if (val == EAGAIN) {
1056                 return 1;
1057         }
1058 #endif
1059         return 0;
1060 }
1061
1062 static Lstream_data_count
1063 filedesc_writer(lstream_t stream, const unsigned char *data,
1064                 Lstream_data_count size)
1065 {
1066         filedesc_stream_t str = FILEDESC_STREAM_DATA(stream);
1067         Lstream_data_count retval;
1068         int need_newline = 0;
1069
1070         /* This function would be simple if it were not for the blasted
1071            PTY max-bytes stuff.  Why the hell can't they just have written
1072            the PTY drivers right so this problem doesn't exist?
1073
1074            Maybe all the PTY crap here should be moved into another stream
1075            that does nothing but periodically insert EOF's as necessary. */
1076         if (str->pty_flushing) {
1077                 /* To make life easy, only send out one line at the most. */
1078                 const unsigned char *ptr;
1079
1080                 ptr = (const unsigned char *)memchr(data, '\n', size);
1081                 if (ptr) {
1082                         need_newline = 1;
1083                 } else {
1084                         ptr = data + size;
1085                 }
1086                 if (ptr - data >=
1087                     str->pty_max_bytes - str->chars_sans_newline) {
1088                         ptr = data +
1089                                 str->pty_max_bytes - str->chars_sans_newline;
1090                         need_newline = 0;
1091                 }
1092                 size = ptr - data;
1093         }
1094
1095         /**** start of non-PTY-crap ****/
1096         if (size > 0) {
1097                 retval = str->allow_quit
1098                         ? write_allowing_quit(str->fd, data, size)
1099                         : write(str->fd, data, size);
1100         } else {
1101                 retval = 0;
1102         }
1103         if (retval < 0 && errno_would_block_p(errno) && str->blocked_ok) {
1104                 str->blocking_error_p = 1;
1105                 return 0;
1106         }
1107         str->blocking_error_p = 0;
1108         if (retval < 0) {
1109                 return retval;
1110         }
1111         /**** end non-PTY-crap ****/
1112
1113         if (str->pty_flushing) {
1114                 str->chars_sans_newline += retval;
1115                 /* Note that a newline was not among the bytes written out.
1116                    Add to the number of non-newline bytes written out,
1117                    and flush with an EOF if necessary.  Be careful to
1118                    keep track of write errors as we go along and look
1119                    out for EWOULDBLOCK. */
1120                 if (str->chars_sans_newline >= str->pty_max_bytes) {
1121                         Lstream_data_count retval2 = str->allow_quit
1122                                 ? write_allowing_quit(
1123                                         str->fd, &str->eof_char, 1)
1124                                 : write(str->fd, &str->eof_char, 1);
1125
1126                         if (retval2 > 0) {
1127                                 str->chars_sans_newline = 0;
1128                         }
1129                         else if (retval2 < 0) {
1130                                 /* Error writing the EOF char.  If nothing got
1131                                    written, then treat this as an error --
1132                                    either return an error condition or set the
1133                                    blocking-error flag. */
1134                                 if (retval == 0) {
1135                                         if (errno_would_block_p(errno)
1136                                             && str->blocked_ok) {
1137                                                 str->blocking_error_p = 1;
1138                                                 return 0;
1139                                         } else
1140                                                 return retval2;
1141                                 } else {
1142                                         return retval;
1143                                 }
1144                         }
1145                 }
1146         }
1147
1148         /* The need_newline flag is necessary because otherwise when the
1149            first byte is a newline, we'd get stuck never writing anything
1150            in pty-flushing mode. */
1151         if (need_newline) {
1152                 Bufbyte nl = '\n';
1153                 Lstream_data_count retval2 = str->allow_quit
1154                         ? write_allowing_quit(str->fd, &nl, 1)
1155                         : write(str->fd, &nl, 1);
1156
1157                 if (retval2 > 0) {
1158                         str->chars_sans_newline = 0;
1159                         retval++;
1160                 } else if (retval2 < 0) {
1161                         /* Error writing the newline char.  If nothing got
1162                            written, then treat this as an error -- either return
1163                            an error condition or set the blocking-error flag. */
1164                         if (retval == 0) {
1165                                 if (errno_would_block_p(errno)
1166                                     && str->blocked_ok) {
1167                                         str->blocking_error_p = 1;
1168                                         return 0;
1169                                 } else {
1170                                         return retval2;
1171                                 }
1172                         } else {
1173                                 return retval;
1174                         }
1175                 }
1176         }
1177
1178         return retval;
1179 }
1180
1181 static int
1182 filedesc_rewinder(lstream_t stream)
1183 {
1184         filedesc_stream_t str = FILEDESC_STREAM_DATA(stream);
1185         if (str->starting_pos < 0 ||
1186             lseek(FILEDESC_STREAM_DATA(stream)->fd, str->starting_pos,
1187                   SEEK_SET) == -1) {
1188                 return -1;
1189         } else {
1190                 str->current_pos = str->starting_pos;
1191                 return 0;
1192         }
1193 }
1194
1195 static int
1196 filedesc_seekable_p(lstream_t stream)
1197 {
1198         filedesc_stream_t str = FILEDESC_STREAM_DATA(stream);
1199
1200         if (str->starting_pos < 0) {
1201                 return 0;
1202         } else {
1203                 struct stat lestat;
1204
1205                 if (fstat(str->fd, &lestat) < 0) {
1206                         return 0;
1207                 }
1208                 return S_ISREG(lestat.st_mode);
1209         }
1210 }
1211
1212 static int
1213 filedesc_closer(lstream_t stream)
1214 {
1215         filedesc_stream_t str = FILEDESC_STREAM_DATA(stream);
1216
1217         if (str->closing) {
1218                 return close(str->fd);
1219         } else {
1220                 return 0;
1221         }
1222 }
1223
1224 static int
1225 filedesc_was_blocked_p(lstream_t stream)
1226 {
1227         filedesc_stream_t str = FILEDESC_STREAM_DATA(stream);
1228         return str->blocking_error_p;
1229 }
1230
1231 void
1232 filedesc_stream_set_pty_flushing(lstream_t stream, int pty_max_bytes,
1233                                  Bufbyte eof_char)
1234 {
1235         filedesc_stream_t str = FILEDESC_STREAM_DATA(stream);
1236         str->pty_max_bytes = pty_max_bytes;
1237         str->eof_char = eof_char;
1238         str->pty_flushing = 1;
1239         return;
1240 }
1241
1242 static int
1243 filedesc_get_fd(lstream_t stream)
1244 {
1245         filedesc_stream_t str = FILEDESC_STREAM_DATA(stream);
1246         return str->fd;
1247 }
1248
1249 /*********** read from a Lisp string ***********/
1250
1251 #define LISP_STRING_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, lisp_string)
1252
1253 typedef struct lisp_string_stream_s *lisp_string_stream_t;
1254 struct lisp_string_stream_s {
1255         Lisp_Object obj;
1256         Bytecount init_offset;
1257         Bytecount offset, end;
1258 };
1259
1260 DEFINE_LSTREAM_IMPLEMENTATION("lisp-string", lstream_lisp_string,
1261                               sizeof(struct lisp_string_stream_s));
1262
1263 Lisp_Object
1264 make_lisp_string_input_stream(Lisp_Object string, Bytecount offset,
1265                               Bytecount len)
1266 {
1267         Lisp_Object obj;
1268         lstream_t lstr;
1269         lisp_string_stream_t str;
1270
1271         CHECK_STRING(string);
1272         if (len < 0) {
1273                 len = XSTRING_LENGTH(string) - offset;
1274         }
1275         assert(offset >= 0);
1276         assert(len >= 0);
1277         assert(offset + len <= XSTRING_LENGTH(string));
1278
1279         lstr = Lstream_new(lstream_lisp_string, "r");
1280         str = LISP_STRING_STREAM_DATA(lstr);
1281         str->offset = offset;
1282         str->end = offset + len;
1283         str->init_offset = offset;
1284         str->obj = string;
1285         XSETLSTREAM(obj, lstr);
1286         return obj;
1287 }
1288
1289 static Lstream_data_count
1290 lisp_string_reader(lstream_t stream, unsigned char *data,
1291                    Lstream_data_count size)
1292 {
1293         lisp_string_stream_t str = LISP_STRING_STREAM_DATA(stream);
1294         /* Don't lose if the string shrank past us ... */
1295         Bytecount offset = min(str->offset, XSTRING_LENGTH(str->obj));
1296         Bufbyte *strstart = XSTRING_DATA(str->obj);
1297         Bufbyte *start = strstart + offset;
1298
1299         /* ... or if someone changed the string and we ended up in the
1300            middle of a character. */
1301         /* Being in the middle of a character is `normal' unless
1302            LSTREAM_NO_PARTIAL_CHARS - mrb */
1303         if (stream->flags & LSTREAM_FL_NO_PARTIAL_CHARS) {
1304                 VALIDATE_CHARPTR_BACKWARD(start);
1305         }
1306         offset = start - strstart;
1307         size = min(size, (Lstream_data_count) (str->end - offset));
1308         memcpy(data, start, size);
1309         str->offset = offset + size;
1310         return size;
1311 }
1312
1313 static int
1314 lisp_string_rewinder(lstream_t stream)
1315 {
1316         lisp_string_stream_t str = LISP_STRING_STREAM_DATA(stream);
1317         int pos = str->init_offset;
1318
1319         if (pos > str->end) {
1320                 pos = str->end;
1321         }
1322         /* Don't lose if the string shrank past us ... */
1323         pos = min(pos, XSTRING_LENGTH(str->obj));
1324         /* ... or if someone changed the string and we ended up in the
1325            middle of a character. */
1326         {
1327                 Bufbyte *strstart = XSTRING_DATA(str->obj);
1328                 Bufbyte *start = strstart + pos;
1329                 VALIDATE_CHARPTR_BACKWARD(start);
1330                 pos = start - strstart;
1331         }
1332         str->offset = pos;
1333         return 0;
1334 }
1335
1336 static Lisp_Object
1337 lisp_string_marker(Lisp_Object stream)
1338 {
1339         lisp_string_stream_t str = LISP_STRING_STREAM_DATA(XLSTREAM(stream));
1340         return str->obj;
1341 }
1342
1343 /*********** a fixed buffer ***********/
1344
1345 #define FIXED_BUFFER_STREAM_DATA(stream)                \
1346         LSTREAM_TYPE_DATA (stream, fixed_buffer)
1347
1348 typedef struct fixed_buffer_stream_s *fixed_buffer_stream_t;
1349 struct fixed_buffer_stream_s {
1350         const unsigned char *inbuf;
1351         unsigned char *outbuf;
1352         Lstream_data_count size;
1353         Lstream_data_count offset;
1354 };
1355
1356 DEFINE_LSTREAM_IMPLEMENTATION("fixed-buffer", lstream_fixed_buffer,
1357                               sizeof(struct fixed_buffer_stream_s));
1358
1359 Lisp_Object
1360 make_fixed_buffer_input_stream(const void *buf, Lstream_data_count size)
1361 {
1362         Lisp_Object obj;
1363         lstream_t lstr = Lstream_new(lstream_fixed_buffer, "r");
1364         fixed_buffer_stream_t str = FIXED_BUFFER_STREAM_DATA(lstr);
1365         str->inbuf = (const unsigned char *)buf;
1366         str->size = size;
1367         XSETLSTREAM(obj, lstr);
1368         return obj;
1369 }
1370
1371 Lisp_Object
1372 make_fixed_buffer_output_stream(void *buf, Lstream_data_count size)
1373 {
1374         Lisp_Object obj;
1375         lstream_t lstr = Lstream_new(lstream_fixed_buffer, "w");
1376         fixed_buffer_stream_t str = FIXED_BUFFER_STREAM_DATA(lstr);
1377         str->outbuf = (unsigned char *)buf;
1378         str->size = size;
1379         XSETLSTREAM(obj, lstr);
1380         return obj;
1381 }
1382
1383 static Lstream_data_count
1384 fixed_buffer_reader(lstream_t stream, unsigned char *data,
1385                     Lstream_data_count size)
1386 {
1387         fixed_buffer_stream_t str = FIXED_BUFFER_STREAM_DATA(stream);
1388         size = min(size, str->size - str->offset);
1389         memcpy(data, str->inbuf + str->offset, size);
1390         str->offset += size;
1391         return size;
1392 }
1393
1394 static Lstream_data_count
1395 fixed_buffer_writer(lstream_t stream, const unsigned char *data,
1396                     Lstream_data_count size)
1397 {
1398         fixed_buffer_stream_t str = FIXED_BUFFER_STREAM_DATA(stream);
1399         if (str->offset == str->size) {
1400                 /* If we're at the end, just throw away the data and pretend
1401                    we wrote all of it.  If we return 0, then the lstream routines
1402                    will try again and again to write it out. */
1403                 return size;
1404         }
1405         size = min(size, str->size - str->offset);
1406         memcpy(str->outbuf + str->offset, data, size);
1407         str->offset += size;
1408         return size;
1409 }
1410
1411 static int
1412 fixed_buffer_rewinder(lstream_t stream)
1413 {
1414         fixed_buffer_stream_t p = FIXED_BUFFER_STREAM_DATA(stream);
1415         p->offset = 0;
1416         return 0;
1417 }
1418
1419 const unsigned char*
1420 fixed_buffer_input_stream_ptr(lstream_t stream)
1421 {
1422         fixed_buffer_stream_t p = FIXED_BUFFER_STREAM_DATA(stream);
1423         assert(stream->imp == lstream_fixed_buffer);
1424         return p->inbuf;
1425 }
1426
1427 unsigned char*
1428 fixed_buffer_output_stream_ptr(lstream_t stream)
1429 {
1430         fixed_buffer_stream_t p = FIXED_BUFFER_STREAM_DATA(stream);
1431         assert(stream->imp == lstream_fixed_buffer);
1432         return p->outbuf;
1433 }
1434
1435 /*********** write to a resizing buffer ***********/
1436
1437 #define RESIZING_BUFFER_STREAM_DATA(stream)             \
1438         LSTREAM_TYPE_DATA (stream, resizing_buffer)
1439
1440 typedef struct resizing_buffer_stream_s *resizing_buffer_stream_t;
1441 struct resizing_buffer_stream_s {
1442         unsigned char *buf;
1443         Lstream_data_count allocked;
1444         int max_stored;
1445         int stored;
1446 };
1447
1448 DEFINE_LSTREAM_IMPLEMENTATION("resizing-buffer", lstream_resizing_buffer,
1449                               sizeof(struct resizing_buffer_stream_s));
1450
1451 Lisp_Object make_resizing_buffer_output_stream(void)
1452 {
1453         Lisp_Object obj;
1454         XSETLSTREAM(obj, Lstream_new(lstream_resizing_buffer, "w"));
1455         return obj;
1456 }
1457
1458 static Lstream_data_count
1459 resizing_buffer_writer(lstream_t stream, const unsigned char *data,
1460                        Lstream_data_count size)
1461 {
1462         resizing_buffer_stream_t str = RESIZING_BUFFER_STREAM_DATA(stream);
1463
1464         LSTR_ALLOC_TO(str->buf, str->allocked, str->stored + size,
1465                       unsigned char);
1466         memcpy(str->buf + str->stored, data, size);
1467         str->stored += size;
1468         str->max_stored = max(str->max_stored, str->stored);
1469         return size;
1470 }
1471
1472 static int
1473 resizing_buffer_rewinder(lstream_t stream)
1474 {
1475         resizing_buffer_stream_t p = RESIZING_BUFFER_STREAM_DATA(stream);
1476         p->stored = 0;
1477         return 0;
1478 }
1479
1480 static int
1481 resizing_buffer_closer(lstream_t stream)
1482 {
1483         resizing_buffer_stream_t str = RESIZING_BUFFER_STREAM_DATA(stream);
1484
1485         if (str->buf) {
1486                 xfree(str->buf);
1487                 str->buf = 0;
1488         }
1489         return 0;
1490 }
1491
1492 unsigned char*
1493 resizing_buffer_stream_ptr(lstream_t stream)
1494 {
1495         resizing_buffer_stream_t p = RESIZING_BUFFER_STREAM_DATA(stream);
1496         return p->buf;
1497 }
1498
1499 /*********** write to an unsigned-char dynarr ***********/
1500
1501 /* Note: If you have a dynarr whose type is not unsigned_char_dynarr
1502    but which is really just an unsigned_char_dynarr (e.g. its type
1503    is Bufbyte or Extbyte), just cast to unsigned_char_dynarr. */
1504
1505 #define DYNARR_STREAM_DATA(stream)              \
1506         LSTREAM_TYPE_DATA (stream, dynarr)
1507
1508 typedef struct dynarr_stream_s *dynarr_stream_t;
1509 struct dynarr_stream_s {
1510         unsigned_char_dynarr *dyn;
1511 };
1512
1513 DEFINE_LSTREAM_IMPLEMENTATION("dynarr", lstream_dynarr,
1514                               sizeof(struct dynarr_stream_s));
1515
1516 Lisp_Object
1517 make_dynarr_output_stream(unsigned_char_dynarr * dyn)
1518 {
1519         Lisp_Object obj;
1520         dynarr_stream_t p;
1521
1522         XSETLSTREAM(obj, Lstream_new(lstream_dynarr, "w"));
1523         p = DYNARR_STREAM_DATA(XLSTREAM(obj));
1524         p->dyn = dyn;
1525         return obj;
1526 }
1527
1528 static Lstream_data_count
1529 dynarr_writer(lstream_t stream, const unsigned char *data,
1530               Lstream_data_count size)
1531 {
1532         dynarr_stream_t str = DYNARR_STREAM_DATA(stream);
1533         Dynarr_add_many(str->dyn, data, size);
1534         return size;
1535 }
1536
1537 static int
1538 dynarr_rewinder(lstream_t stream)
1539 {
1540         dynarr_stream_t p = DYNARR_STREAM_DATA(stream);
1541         Dynarr_reset(p->dyn);
1542         return 0;
1543 }
1544
1545 static int
1546 dynarr_closer(lstream_t stream)
1547 {
1548         return 0;
1549 }
1550
1551 /************ read from or write to a Lisp buffer ************/
1552
1553 /* Note: Lisp-buffer read streams never return partial characters,
1554    and Lisp-buffer write streams expect to never get partial
1555    characters. */
1556
1557 #define LISP_BUFFER_STREAM_DATA(stream)         \
1558         LSTREAM_TYPE_DATA (stream, lisp_buffer)
1559
1560 typedef struct lisp_buffer_stream_s *lisp_buffer_stream_t;
1561 struct lisp_buffer_stream_s {
1562         Lisp_Object buffer;
1563         Lisp_Object orig_start;
1564         /* we use markers to properly deal with insertion/deletion */
1565         Lisp_Object start, end;
1566         int flags;
1567 };
1568
1569 DEFINE_LSTREAM_IMPLEMENTATION("lisp-buffer", lstream_lisp_buffer,
1570                               sizeof(struct lisp_buffer_stream_s));
1571
1572 static Lisp_Object
1573 make_lisp_buffer_stream_1(struct buffer *buf, Bufpos start, Bufpos end,
1574                           int flags, const char *mode)
1575 {
1576         Lisp_Object obj;
1577         lstream_t lstr;
1578         lisp_buffer_stream_t str;
1579         Bufpos bmin, bmax;
1580         int reading = !strcmp(mode, "r");
1581
1582         /* Make sure the luser didn't pass "w" in. */
1583         if (!strcmp(mode, "w")) {
1584                 abort();
1585         }
1586
1587         if (flags & LSTR_IGNORE_ACCESSIBLE) {
1588                 bmin = BUF_BEG(buf);
1589                 bmax = BUF_Z(buf);
1590         } else {
1591                 bmin = BUF_BEGV(buf);
1592                 bmax = BUF_ZV(buf);
1593         }
1594
1595         if (start == -1) {
1596                 start = bmin;
1597         }
1598         if (end == -1) {
1599                 end = bmax;
1600         }
1601         assert(bmin <= start);
1602         assert(start <= bmax);
1603         if (reading) {
1604                 assert(bmin <= end);
1605                 assert(end <= bmax);
1606                 assert(start <= end);
1607         }
1608
1609         lstr = Lstream_new(lstream_lisp_buffer, mode);
1610         str = LISP_BUFFER_STREAM_DATA(lstr);
1611         {
1612                 Lisp_Object marker;
1613                 Lisp_Object buffer;
1614
1615                 XSETBUFFER(buffer, buf);
1616                 marker = Fmake_marker();
1617                 Fset_marker(marker, make_int(start), buffer);
1618                 str->start = marker;
1619                 marker = Fmake_marker();
1620                 Fset_marker(marker, make_int(start), buffer);
1621                 str->orig_start = marker;
1622                 if (reading) {
1623                         marker = Fmake_marker();
1624                         Fset_marker(marker, make_int(end), buffer);
1625                         str->end = marker;
1626                 } else {
1627                         str->end = Qnil;
1628                 }
1629                 str->buffer = buffer;
1630         }
1631         str->flags = flags;
1632         XSETLSTREAM(obj, lstr);
1633         return obj;
1634 }
1635
1636 Lisp_Object
1637 make_lisp_buffer_input_stream(struct buffer *buf, Bufpos start, Bufpos end,
1638                               int flags)
1639 {
1640         return make_lisp_buffer_stream_1(buf, start, end, flags, "r");
1641 }
1642
1643 Lisp_Object
1644 make_lisp_buffer_output_stream(struct buffer *buf, Bufpos pos, int flags)
1645 {
1646         Lisp_Object lstr = make_lisp_buffer_stream_1(buf, pos, 0, flags, "wc");
1647
1648         Lstream_set_character_mode(XLSTREAM(lstr));
1649         return lstr;
1650 }
1651
1652 static Lstream_data_count
1653 lisp_buffer_reader(lstream_t stream, unsigned char *data,
1654                    Lstream_data_count size)
1655 {
1656         lisp_buffer_stream_t str = LISP_BUFFER_STREAM_DATA(stream);
1657         unsigned char *orig_data = data;
1658         Bytind start;
1659         Bytind end;
1660         struct buffer *buf = XBUFFER(str->buffer);
1661
1662         if (!BUFFER_LIVE_P(buf)) {
1663                 /* Fut. */
1664                 return 0;
1665         }
1666
1667         /* NOTE: We do all our operations in Bytind's.
1668            Keep in mind that SIZE is a value in bytes, not chars. */
1669
1670         start = bi_marker_position(str->start);
1671         end = bi_marker_position(str->end);
1672         if (!(str->flags & LSTR_IGNORE_ACCESSIBLE)) {
1673                 start = bytind_clip_to_bounds(BI_BUF_BEGV(buf), start,
1674                                               BI_BUF_ZV(buf));
1675                 end = bytind_clip_to_bounds(BI_BUF_BEGV(buf), end,
1676                                             BI_BUF_ZV(buf));
1677         }
1678
1679         size = min(size, (Lstream_data_count) (end - start));
1680         end = start + size;
1681         /* We cannot return a partial character. */
1682         VALIDATE_BYTIND_BACKWARD(buf, end);
1683
1684         while (start < end) {
1685                 Bytind _ceil_;
1686                 Bytecount chunk;
1687
1688                 if (str->flags & LSTR_IGNORE_ACCESSIBLE) {
1689                         _ceil_ = BI_BUF_CEILING_OF_IGNORE_ACCESSIBLE(
1690                                 buf, start);
1691                 } else {
1692                         _ceil_ = BI_BUF_CEILING_OF(buf, start);
1693                 }
1694                 chunk = min(_ceil_, end) - start;
1695                 memcpy(data, BI_BUF_BYTE_ADDRESS(buf, start), chunk);
1696                 data += chunk;
1697                 start += chunk;
1698         }
1699
1700         if (EQ(buf->selective_display, Qt) && str->flags & LSTR_SELECTIVE) {
1701                 /* What a kludge.  What a kludge.  What a kludge. */
1702                 unsigned char *p;
1703                 for (p = orig_data; p < data; p++) {
1704                         if (*p == '\r') {
1705                                 *p = '\n';
1706                         }
1707                 }
1708         }
1709
1710         set_bi_marker_position(str->start, end);
1711         return data - orig_data;
1712 }
1713
1714 static Lstream_data_count
1715 lisp_buffer_writer(lstream_t stream, const unsigned char *data,
1716                    Lstream_data_count size)
1717 {
1718         lisp_buffer_stream_t str = LISP_BUFFER_STREAM_DATA(stream);
1719         Bufpos pos;
1720         struct buffer *buf = XBUFFER(str->buffer);
1721
1722         if (!BUFFER_LIVE_P(buf)) {
1723                 /* Fut. */
1724                 return 0;
1725         }
1726
1727         pos = marker_position(str->start);
1728         pos += buffer_insert_raw_string_1(buf, pos, data, size, 0);
1729         set_marker_position(str->start, pos);
1730         return size;
1731 }
1732
1733 static int
1734 lisp_buffer_rewinder(lstream_t stream)
1735 {
1736         lisp_buffer_stream_t str = LISP_BUFFER_STREAM_DATA(stream);
1737         struct buffer *buf = XBUFFER(str->buffer);
1738         long pos = marker_position(str->orig_start);
1739
1740         if (!BUFFER_LIVE_P(buf)) {
1741                 /* Fut. */
1742                 return -1;
1743         }
1744         if (pos > BUF_ZV(buf)) {
1745                 pos = BUF_ZV(buf);
1746         }
1747         if (pos < marker_position(str->orig_start)) {
1748                 pos = marker_position(str->orig_start);
1749         }
1750         if (MARKERP(str->end) && pos > marker_position(str->end)) {
1751                 pos = marker_position(str->end);
1752         }
1753         set_marker_position(str->start, pos);
1754         return 0;
1755 }
1756
1757 static Lisp_Object
1758 lisp_buffer_marker(Lisp_Object stream)
1759 {
1760         lisp_buffer_stream_t str = LISP_BUFFER_STREAM_DATA(XLSTREAM(stream));
1761
1762         mark_object(str->start);
1763         mark_object(str->end);
1764         return str->buffer;
1765 }
1766
1767 Bufpos
1768 lisp_buffer_stream_startpos(lstream_t stream)
1769 {
1770         lisp_buffer_stream_t p = LISP_BUFFER_STREAM_DATA(stream);
1771         return marker_position(p->start);
1772 }
1773
1774 #if defined(HAVE_OPENSSL) && defined(OPENSSL_SSL)
1775 #include "openssl.h"
1776 /* SSL things */
1777 typedef struct ssl_stream_s *ssl_stream_t;
1778 struct ssl_stream_s {
1779         SSL *conn;
1780         bool closing:1;
1781         bool allow_quit:1;
1782         bool blocked_ok:1;
1783         bool blocking_error_p:1;
1784 };
1785
1786 #define SSL_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, ssl)
1787
1788 DEFINE_LSTREAM_IMPLEMENTATION("ssl", lstream_ssl, sizeof(struct ssl_stream_s));
1789
1790 static Lisp_Object
1791 make_ssl_stream_1(SSL *conn, int flags, const char *mode)
1792 {
1793         Lisp_Object obj;
1794         lstream_t lstr = Lstream_new(lstream_ssl, mode);
1795         ssl_stream_t str = SSL_STREAM_DATA(lstr);
1796         str->conn = conn;
1797         XSETLSTREAM(obj, lstr);
1798         return obj;
1799 }
1800
1801 Lisp_Object
1802 make_ssl_input_stream(SSL *conn, int flags)
1803 {
1804         return make_ssl_stream_1(conn, flags, "r");
1805 }
1806
1807 Lisp_Object
1808 make_ssl_output_stream(SSL *conn, int flags)
1809 {
1810         return make_ssl_stream_1(conn, flags, "w");
1811 }
1812
1813 static Lstream_data_count
1814 ssl_reader(lstream_t stream, unsigned char *data, Lstream_data_count size)
1815 {
1816         Lstream_data_count nread;
1817         ssl_stream_t str = SSL_STREAM_DATA(stream);
1818
1819         nread = SSL_read(str->conn, data, size);
1820         if (nread < 0) {
1821                 return -1;
1822         }
1823         return nread;
1824 }
1825
1826 static Lstream_data_count
1827 ssl_writer(lstream_t stream, const unsigned char *data,
1828            Lstream_data_count size)
1829 {
1830         Lstream_data_count nwrite;
1831         ssl_stream_t str = SSL_STREAM_DATA(stream);
1832
1833         nwrite = SSL_write(str->conn, data, size);
1834         if (nwrite < 0) {
1835                 return -1;
1836         }
1837         return nwrite;
1838 }
1839
1840 static int
1841 ssl_closer(lstream_t stream)
1842 {
1843         ssl_stream_t str = SSL_STREAM_DATA(stream);
1844         if (str->closing) {
1845                 return SSL_shutdown(str->conn);
1846         } else {
1847                 return 0;
1848         }
1849 }
1850
1851 static int
1852 ssl_get_fd(lstream_t stream)
1853 {
1854         ssl_stream_t str = SSL_STREAM_DATA(stream);
1855         return SSL_get_rfd(str->conn);
1856 }
1857 #endif
1858 \f
1859 /************************************************************************/
1860 /*                            initialization                            */
1861 /************************************************************************/
1862
1863 void lstream_type_create(void)
1864 {
1865         LSTREAM_HAS_METHOD(stdio, reader);
1866         LSTREAM_HAS_METHOD(stdio, writer);
1867         LSTREAM_HAS_METHOD(stdio, rewinder);
1868         LSTREAM_HAS_METHOD(stdio, seekable_p);
1869         LSTREAM_HAS_METHOD(stdio, flusher);
1870         LSTREAM_HAS_METHOD(stdio, closer);
1871
1872         LSTREAM_HAS_METHOD(filedesc, reader);
1873         LSTREAM_HAS_METHOD(filedesc, writer);
1874         LSTREAM_HAS_METHOD(filedesc, was_blocked_p);
1875         LSTREAM_HAS_METHOD(filedesc, rewinder);
1876         LSTREAM_HAS_METHOD(filedesc, seekable_p);
1877         LSTREAM_HAS_METHOD(filedesc, closer);
1878         LSTREAM_HAS_METHOD(filedesc, get_fd);
1879
1880         LSTREAM_HAS_METHOD(lisp_string, reader);
1881         LSTREAM_HAS_METHOD(lisp_string, rewinder);
1882         LSTREAM_HAS_METHOD(lisp_string, marker);
1883
1884         LSTREAM_HAS_METHOD(fixed_buffer, reader);
1885         LSTREAM_HAS_METHOD(fixed_buffer, writer);
1886         LSTREAM_HAS_METHOD(fixed_buffer, rewinder);
1887
1888         LSTREAM_HAS_METHOD(resizing_buffer, writer);
1889         LSTREAM_HAS_METHOD(resizing_buffer, rewinder);
1890         LSTREAM_HAS_METHOD(resizing_buffer, closer);
1891
1892         LSTREAM_HAS_METHOD(dynarr, writer);
1893         LSTREAM_HAS_METHOD(dynarr, rewinder);
1894         LSTREAM_HAS_METHOD(dynarr, closer);
1895
1896         LSTREAM_HAS_METHOD(lisp_buffer, reader);
1897         LSTREAM_HAS_METHOD(lisp_buffer, writer);
1898         LSTREAM_HAS_METHOD(lisp_buffer, rewinder);
1899         LSTREAM_HAS_METHOD(lisp_buffer, marker);
1900
1901 #if defined(HAVE_OPENSSL) && defined(OPENSSL_SSL)
1902         LSTREAM_HAS_METHOD(ssl, reader);
1903         LSTREAM_HAS_METHOD(ssl, writer);
1904         LSTREAM_HAS_METHOD(ssl, closer);
1905         LSTREAM_HAS_METHOD(ssl, get_fd);
1906 #endif
1907 }
1908
1909 void reinit_vars_of_lstream(void)
1910 {
1911 #if !defined HAVE_BDWGC || !defined EF_USE_BDWGC
1912         for (int i = 0; i < countof(Vlstream_free_list); i++) {
1913                 Vlstream_free_list[i] = Qnil;
1914                 staticpro_nodump(&Vlstream_free_list[i]);
1915         }
1916 #endif  /* !BDWGC */
1917 }
1918
1919 void vars_of_lstream(void)
1920 {
1921         INIT_LRECORD_IMPLEMENTATION(lstream);
1922
1923         reinit_vars_of_lstream();
1924 }
1925
1926 /* lstream.c ends here */