1
/* estream.c - Extended stream I/O/ Library
2
Copyright (C) 2004 g10 Code GmbH
4
This file is part of Libestream.
6
Libestream is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published
8
by the Free Software Foundation; either version 2 of the License,
9
or (at your option) any later version.
11
Libestream is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
Lesser General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with Libestream; if not, write to the Free Software
18
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1
/* estream.c - Extended Stream I/O Library
2
* Copyright (C) 2004, 2005, 2006, 2007 g10 Code GmbH
4
* This file is part of Libestream.
6
* Libestream is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published
8
* by the Free Software Foundation; either version 2 of the License,
9
* or (at your option) any later version.
11
* Libestream is distributed in the hope that it will be useful, but
12
* WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with Libestream; if not, see <http://www.gnu.org/licenses/>.
21
20
#ifdef USE_ESTREAM_SUPPORT_H
22
21
# include <estream-support.h>
132
143
unsigned char buffer[BUFFER_BLOCK_SIZE];
133
144
unsigned char unread_buffer[BUFFER_UNREAD_SIZE];
134
145
estream_mutex_t lock; /* Lock. */
135
void *cookie; /* Cookie. */
136
void *opaque; /* Opaque data. */
137
unsigned int flags; /* Flags. */
146
void *cookie; /* Cookie. */
147
void *opaque; /* Opaque data. */
148
unsigned int modeflags; /* Flags for the backend. */
139
150
es_cookie_read_function_t func_read;
140
151
es_cookie_write_function_t func_write;
293
350
/* Cookie for memory objects. */
294
351
typedef struct estream_cookie_mem
296
unsigned int flags; /* Open flags. */
297
unsigned char *memory; /* Data. */
298
size_t memory_size; /* Size of MEMORY. */
353
unsigned int modeflags; /* Open flags. */
354
unsigned char *memory; /* Allocated data buffer. */
355
size_t memory_size; /* Allocated size of memory. */
356
size_t memory_limit; /* Maximum allowed allocation size or
299
358
size_t offset; /* Current offset in MEMORY. */
300
359
size_t data_len; /* Length of data in MEMORY. */
301
360
size_t block_size; /* Block size. */
302
unsigned int grow: 1; /* MEMORY is allowed to grow. */
303
unsigned int append_zero: 1; /* Append zero after data. */
304
unsigned int dont_free: 1; /* Append zero after data. */
362
unsigned int grow: 1; /* MEMORY is allowed to grow. */
307
364
func_realloc_t func_realloc;
308
365
func_free_t func_free;
309
366
} *estream_cookie_mem_t;
311
369
/* Create function for memory objects. */
313
371
es_func_mem_create (void *ES__RESTRICT *ES__RESTRICT cookie,
314
372
unsigned char *ES__RESTRICT data, size_t data_n,
316
374
size_t block_size, unsigned int grow,
317
unsigned int append_zero, unsigned int dont_free,
318
char **ptr, size_t *size,
319
375
func_realloc_t func_realloc, func_free_t func_free,
376
unsigned int modeflags,
322
379
estream_cookie_mem_t mem_cookie;
325
mem_cookie = MEM_ALLOC (sizeof (*mem_cookie));
382
mem_cookie = mem_alloc (sizeof (*mem_cookie));
330
mem_cookie->flags = flags;
387
mem_cookie->modeflags = modeflags;
331
388
mem_cookie->memory = data;
332
389
mem_cookie->memory_size = data_n;
390
mem_cookie->memory_limit = memory_limit;
333
391
mem_cookie->offset = 0;
334
392
mem_cookie->data_len = data_len;
335
393
mem_cookie->block_size = block_size;
336
mem_cookie->grow = grow ? 1 : 0;
337
mem_cookie->append_zero = append_zero ? 1 : 0;
338
mem_cookie->dont_free = dont_free ? 1 : 0;
339
mem_cookie->ptr = ptr;
340
mem_cookie->size = size;
341
mem_cookie->func_realloc = func_realloc ? func_realloc : MEM_REALLOC;
342
mem_cookie->func_free = func_free ? func_free : MEM_FREE;
343
mem_cookie->offset = 0;
394
mem_cookie->flags.grow = !!grow;
395
mem_cookie->func_realloc = func_realloc ? func_realloc : mem_realloc;
396
mem_cookie->func_free = func_free ? func_free : mem_free;
344
397
*cookie = mem_cookie;
372
426
/* Write function for memory objects. */
374
428
es_func_mem_write (void *cookie, const void *buffer, size_t size)
376
430
estream_cookie_mem_t mem_cookie = cookie;
377
func_realloc_t func_realloc = mem_cookie->func_realloc;
378
unsigned char *memory_new;
387
if (mem_cookie->flags & O_APPEND)
388
/* Append to data. */
389
mem_cookie->offset = mem_cookie->data_len;
391
if (! mem_cookie->grow)
392
if (size > mem_cookie->memory_size - mem_cookie->offset)
393
size = mem_cookie->memory_size - mem_cookie->offset;
397
while (size > (mem_cookie->memory_size - mem_cookie->offset))
399
memory_new = (*func_realloc) (mem_cookie->memory,
400
mem_cookie->memory_size
401
+ mem_cookie->block_size);
409
if (mem_cookie->memory != memory_new)
410
mem_cookie->memory = memory_new;
411
mem_cookie->memory_size += mem_cookie->block_size;
419
memcpy (mem_cookie->memory + mem_cookie->offset, buffer, size);
420
if (mem_cookie->offset + size > mem_cookie->data_len)
421
mem_cookie->data_len = mem_cookie->offset + size;
422
mem_cookie->offset += size;
430
if (mem_cookie->append_zero)
432
if (mem_cookie->data_len >= mem_cookie->memory_size)
434
newsize = BUFFER_ROUND_TO_BLOCK (mem_cookie->data_len + 1,
435
mem_cookie->block_size)
436
* mem_cookie->block_size;
438
memory_new = (*func_realloc) (mem_cookie->memory, newsize);
445
if (mem_cookie->memory != memory_new)
446
mem_cookie->memory = memory_new;
447
mem_cookie->memory_size = newsize;
450
mem_cookie->memory[mem_cookie->data_len + 1] = 0;
453
/* Return information to user if necessary. */
455
*mem_cookie->ptr = (char *) mem_cookie->memory;
456
if (mem_cookie->size)
457
*mem_cookie->size = mem_cookie->data_len;
434
return 0; /* A flush is a NOP for memory objects. */
436
if (mem_cookie->modeflags & O_APPEND)
438
/* Append to data. */
439
mem_cookie->offset = mem_cookie->data_len;
442
if (!mem_cookie->flags.grow)
444
/* We are not alloew to grow, thus limit the size to the left
445
space. FIXME: Does the grow flag an its semtics make sense
447
if (size > mem_cookie->memory_size - mem_cookie->offset)
448
size = mem_cookie->memory_size - mem_cookie->offset;
451
if (size > (mem_cookie->memory_size - mem_cookie->offset))
453
unsigned char *newbuf;
456
newsize = mem_cookie->memory_size + mem_cookie->block_size;
458
newsize = mem_cookie->offset + size;
459
if (newsize < mem_cookie->offset)
464
newsize += mem_cookie->block_size - 1;
465
if (newsize < mem_cookie->offset)
470
newsize /= mem_cookie->block_size;
471
newsize *= mem_cookie->block_size;
473
if (mem_cookie->memory_limit && newsize > mem_cookie->memory_limit)
479
newbuf = mem_cookie->func_realloc (mem_cookie->memory, newsize);
483
mem_cookie->memory = newbuf;
484
mem_cookie->memory_size = newsize;
486
assert (!(size > (mem_cookie->memory_size - mem_cookie->offset)));
489
memcpy (mem_cookie->memory + mem_cookie->offset, buffer, size);
490
if (mem_cookie->offset + size > mem_cookie->data_len)
491
mem_cookie->data_len = mem_cookie->offset + size;
492
mem_cookie->offset += size;
470
499
/* Seek function for memory objects. */
472
501
es_func_mem_seek (void *cookie, off_t *offset, int whence)
474
503
estream_cookie_mem_t mem_cookie = cookie;
497
525
if (pos_new > mem_cookie->memory_size)
499
/* Grow buffer if possible. */
501
if (mem_cookie->grow)
503
func_realloc_t func_realloc = mem_cookie->func_realloc;
507
newsize = BUFFER_ROUND_TO_BLOCK (pos_new, mem_cookie->block_size);
508
p = (*func_realloc) (mem_cookie->memory, newsize);
516
if (mem_cookie->memory != p)
517
mem_cookie->memory = p;
518
mem_cookie->memory_size = newsize;
530
if (!mem_cookie->flags.grow)
537
newsize = pos_new + mem_cookie->block_size - 1;
538
if (newsize < pos_new)
543
newsize /= mem_cookie->block_size;
544
newsize *= mem_cookie->block_size;
545
if (mem_cookie->memory_limit && newsize > mem_cookie->memory_limit)
551
newbuf = mem_cookie->func_realloc (mem_cookie->memory, newsize);
555
mem_cookie->memory = newbuf;
556
mem_cookie->memory_size = newsize;
529
559
if (pos_new > mem_cookie->data_len)
530
/* Fill spare space with zeroes. */
531
memset (mem_cookie->memory + mem_cookie->data_len,
532
0, pos_new - mem_cookie->data_len);
561
/* Fill spare space with zeroes. */
562
memset (mem_cookie->memory + mem_cookie->data_len,
563
0, pos_new - mem_cookie->data_len);
564
mem_cookie->data_len = pos_new;
534
567
mem_cookie->offset = pos_new;
535
568
*offset = pos_new;
542
574
/* Destroy function for memory objects. */
544
576
es_func_mem_destroy (void *cookie)
546
578
estream_cookie_mem_t mem_cookie = cookie;
547
func_free_t func_free = mem_cookie->func_free;
549
if (! mem_cookie->dont_free)
550
(*func_free) (mem_cookie->memory);
551
MEM_FREE (mem_cookie);
582
mem_cookie->func_free (mem_cookie->memory);
583
mem_free (mem_cookie);
556
589
static es_cookie_io_functions_t estream_functions_mem =
558
591
es_func_mem_read,
559
592
es_func_mem_write,
560
593
es_func_mem_seek,
564
599
/* Implementation of fd I/O. */
566
601
/* Cookie for fd objects. */
567
602
typedef struct estream_cookie_fd
604
int fd; /* The file descriptor we are using for actual output. */
605
int no_close; /* If set we won't close the file descriptor. */
570
606
} *estream_cookie_fd_t;
572
608
/* Create function for fd objects. */
574
es_func_fd_create (void **cookie, int fd, unsigned int flags)
610
es_func_fd_create (void **cookie, int fd, unsigned int modeflags, int no_close)
576
612
estream_cookie_fd_t fd_cookie;
579
fd_cookie = MEM_ALLOC (sizeof (*fd_cookie));
615
fd_cookie = mem_alloc (sizeof (*fd_cookie));
620
#ifdef HAVE_DOSISH_SYSTEM
621
/* Make sure it is in binary mode if requested. */
622
if ( (modeflags & O_BINARY) )
623
setmode (fd, O_BINARY);
584
625
fd_cookie->fd = fd;
626
fd_cookie->no_close = no_close;
585
627
*cookie = fd_cookie;
665
708
es_func_fd_destroy
714
/* Implementation of FILE* I/O. */
716
/* Cookie for fp objects. */
717
typedef struct estream_cookie_fp
719
FILE *fp; /* The file pointer we are using for actual output. */
720
int no_close; /* If set we won't close the file pointer. */
721
} *estream_cookie_fp_t;
723
/* Create function for fd objects. */
725
es_func_fp_create (void **cookie, FILE *fp, unsigned int modeflags, int no_close)
727
estream_cookie_fp_t fp_cookie;
730
fp_cookie = mem_alloc (sizeof *fp_cookie);
735
#ifdef HAVE_DOSISH_SYSTEM
736
/* Make sure it is in binary mode if requested. */
737
if ( (modeflags & O_BINARY) )
738
setmode (fileno (fp), O_BINARY);
741
fp_cookie->no_close = no_close;
749
/* Read function for FILE* objects. */
751
es_func_fp_read (void *cookie, void *buffer, size_t size)
754
estream_cookie_fp_t file_cookie = cookie;
757
bytes_read = fread (buffer, 1, size, file_cookie->fp);
758
if (!bytes_read && ferror (file_cookie->fp))
763
/* Write function for FILE* objects. */
765
es_func_fp_write (void *cookie, const void *buffer, size_t size)
768
estream_cookie_fp_t file_cookie = cookie;
769
size_t bytes_written;
771
bytes_written = fwrite (buffer, 1, size, file_cookie->fp);
772
if (bytes_written != size)
774
return bytes_written;
777
/* Seek function for FILE* objects. */
779
es_func_fp_seek (void *cookie, off_t *offset, int whence)
781
estream_cookie_fp_t file_cookie = cookie;
784
if ( fseek (file_cookie->fp, (long int)*offset, whence) )
786
fprintf (stderr, "\nfseek failed: errno=%d (%s)\n", errno,strerror (errno));
790
offset_new = ftell (file_cookie->fp);
791
if (offset_new == -1)
793
fprintf (stderr, "\nftell failed: errno=%d (%s)\n", errno,strerror (errno));
796
*offset = offset_new;
800
/* Destroy function for fd objects. */
802
es_func_fp_destroy (void *cookie)
804
estream_cookie_fp_t fp_cookie = cookie;
809
fflush (fp_cookie->fp);
810
err = fp_cookie->no_close? 0 : fclose (fp_cookie->fp);
811
mem_free (fp_cookie);
820
static es_cookie_io_functions_t estream_functions_fp =
668
831
/* Implementation of file I/O. */
670
833
/* Create function for file objects. */
672
835
es_func_file_create (void **cookie, int *filedes,
673
const char *path, unsigned int flags)
836
const char *path, unsigned int modeflags)
675
838
estream_cookie_fd_t file_cookie;
727
898
} mode_flags[] = { { "r",
901
O_RDONLY | O_BINARY },
732
903
O_WRONLY | O_TRUNC | O_CREAT },
734
O_WRONLY | O_TRUNC | O_CREAT },
905
O_WRONLY | O_TRUNC | O_CREAT | O_BINARY },
736
907
O_WRONLY | O_APPEND | O_CREAT },
738
O_WRONLY | O_APPEND | O_CREAT },
909
O_WRONLY | O_APPEND | O_CREAT | O_BINARY },
744
O_RDONLY | O_WRONLY },
915
O_RDONLY | O_WRONLY | O_BINARY },
746
917
O_RDWR | O_TRUNC | O_CREAT },
748
O_RDWR | O_TRUNC | O_CREAT },
919
O_RDWR | O_TRUNC | O_CREAT | O_BINARY },
750
O_RDWR | O_TRUNC | O_CREAT },
921
O_RDWR | O_TRUNC | O_CREAT | O_BINARY },
752
923
O_RDWR | O_CREAT | O_APPEND },
754
O_RDWR | O_CREAT | O_APPEND },
925
O_RDWR | O_CREAT | O_APPEND | O_BINARY },
756
O_RDWR | O_CREAT | O_APPEND } };
927
O_RDWR | O_CREAT | O_APPEND | O_BINARY }
923
1100
stream->data_offset = 0;
924
1101
stream->data_flushed = 0;
925
1102
stream->unread_data_len = 0;
1103
/* Depending on the modeflags we set whether we start in writing or
1104
reading mode. This is required in case we are working on a
1105
wronly stream which is not seeekable (like stdout). Without this
1106
pre-initialization we would do a seek at the first write call and
1107
as this will fail no utput will be delivered. */
1108
if ((modeflags & O_WRONLY) || (modeflags & O_RDWR) )
1109
stream->flags.writing = 1;
1111
stream->flags.writing = 0;
929
1114
/* Deinitialize STREAM. */
933
1118
es_cookie_close_function_t func_close;
934
1119
int err, tmp_err;
1121
if (stream->intern->print_fp)
1123
int save_errno = errno;
1124
fclose (stream->intern->print_fp);
1125
stream->intern->print_fp = NULL;
936
1129
func_close = stream->intern->func_close;
939
if (stream->flags & ES_FLAG_WRITING)
1132
if (stream->flags.writing)
940
1133
SET_UNLESS_NONZERO (err, tmp_err, es_flush (stream));
942
1135
SET_UNLESS_NONZERO (err, tmp_err, (*func_close) (stream->intern->cookie));
1398
1592
data_written = 0;
1401
if (! (stream->flags & ES_FLAG_WRITING))
1595
if (!stream->flags.writing)
1403
1597
/* Switching to writing mode -> discard input data and seek to
1404
position at which reading has stopped. */
1406
err = es_seek (stream, 0, SEEK_CUR, NULL);
1409
if (errno == ESPIPE)
1598
position at which reading has stopped. We can do this only
1599
if a seek function has been registered. */
1600
if (stream->intern->func_seek)
1602
err = es_seek (stream, 0, SEEK_CUR, NULL);
1605
if (errno == ESPIPE)
1416
1613
switch (stream->intern->strategy)
1515
1712
line_stream = NULL;
1516
1713
line_stream_cookie = NULL;
1518
err = es_func_mem_create (&line_stream_cookie, NULL, 0, 0, BUFFER_BLOCK_SIZE,
1519
1, 0, 0, NULL, 0, MEM_REALLOC, MEM_FREE, O_RDWR);
1715
err = es_func_mem_create (&line_stream_cookie, NULL, 0, 0,
1716
BUFFER_BLOCK_SIZE, 1,
1717
mem_realloc, mem_free,
1523
1723
err = es_create (&line_stream, line_stream_cookie, -1,
1524
estream_functions_mem);
1724
estream_functions_mem, O_RDWR);
1824
/* Output fucntion used for estream_format. */
1826
print_writer (void *outfncarg, const char *buf, size_t buflen)
1828
estream_t stream = outfncarg;
1833
rc = es_writen (stream, buf, buflen, &nwritten);
1834
stream->intern->print_ntotal += nwritten;
1839
/* The core of our printf function. This is called in locked state. */
1625
1841
es_print (estream_t ES__RESTRICT stream,
1626
1842
const char *ES__RESTRICT format, va_list ap)
1628
char data[BUFFER_BLOCK_SIZE];
1629
size_t bytes_written;
1638
tmp_stream = tmpfile ();
1645
err = vfprintf (tmp_stream, format, ap);
1649
err = fseek (tmp_stream, 0, SEEK_SET);
1655
bytes_read = fread (data, 1, sizeof (data), tmp_stream);
1656
if (ferror (tmp_stream))
1662
err = es_writen (stream, data, bytes_read, NULL);
1666
bytes_written += bytes_read;
1667
if (feof (tmp_stream))
1676
fclose (tmp_stream);
1678
return err ? -1 : bytes_written;
1846
stream->intern->print_ntotal = 0;
1847
rc = estream_format (print_writer, stream, format, ap);
1850
return (int)stream->intern->print_ntotal;
1823
1995
create_called = 0;
1825
err = es_convert_mode (mode, &flags);
1997
err = es_convert_mode (mode, &modeflags);
1829
err = es_func_file_create (&cookie, &fd, path, flags);
2001
err = es_func_file_create (&cookie, &fd, path, modeflags);
1833
2005
create_called = 1;
1834
err = es_create (&stream, cookie, fd, estream_functions_file);
2006
err = es_create (&stream, cookie, fd, estream_functions_file, modeflags);
1861
2033
create_called = 0;
1863
err = es_convert_mode (mode, &flags);
2035
err = es_convert_mode (mode, &modeflags);
1867
2039
err = es_func_mem_create (&cookie, data, data_n, data_len,
1868
BUFFER_BLOCK_SIZE, grow, 0, 0,
1869
NULL, 0, func_realloc, func_free, flags);
2040
BUFFER_BLOCK_SIZE, grow,
2041
func_realloc, func_free, modeflags, 0);
1873
2045
create_called = 1;
1874
err = es_create (&stream, cookie, -1, estream_functions_mem);
2046
err = es_create (&stream, cookie, -1, estream_functions_mem, modeflags);
1886
es_open_memstream (char **ptr, size_t *size)
2058
es_fopenmem (size_t memlimit, const char *ES__RESTRICT mode)
1899
err = es_func_mem_create (&cookie, NULL, 0, 0,
1900
BUFFER_BLOCK_SIZE, 1, 1, 1,
1901
ptr, size, MEM_REALLOC, MEM_FREE, flags);
1906
err = es_create (&stream, cookie, -1, estream_functions_mem);
1910
if (err && create_called)
2060
unsigned int modeflags;
2061
estream_t stream = NULL;
2062
void *cookie = NULL;
2064
/* Memory streams are always read/write. We use MODE only to get
2066
if (es_convert_mode (mode, &modeflags))
2068
modeflags |= O_RDWR;
2071
if (es_func_mem_create (&cookie, NULL, 0, 0,
2072
BUFFER_BLOCK_SIZE, 1,
2073
mem_realloc, mem_free, modeflags,
2077
if (es_create (&stream, cookie, -1, estream_functions_mem, modeflags))
1911
2078
(*estream_functions_mem.func_close) (cookie);
1918
2086
es_fopencookie (void *ES__RESTRICT cookie,
1919
2087
const char *ES__RESTRICT mode,
1920
2088
es_cookie_io_functions_t functions)
2090
unsigned int modeflags;
1923
2091
estream_t stream;
1929
err = es_convert_mode (mode, &flags);
1933
err = es_create (&stream, cookie, -1, functions);
2097
err = es_convert_mode (mode, &modeflags);
2101
err = es_create (&stream, cookie, -1, functions, modeflags);
2112
do_fdopen (int filedes, const char *mode, int no_close)
2114
unsigned int modeflags;
2124
err = es_convert_mode (mode, &modeflags);
2128
err = es_func_fd_create (&cookie, filedes, modeflags, no_close);
2133
err = es_create (&stream, cookie, filedes, estream_functions_fd, modeflags);
2137
if (err && create_called)
2138
(*estream_functions_fd.func_close) (cookie);
1944
2144
es_fdopen (int filedes, const char *mode)
2146
return do_fdopen (filedes, mode, 0);
2149
/* A variant of es_fdopen which does not close FILEDES at the end. */
2151
es_fdopen_nc (int filedes, const char *mode)
2153
return do_fdopen (filedes, mode, 1);
2158
do_fpopen (FILE *fp, const char *mode, int no_close)
2160
unsigned int modeflags;
1947
2161
int create_called;
1948
2162
estream_t stream;
1954
2168
create_called = 0;
1956
err = es_convert_mode (mode, &flags);
2170
err = es_convert_mode (mode, &modeflags);
1960
err = es_func_fd_create (&cookie, filedes, flags);
2175
err = es_func_fp_create (&cookie, fp, modeflags, no_close);
1964
2179
create_called = 1;
1965
err = es_create (&stream, cookie, filedes, estream_functions_fd);
2180
err = es_create (&stream, cookie, fileno (fp), estream_functions_fp,
1969
2185
if (err && create_called)
1970
(*estream_functions_fd.func_close) (cookie);
2186
(*estream_functions_fp.func_close) (cookie);
2192
/* Create an estream from the stdio stream FP. This mechanism is
2193
useful in case the stdio streams have special properties and may
2194
not be mixed with fd based functions. This is for example the case
2195
under Windows where the 3 standard streams are associated with the
2196
console whereas a duped and fd-opened stream of one of this stream
2197
won't be associated with the console. As this messes things up it
2198
is easier to keep on using the standard I/O stream as a backend for
2201
es_fpopen (FILE *fp, const char *mode)
2203
return do_fpopen (fp, mode, 0);
2207
/* Same as es_fpopen but does not close FP at the end. */
2209
es_fpopen_nc (FILE *fp, const char *mode)
2211
return do_fpopen (fp, mode, 1);
1977
2216
es_freopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode,
1994
2233
es_deinitialize (stream);
1996
err = es_convert_mode (mode, &flags);
2235
err = es_convert_mode (mode, &modeflags);
2000
err = es_func_file_create (&cookie, &fd, path, flags);
2239
err = es_func_file_create (&cookie, &fd, path, modeflags);
2004
2243
create_called = 1;
2005
es_initialize (stream, cookie, fd, estream_functions_file);
2244
es_initialize (stream, cookie, fd, estream_functions_file, modeflags);
2376
es_fgets (char *ES__RESTRICT s, int n, estream_t ES__RESTRICT stream)
2615
es_fgets (char *ES__RESTRICT buffer, int length, estream_t ES__RESTRICT stream)
2617
unsigned char *s = (unsigned char*)buffer;
2624
ESTREAM_LOCK (stream);
2625
while (length > 1 && (c = es_getc_unlocked (stream)) != EOF && c != '\n')
2384
ESTREAM_LOCK (stream);
2385
err = es_read_line (stream, n, &s, NULL);
2386
ESTREAM_UNLOCK (stream);
2630
ESTREAM_UNLOCK (stream);
2632
if (c == EOF && s == (unsigned char*)buffer)
2633
return NULL; /* Nothing read. */
2635
if (c != EOF && length > 1)
2714
/* Same as fgets() but if the provided buffer is too short a larger
2715
one will be allocated. This is similar to getline. A line is
2716
considered a byte stream ending in a LF.
2718
If MAX_LENGTH is not NULL, it shall point to a value with the
2719
maximum allowed allocation.
2721
Returns the length of the line. EOF is indicated by a line of
2722
length zero. A truncated line is indicated my setting the value at
2723
MAX_LENGTH to 0. If the returned value is less then 0 not enough
2724
memory was enable or another error occurred; ERRNO is then set
2727
If a line has been truncated, the file pointer is moved forward to
2728
the end of the line so that the next read starts with the next
2729
line. Note that MAX_LENGTH must be re-initialzied in this case.
2731
The caller initially needs to provide the address of a variable,
2732
initialized to NULL, at ADDR_OF_BUFFER and don't change this value
2733
anymore with the following invocations. LENGTH_OF_BUFFER should be
2734
the address of a variable, initialized to 0, which is also
2735
maintained by this function. Thus, both paramaters should be
2736
considered the state of this function.
2738
Note: The returned buffer is allocated with enough extra space to
2739
allow the caller to append a CR,LF,Nul. The buffer should be
2740
released using es_free.
2743
es_read_line (estream_t stream,
2744
char **addr_of_buffer, size_t *length_of_buffer,
2748
char *buffer = *addr_of_buffer;
2749
size_t length = *length_of_buffer;
2751
size_t maxlen = max_length? *max_length : 0;
2756
/* No buffer given - allocate a new one. */
2758
buffer = mem_alloc (length);
2759
*addr_of_buffer = buffer;
2762
*length_of_buffer = 0;
2767
*length_of_buffer = length;
2772
/* This should never happen. If it does, the function has been
2773
called with wrong arguments. */
2777
length -= 3; /* Reserve 3 bytes for CR,LF,EOL. */
2779
ESTREAM_LOCK (stream);
2781
while ((c = es_getc_unlocked (stream)) != EOF)
2783
if (nbytes == length)
2785
/* Enlarge the buffer. */
2786
if (maxlen && length > maxlen)
2788
/* We are beyond our limit: Skip the rest of the line. */
2789
while (c != '\n' && (c=es_getc_unlocked (stream)) != EOF)
2791
*p++ = '\n'; /* Always append a LF (we reserved some space). */
2794
*max_length = 0; /* Indicate truncation. */
2795
break; /* the while loop. */
2797
length += 3; /* Adjust for the reserved bytes. */
2798
length += length < 1024? 256 : 1024;
2799
*addr_of_buffer = mem_realloc (buffer, length);
2800
if (!*addr_of_buffer)
2802
int save_errno = errno;
2804
*length_of_buffer = *max_length = 0;
2805
ESTREAM_UNLOCK (stream);
2809
buffer = *addr_of_buffer;
2810
*length_of_buffer = length;
2812
p = buffer + nbytes;
2819
*p = 0; /* Make sure the line is a string. */
2820
ESTREAM_UNLOCK (stream);
2825
/* Wrapper around free() to match the memory allocation system used
2826
by estream. Should be used for all buffers returned to the caller
2466
2836
es_vfprintf (estream_t ES__RESTRICT stream, const char *ES__RESTRICT format,
2884
#ifdef HAVE_W32_SYSTEM
2886
char buffer[MAX_PATH+9+12+1];
2889
int pid = GetCurrentProcessId ();
2893
n = GetTempPath (MAX_PATH+1, buffer);
2894
if (!n || n > MAX_PATH || strlen (buffer) > MAX_PATH)
2899
p = buffer + strlen (buffer);
2900
strcpy (p, "_estream");
2902
/* We try to create the directory but don't care about an error as
2903
it may already exist and the CreateFile would throw an error
2905
CreateDirectory (buffer, NULL);
2908
for (attempts=0; attempts < 10; attempts++)
2911
value = (GetTickCount () ^ ((pid<<16) & 0xffff0000));
2912
for (i=0; i < 8; i++)
2914
*p++ = tohex (((value >> 28) & 0x0f));
2918
file = CreateFile (buffer,
2919
GENERIC_READ | GENERIC_WRITE,
2923
FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
2925
if (file != INVALID_HANDLE_VALUE)
2927
int fd = _open_osfhandle ((long)file, 0);
2935
Sleep (1); /* One ms as this is the granularity of GetTickCount. */
2939
#else /*!HAVE_W32_SYSTEM*/
3059
/* Print a BUFFER to STREAM while replacing all control characters and
3060
the characters in DELIMITERS by standard C escape sequences.
3061
Returns 0 on success or -1 on error. If BYTES_WRITTEN is not NULL
3062
the number of bytes actually written are stored at this
3065
es_write_sanitized (estream_t ES__RESTRICT stream,
3066
const void * ES__RESTRICT buffer, size_t length,
3067
const char * delimiters,
3068
size_t * ES__RESTRICT bytes_written)
3070
const unsigned char *p = buffer;
3074
ESTREAM_LOCK (stream);
3075
for (; length; length--, p++, count++)
3078
|| (*p >= 0x7f && *p < 0xa0)
3080
&& (strchr (delimiters, *p) || *p == '\\')))
3082
es_putc_unlocked ('\\', stream);
3086
es_putc_unlocked ('n', stream);
3089
else if (*p == '\r')
3091
es_putc_unlocked ('r', stream);
3094
else if (*p == '\f')
3096
es_putc_unlocked ('f', stream);
3099
else if (*p == '\v')
3101
es_putc_unlocked ('v', stream);
3104
else if (*p == '\b')
3106
es_putc_unlocked ('b', stream);
3111
es_putc_unlocked('0', stream);
3116
es_fprintf_unlocked (stream, "x%02x", *p);
3122
es_putc_unlocked (*p, stream);
3128
*bytes_written = count;
3129
ret = es_ferror_unlocked (stream)? -1 : 0;
3130
ESTREAM_UNLOCK (stream);
3136
/* Write LENGTH bytes of BUFFER to STREAM as a hex encoded string.
3137
RESERVED must be 0. Returns 0 on success or -1 on error. If
3138
BYTES_WRITTEN is not NULL the number of bytes actually written are
3139
stored at this address. */
3141
es_write_hexstring (estream_t ES__RESTRICT stream,
3142
const void *ES__RESTRICT buffer, size_t length,
3143
int reserved, size_t *ES__RESTRICT bytes_written )
3146
const unsigned char *s;
3149
#define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A'))
3154
ESTREAM_LOCK (stream);
3156
for (s = buffer; length; s++, length--)
3158
es_putc_unlocked ( tohex ((*s>>4)&15), stream);
3159
es_putc_unlocked ( tohex (*s&15), stream);
3164
*bytes_written = count;
3165
ret = es_ferror_unlocked (stream)? -1 : 0;
3167
ESTREAM_UNLOCK (stream);
3176
#ifdef GNUPG_MAJOR_VERSION
3177
/* Special estream function to print an UTF8 string in the native
3178
encoding. The interface is the same as es_write_sanitized, however
3179
only one delimiter may be supported.
3181
THIS IS NOT A STANDARD ESTREAM FUNCTION AND ONLY USED BY GNUPG!. */
3183
es_write_sanitized_utf8_buffer (estream_t stream,
3184
const void *buffer, size_t length,
3185
const char *delimiters, size_t *bytes_written)
3187
const char *p = buffer;
3190
/* We can handle plain ascii simpler, so check for it first. */
3191
for (i=0; i < length; i++ )
3193
if ( (p[i] & 0x80) )
3198
int delim = delimiters? *delimiters : 0;
3202
/*(utf8 conversion already does the control character quoting). */
3203
buf = utf8_to_native (p, length, delim);
3205
*bytes_written = strlen (buf);
3206
ret = es_fputs (buf, stream);
3211
return es_write_sanitized (stream, p, length, delimiters, bytes_written);
3213
#endif /*GNUPG_MAJOR_VERSION*/