Add new gnupg version and a patch with gpgtar.
[gpg4win.git] / patches / gnupg2-2.0.16 / 01-estream.patch
1 #! /bin/sh
2 patch -p0 -f $* < $0
3 exit $?
4
5 2010-07-19  Werner Koch  <wk@g10code.com>
6
7         Estream changes as used by the current gnupg trunk.
8
9         * estream.c (es_fname_get, es_fname_set): New.
10         (fname_set_internal): New.
11         (struct estream_internal): Add fields printable_fname and
12         printable_fname_inuse.
13         (_es_get_std_stream): Set stream name.
14         (es_fopen, es_freopen, es_deinitialize): Set fname.
15
16
17
18 --- common/estream.c    2009-12-21 15:31:38.000000000 +0100
19 +++ common/estream.c    2010-07-08 15:55:15.000000000 +0200
20 @@ -1,5 +1,5 @@
21  /* estream.c - Extended Stream I/O Library
22 - * Copyright (C) 2004, 2005, 2006, 2007, 2009 g10 Code GmbH
23 + * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 g10 Code GmbH
24   *
25   * This file is part of Libestream.
26   *
27 @@ -15,6 +15,40 @@
28   *
29   * You should have received a copy of the GNU General Public License
30   * along with Libestream; if not, see <http://www.gnu.org/licenses/>.
31 + *
32 + * ALTERNATIVELY, Libestream may be distributed under the terms of the
33 + * following license, in which case the provisions of this license are
34 + * required INSTEAD OF the GNU General Public License. If you wish to
35 + * allow use of your version of this file only under the terms of the
36 + * GNU General Public License, and not to allow others to use your
37 + * version of this file under the terms of the following license,
38 + * indicate your decision by deleting this paragraph and the license
39 + * below.
40 + *
41 + * Redistribution and use in source and binary forms, with or without
42 + * modification, are permitted provided that the following conditions
43 + * are met:
44 + * 1. Redistributions of source code must retain the above copyright
45 + *    notice, and the entire permission notice in its entirety,
46 + *    including the disclaimer of warranties.
47 + * 2. Redistributions in binary form must reproduce the above copyright
48 + *    notice, this list of conditions and the following disclaimer in the
49 + *    documentation and/or other materials provided with the distribution.
50 + * 3. The name of the author may not be used to endorse or promote
51 + *    products derived from this software without specific prior
52 + *    written permission.
53 + *
54 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
55 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
56 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
57 + * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
58 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
59 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
60 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
61 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
62 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
63 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
64 + * OF THE POSSIBILITY OF SUCH DAMAGE.
65   */
66  
67  #ifdef USE_ESTREAM_SUPPORT_H
68 @@ -27,6 +61,9 @@
69  
70  #if defined(_WIN32) && !defined(HAVE_W32_SYSTEM)
71  # define HAVE_W32_SYSTEM 1
72 +# if defined(__MINGW32CE__) && !defined (HAVE_W32CE_SYSTEM)
73 +#  define HAVE_W32CE_SYSTEM
74 +# endif
75  #endif
76  
77  #include <sys/types.h>
78 @@ -44,6 +81,9 @@
79  #ifdef HAVE_W32_SYSTEM
80  # include <windows.h>
81  #endif
82 +#ifdef HAVE_W32CE_SYSTEM
83 +# include <gpg-error.h> /* ERRNO replacement.  */
84 +#endif
85  
86  #ifdef WITHOUT_GNU_PTH /* Give the Makefile a chance to build without Pth.  */
87  # undef HAVE_PTH
88 @@ -76,6 +116,22 @@ void *memrchr (const void *block, int c,
89  #define O_BINARY 0
90  #endif
91  
92 +#ifdef HAVE_W32CE_SYSTEM
93 +# define _set_errno(a)  gpg_err_set_errno ((a))
94 +/* Setmode is missing in cegcc but available since CE 5.0.  */
95 +int _setmode (int handle, int mode);
96 +# define setmode(a,b)   _setmode ((a),(b))
97 +#else
98 +# define _set_errno(a)  do { errno = (a); } while (0)
99 +#endif
100 +
101 +#ifdef HAVE_W32_SYSTEM
102 +# define IS_INVALID_FD(a) ((void*)(a) == (void*)(-1))
103 +#else
104 +# define IS_INVALID_FD(a) ((a) == -1)
105 +#endif
106 +
107 +
108  /* Generally used types.  */
109  
110  typedef void *(*func_realloc_t) (void *mem, size_t size);
111 @@ -134,9 +190,11 @@ dummy_mutex_call_int (estream_mutex_t mu
112  #ifdef HAVE_PTH
113  # define ESTREAM_SYS_READ  es_pth_read
114  # define ESTREAM_SYS_WRITE es_pth_write
115 +# define ESTREAM_SYS_YIELD() pth_yield (NULL)
116  #else
117  # define ESTREAM_SYS_READ  read
118  # define ESTREAM_SYS_WRITE write
119 +# define ESTREAM_SYS_YIELD() do { } while (0)
120  #endif
121  
122  /* Misc definitions.  */
123 @@ -153,6 +211,7 @@ struct estream_internal
124    void *cookie;                         /* Cookie.                */
125    void *opaque;                         /* Opaque data.           */
126    unsigned int modeflags;       /* Flags for the backend. */
127 +  char *printable_fname;         /* Malloced filename for es_fname_get.  */
128    off_t offset;
129    es_cookie_read_function_t func_read;
130    es_cookie_write_function_t func_write;
131 @@ -166,7 +225,10 @@ struct estream_internal
132      unsigned int eof: 1;
133    } indicators;
134    unsigned int deallocate_buffer: 1;
135 +  unsigned int is_stdstream:1;   /* This is a standard stream.  */
136 +  unsigned int stdstream_fd:2;   /* 0, 1 or 2 for a standard stream.  */
137    unsigned int print_err: 1;     /* Error in print_fun_writer.  */
138 +  unsigned int printable_fname_inuse: 1;  /* es_fname_get has been used.  */
139    int print_errno;               /* Errno from print_fun_writer.  */
140    size_t print_ntotal;           /* Bytes written from in print_fun_writer. */
141    FILE *print_fp;                /* Stdio stream used by print_fun_writer.  */
142 @@ -196,13 +258,22 @@ static estream_mutex_t estream_list_lock
143  #define ESTREAM_LIST_LOCK   ESTREAM_MUTEX_LOCK   (estream_list_lock)
144  #define ESTREAM_LIST_UNLOCK ESTREAM_MUTEX_UNLOCK (estream_list_lock)
145  
146 +/* File descriptors registered to be used as the standard file handles. */
147 +static int custom_std_fds[3];
148 +static unsigned char custom_std_fds_valid[3];
149 +
150 +
151  #ifndef EOPNOTSUPP
152  # define EOPNOTSUPP ENOSYS
153  #endif
154  
155  
156 -\f
157 +/* Local prototypes.  */
158 +static void fname_set_internal (estream_t stream, const char *fname, int quote);
159  
160 +
161 +
162 +\f
163  /* Macros.  */
164  
165  /* Calculate array dimension.  */
166 @@ -255,9 +326,11 @@ mem_free (void *p)
167   * List manipulation.
168   */
169  
170 -/* Add STREAM to the list of registered stream objects.  */
171 +/* Add STREAM to the list of registered stream objects.  If
172 +   WITH_LOCKED_LIST is true we assumed that the list of streams is
173 +   already locked.  */
174  static int
175 -es_list_add (estream_t stream)
176 +es_list_add (estream_t stream, int with_locked_list)
177  {
178    estream_list_t list_obj;
179    int ret;
180 @@ -267,14 +340,16 @@ es_list_add (estream_t stream)
181      ret = -1;
182    else
183      {
184 -      ESTREAM_LIST_LOCK;
185 +      if (!with_locked_list)
186 +        ESTREAM_LIST_LOCK;
187        list_obj->car = stream;
188        list_obj->cdr = estream_list;
189        list_obj->prev_cdr = &estream_list;
190        if (estream_list)
191         estream_list->prev_cdr = &list_obj->cdr;
192        estream_list = list_obj;
193 -      ESTREAM_LIST_UNLOCK;
194 +      if (!with_locked_list)
195 +        ESTREAM_LIST_UNLOCK;
196        ret = 0;
197      }
198  
199 @@ -283,11 +358,12 @@ es_list_add (estream_t stream)
200  
201  /* Remove STREAM from the list of registered stream objects.  */
202  static void
203 -es_list_remove (estream_t stream)
204 +es_list_remove (estream_t stream, int with_locked_list)
205  {
206    estream_list_t list_obj;
207    
208 -  ESTREAM_LIST_LOCK;
209 +  if (!with_locked_list)
210 +    ESTREAM_LIST_LOCK;
211    for (list_obj = estream_list; list_obj; list_obj = list_obj->cdr)
212      if (list_obj->car == stream)
213        {
214 @@ -297,7 +373,8 @@ es_list_remove (estream_t stream)
215         mem_free (list_obj);
216         break;
217        }
218 -  ESTREAM_LIST_UNLOCK;
219 +  if (!with_locked_list)
220 +    ESTREAM_LIST_UNLOCK;
221  }
222  
223  /* Type of an stream-iterator-function.  */
224 @@ -360,6 +437,14 @@ es_pth_write (int fd, const void *buffer
225  
226  \f
227  
228 +static void
229 +es_deinit (void)
230 +{
231 +  /* Flush all streams. */
232 +  es_fflush (NULL);
233 +}
234 +
235 +
236  /*
237   * Initialization.
238   */
239 @@ -367,17 +452,20 @@ es_pth_write (int fd, const void *buffer
240  static int
241  es_init_do (void)
242  {
243 -#ifdef HAVE_PTH
244    static int initialized;
245  
246    if (!initialized)
247      {
248 +#ifdef HAVE_PTH
249        if (!pth_init () && errno != EPERM )
250          return -1;
251        if (pth_mutex_init (&estream_list_lock))
252          initialized = 1;
253 -    }
254 +#else
255 +      initialized = 1;
256  #endif
257 +      atexit (es_deinit);  
258 +    }
259    return 0;
260  }
261  
262 @@ -427,7 +515,7 @@ es_func_mem_create (void *ES__RESTRICT *
263  
264    if (!data && (data_n || data_len))
265      {
266 -      errno = EINVAL;
267 +      _set_errno (EINVAL);
268        return -1;
269      }
270  
271 @@ -511,7 +599,7 @@ es_func_mem_write (void *cookie, const v
272          newsize = mem_cookie->memory_size + (nleft - size);
273        if (newsize < mem_cookie->offset)
274          {
275 -          errno = EINVAL;
276 +          _set_errno (EINVAL);
277            return -1;
278          }
279  
280 @@ -522,7 +610,7 @@ es_func_mem_write (void *cookie, const v
281            newsize += mem_cookie->block_size - 1;
282            if (newsize < mem_cookie->offset)
283              {
284 -              errno = EINVAL;
285 +              _set_errno (EINVAL);
286                return -1;
287              }
288            newsize /= mem_cookie->block_size;
289 @@ -532,7 +620,7 @@ es_func_mem_write (void *cookie, const v
290        /* Check for a total limit.  */
291        if (mem_cookie->memory_limit && newsize > mem_cookie->memory_limit)
292          {
293 -          errno = ENOSPC;
294 +          _set_errno (ENOSPC);
295            return -1;
296          }
297        
298 @@ -581,7 +669,7 @@ es_func_mem_seek (void *cookie, off_t *o
299        break;
300  
301      default:
302 -      errno = EINVAL;
303 +      _set_errno (EINVAL);
304        return -1;
305      }
306  
307 @@ -592,14 +680,14 @@ es_func_mem_seek (void *cookie, off_t *o
308  
309        if (!mem_cookie->flags.grow)
310         {
311 -         errno = ENOSPC;
312 +         _set_errno (ENOSPC);
313           return -1;
314          }
315  
316        newsize = pos_new + mem_cookie->block_size - 1;
317        if (newsize < pos_new)
318          {
319 -          errno = EINVAL;
320 +          _set_errno (EINVAL);
321            return -1;
322          }
323        newsize /= mem_cookie->block_size;
324 @@ -607,7 +695,7 @@ es_func_mem_seek (void *cookie, off_t *o
325  
326        if (mem_cookie->memory_limit && newsize > mem_cookie->memory_limit)
327          {
328 -          errno = ENOSPC;
329 +          _set_errno (ENOSPC);
330            return -1;
331          }
332        
333 @@ -703,10 +791,18 @@ es_func_fd_read (void *cookie, void *buf
334  {
335    estream_cookie_fd_t file_cookie = cookie;
336    ssize_t bytes_read;
337 -
338 -  do 
339 -    bytes_read = ESTREAM_SYS_READ (file_cookie->fd, buffer, size);
340 -  while (bytes_read == -1 && errno == EINTR);
341 +  
342 +  if (IS_INVALID_FD (file_cookie->fd))
343 +    {
344 +      ESTREAM_SYS_YIELD ();
345 +      bytes_read = 0;
346 +    }
347 +  else
348 +    {
349 +      do 
350 +        bytes_read = ESTREAM_SYS_READ (file_cookie->fd, buffer, size);
351 +      while (bytes_read == -1 && errno == EINTR);
352 +    }
353  
354    return bytes_read;
355  }
356 @@ -714,14 +810,21 @@ es_func_fd_read (void *cookie, void *buf
357  /* Write function for fd objects.  */
358  static ssize_t
359  es_func_fd_write (void *cookie, const void *buffer, size_t size)
360 -                          
361  {
362    estream_cookie_fd_t file_cookie = cookie;
363    ssize_t bytes_written;
364  
365 -  do
366 -    bytes_written = ESTREAM_SYS_WRITE (file_cookie->fd, buffer, size);
367 -  while (bytes_written == -1 && errno == EINTR);
368 +  if (IS_INVALID_FD (file_cookie->fd))
369 +    {
370 +      ESTREAM_SYS_YIELD ();
371 +      bytes_written = size; /* Yeah:  Success writing to the bit bucket.  */
372 +    }
373 +  else
374 +    {
375 +      do
376 +        bytes_written = ESTREAM_SYS_WRITE (file_cookie->fd, buffer, size);
377 +      while (bytes_written == -1 && errno == EINTR);
378 +    }
379  
380    return bytes_written;
381  }
382 @@ -734,13 +837,21 @@ es_func_fd_seek (void *cookie, off_t *of
383    off_t offset_new;
384    int err;
385  
386 -  offset_new = lseek (file_cookie->fd, *offset, whence);
387 -  if (offset_new == -1)
388 -    err = -1;
389 +  if (IS_INVALID_FD (file_cookie->fd))
390 +    {
391 +      _set_errno (ESPIPE);
392 +      err = -1;
393 +    }
394    else
395      {
396 -      *offset = offset_new;
397 -      err = 0;
398 +      offset_new = lseek (file_cookie->fd, *offset, whence);
399 +      if (offset_new == -1)
400 +        err = -1;
401 +      else
402 +        {
403 +          *offset = offset_new;
404 +          err = 0;
405 +        }
406      }
407  
408    return err;
409 @@ -755,7 +866,10 @@ es_func_fd_destroy (void *cookie)
410  
411    if (fd_cookie)
412      {
413 -      err = fd_cookie->no_close? 0 : close (fd_cookie->fd);
414 +      if (IS_INVALID_FD (fd_cookie->fd))
415 +        err = 0;
416 +      else
417 +        err = fd_cookie->no_close? 0 : close (fd_cookie->fd);
418        mem_free (fd_cookie);
419      }
420    else
421 @@ -822,7 +936,10 @@ es_func_fp_read (void *cookie, void *buf
422    estream_cookie_fp_t file_cookie = cookie;
423    ssize_t bytes_read;
424  
425 -  bytes_read = fread (buffer, 1, size, file_cookie->fp);
426 +  if (file_cookie->fp)
427 +    bytes_read = fread (buffer, 1, size, file_cookie->fp);
428 +  else
429 +    bytes_read = 0;
430    if (!bytes_read && ferror (file_cookie->fp))
431      return -1;
432    return bytes_read;
433 @@ -836,7 +953,11 @@ es_func_fp_write (void *cookie, const vo
434    estream_cookie_fp_t file_cookie = cookie;
435    size_t bytes_written;
436  
437 -  bytes_written = fwrite (buffer, 1, size, file_cookie->fp);
438 +
439 +  if (file_cookie->fp)
440 +    bytes_written = fwrite (buffer, 1, size, file_cookie->fp);
441 +  else
442 +    bytes_written = size; /* Successfully written to the bit bucket.  */
443    if (bytes_written != size)
444      return -1;
445    return bytes_written;
446 @@ -849,23 +970,31 @@ es_func_fp_seek (void *cookie, off_t *of
447    estream_cookie_fp_t file_cookie = cookie;
448    long int offset_new;
449  
450 +  if (!file_cookie->fp)
451 +    {
452 +      _set_errno (ESPIPE);
453 +      return -1; 
454 +    }
455 +
456    if ( fseek (file_cookie->fp, (long int)*offset, whence) )
457      {
458 -      fprintf (stderr, "\nfseek failed: errno=%d (%s)\n", errno,strerror (errno));
459 -    return -1;
460 +      /* fprintf (stderr, "\nfseek failed: errno=%d (%s)\n", */
461 +      /*          errno,strerror (errno)); */
462 +      return -1;
463      }
464  
465    offset_new = ftell (file_cookie->fp);
466    if (offset_new == -1)
467      {
468 -      fprintf (stderr, "\nftell failed: errno=%d (%s)\n", errno,strerror (errno));
469 -    return -1;
470 +      /* fprintf (stderr, "\nftell failed: errno=%d (%s)\n",  */
471 +      /*          errno,strerror (errno)); */
472 +      return -1;
473      }
474    *offset = offset_new;
475    return 0;
476  }
477  
478 -/* Destroy function for fd objects.  */
479 +/* Destroy function for FILE* objects.  */
480  static int
481  es_func_fp_destroy (void *cookie)
482  {
483 @@ -874,8 +1003,13 @@ es_func_fp_destroy (void *cookie)
484  
485    if (fp_cookie)
486      {
487 -      fflush (fp_cookie->fp);
488 -      err = fp_cookie->no_close? 0 : fclose (fp_cookie->fp);
489 +      if (fp_cookie->fp)
490 +        {
491 +          fflush (fp_cookie->fp);
492 +          err = fp_cookie->no_close? 0 : fclose (fp_cookie->fp);
493 +        }
494 +      else
495 +        err = 0;
496        mem_free (fp_cookie);
497      }
498    else
499 @@ -942,14 +1076,6 @@ es_func_file_create (void **cookie, int 
500    return err;
501  }
502  
503 -static es_cookie_io_functions_t estream_functions_file =
504 -  {
505 -    es_func_fd_read,
506 -    es_func_fd_write,
507 -    es_func_fd_seek,
508 -    es_func_fd_destroy
509 -  };
510 -
511  \f
512  static int
513  es_convert_mode (const char *mode, unsigned int *modeflags)
514 @@ -971,7 +1097,7 @@ es_convert_mode (const char *mode, unsig
515        oflags = O_APPEND | O_CREAT;
516        break;
517      default:
518 -      errno = EINVAL;
519 +      _set_errno (EINVAL);
520        return -1;
521      }
522    for (mode++; *mode; mode++)
523 @@ -1010,7 +1136,7 @@ es_fill (estream_t stream)
524  
525    if (!stream->intern->func_read)
526      {
527 -      errno = EOPNOTSUPP;
528 +      _set_errno (EOPNOTSUPP);
529        err = -1;
530      }
531    else
532 @@ -1144,7 +1270,11 @@ es_initialize (estream_t stream,
533    stream->intern->print_fp = NULL;
534    stream->intern->indicators.err = 0;
535    stream->intern->indicators.eof = 0;
536 +  stream->intern->is_stdstream = 0;
537 +  stream->intern->stdstream_fd = 0;
538    stream->intern->deallocate_buffer = 0;
539 +  stream->intern->printable_fname = NULL;
540 +  stream->intern->printable_fname_inuse = 0;
541  
542    stream->data_len = 0;
543    stream->data_offset = 0;
544 @@ -1152,7 +1282,7 @@ es_initialize (estream_t stream,
545    stream->unread_data_len = 0;
546    /* Depending on the modeflags we set whether we start in writing or
547       reading mode.  This is required in case we are working on a
548 -     wronly stream which is not seeekable (like stdout).  Without this
549 +     stream which is not seeekable (like stdout).  Without this
550       pre-initialization we would do a seek at the first write call and
551       as this will fail no utput will be delivered. */
552    if ((modeflags & O_WRONLY) || (modeflags & O_RDWR) )
553 @@ -1173,7 +1303,7 @@ es_deinitialize (estream_t stream)
554        int save_errno = errno;
555        fclose (stream->intern->print_fp);
556        stream->intern->print_fp = NULL;
557 -      errno = save_errno;
558 +      _set_errno (save_errno);
559      }
560  
561    func_close = stream->intern->func_close;
562 @@ -1184,14 +1314,18 @@ es_deinitialize (estream_t stream)
563    if (func_close)
564      SET_UNLESS_NONZERO (err, tmp_err, (*func_close) (stream->intern->cookie));
565  
566 -  
567 +  mem_free (stream->intern->printable_fname);
568 +  stream->intern->printable_fname = NULL;
569 +  stream->intern->printable_fname_inuse = 0;
570 +
571    return err;
572  }
573  
574  /* Create a new stream object, initialize it.  */
575  static int
576  es_create (estream_t *stream, void *cookie, int fd,
577 -          es_cookie_io_functions_t functions, unsigned int modeflags)
578 +          es_cookie_io_functions_t functions, unsigned int modeflags,
579 +           int with_locked_list)
580  {
581    estream_internal_t stream_internal_new;
582    estream_t stream_new;
583 @@ -1223,7 +1357,7 @@ es_create (estream_t *stream, void *cook
584    ESTREAM_MUTEX_INITIALIZE (stream_new->intern->lock);
585    es_initialize (stream_new, cookie, fd, functions, modeflags);
586  
587 -  err = es_list_add (stream_new);
588 +  err = es_list_add (stream_new, with_locked_list);
589    if (err)
590      goto out;
591  
592 @@ -1245,13 +1379,13 @@ es_create (estream_t *stream, void *cook
593  
594  /* Deinitialize a stream object and destroy it.  */
595  static int
596 -es_destroy (estream_t stream)
597 +es_destroy (estream_t stream, int with_locked_list)
598  {
599    int err = 0;
600  
601    if (stream)
602      {
603 -      es_list_remove (stream);
604 +      es_list_remove (stream, with_locked_list);
605        err = es_deinitialize (stream);
606        mem_free (stream->intern);
607        mem_free (stream);
608 @@ -1460,7 +1594,7 @@ es_seek (estream_t ES__RESTRICT stream, 
609  
610    if (! func_seek)
611      {
612 -      errno = EOPNOTSUPP;
613 +      _set_errno (EOPNOTSUPP);
614        err = -1;
615        goto out;
616      }
617 @@ -1730,7 +1864,7 @@ es_skip (estream_t stream, size_t size)
618  
619    if (stream->data_offset + size > stream->data_len)
620      {
621 -      errno = EINVAL;
622 +      _set_errno (EINVAL);
623        err = -1;
624      }
625    else
626 @@ -1771,7 +1905,7 @@ doreadline (estream_t ES__RESTRICT strea
627      goto out;
628  
629    err = es_create (&line_stream, line_stream_cookie, -1,
630 -                  estream_functions_mem, O_RDWR);
631 +                  estream_functions_mem, O_RDWR, 0);
632    if (err)
633      goto out;
634  
635 @@ -1856,7 +1990,7 @@ doreadline (estream_t ES__RESTRICT strea
636   out:
637  
638    if (line_stream)
639 -    es_destroy (line_stream);
640 +    es_destroy (line_stream, 0);
641    else if (line_stream_cookie)
642      es_func_mem_destroy (line_stream_cookie);
643  
644 @@ -1961,6 +2095,8 @@ es_set_buffering (estream_t ES__RESTRICT
645         buffer_new = buffer;
646        else
647         {
648 +          if (!size)
649 +            size = BUFSIZ;
650           buffer_new = mem_alloc (size);
651           if (! buffer_new)
652             {
653 @@ -2053,14 +2189,17 @@ es_fopen (const char *ES__RESTRICT path,
654      goto out;
655  
656    create_called = 1;
657 -  err = es_create (&stream, cookie, fd, estream_functions_file, modeflags);
658 +  err = es_create (&stream, cookie, fd, estream_functions_fd, modeflags, 0);
659    if (err)
660      goto out;
661  
662 +  if (stream && path)
663 +    fname_set_internal (stream, path, 1);
664 +
665   out:
666    
667    if (err && create_called)
668 -    (*estream_functions_file.func_close) (cookie);
669 +    (*estream_functions_fd.func_close) (cookie);
670  
671    return stream;
672  }
673 @@ -2093,7 +2232,7 @@ es_mopen (unsigned char *ES__RESTRICT da
674      goto out;
675    
676    create_called = 1;
677 -  err = es_create (&stream, cookie, -1, estream_functions_mem, modeflags);
678 +  err = es_create (&stream, cookie, -1, estream_functions_mem, modeflags, 0);
679  
680   out:
681  
682 @@ -2124,7 +2263,7 @@ es_fopenmem (size_t memlimit, const char
683                            memlimit))
684      return NULL;
685    
686 -  if (es_create (&stream, cookie, -1, estream_functions_mem, modeflags))
687 +  if (es_create (&stream, cookie, -1, estream_functions_mem, modeflags, 0))
688      (*estream_functions_mem.func_close) (cookie);
689  
690    return stream;
691 @@ -2148,7 +2287,7 @@ es_fopencookie (void *ES__RESTRICT cooki
692    if (err)
693      goto out;
694  
695 -  err = es_create (&stream, cookie, -1, functions, modeflags);
696 +  err = es_create (&stream, cookie, -1, functions, modeflags, 0);
697    if (err)
698      goto out;
699  
700 @@ -2159,7 +2298,7 @@ es_fopencookie (void *ES__RESTRICT cooki
701  
702  
703  estream_t
704 -do_fdopen (int filedes, const char *mode, int no_close)
705 +do_fdopen (int filedes, const char *mode, int no_close, int with_locked_list)
706  {
707    unsigned int modeflags;
708    int create_called;
709 @@ -2180,7 +2319,8 @@ do_fdopen (int filedes, const char *mode
710      goto out;
711  
712    create_called = 1;
713 -  err = es_create (&stream, cookie, filedes, estream_functions_fd, modeflags);
714 +  err = es_create (&stream, cookie, filedes, estream_functions_fd,
715 +                   modeflags, with_locked_list);
716  
717   out:
718  
719 @@ -2193,19 +2333,19 @@ do_fdopen (int filedes, const char *mode
720  estream_t
721  es_fdopen (int filedes, const char *mode)
722  {
723 -  return do_fdopen (filedes, mode, 0);
724 +  return do_fdopen (filedes, mode, 0, 0);
725  }
726  
727  /* A variant of es_fdopen which does not close FILEDES at the end.  */
728  estream_t
729  es_fdopen_nc (int filedes, const char *mode)
730  {
731 -  return do_fdopen (filedes, mode, 1);
732 +  return do_fdopen (filedes, mode, 1, 0);
733  }
734  
735  
736  estream_t
737 -do_fpopen (FILE *fp, const char *mode, int no_close)
738 +do_fpopen (FILE *fp, const char *mode, int no_close, int with_locked_list)
739  {
740    unsigned int modeflags;
741    int create_called;
742 @@ -2221,14 +2361,15 @@ do_fpopen (FILE *fp, const char *mode, i
743    if (err)
744      goto out;
745  
746 -  fflush (fp);
747 +  if (fp)
748 +    fflush (fp);
749    err = es_func_fp_create (&cookie, fp, modeflags, no_close);
750    if (err)
751      goto out;
752 -
753 +  
754    create_called = 1;
755 -  err = es_create (&stream, cookie, fileno (fp), estream_functions_fp,
756 -                   modeflags);
757 +  err = es_create (&stream, cookie, fp? fileno (fp):-1, estream_functions_fp,
758 +                   modeflags, with_locked_list);
759  
760   out:
761  
762 @@ -2250,7 +2391,7 @@ do_fpopen (FILE *fp, const char *mode, i
763  estream_t
764  es_fpopen (FILE *fp, const char *mode)
765  {
766 -  return do_fpopen (fp, mode, 0);
767 +  return do_fpopen (fp, mode, 0, 0);
768  }
769  
770  
771 @@ -2258,7 +2399,86 @@ es_fpopen (FILE *fp, const char *mode)
772  estream_t
773  es_fpopen_nc (FILE *fp, const char *mode)
774  {
775 -  return do_fpopen (fp, mode, 1);
776 +  return do_fpopen (fp, mode, 1, 0);
777 +}
778 +
779 +
780 +/* Set custom standard descriptors to be used for stdin, stdout and
781 +   stderr.  This function needs to be called before any of the
782 +   standard streams are accessed.  */
783 +void
784 +_es_set_std_fd (int no, int fd)
785 +{
786 +  ESTREAM_LIST_LOCK;
787 +  if (no >= 0 && no < 3 && !custom_std_fds_valid[no])
788 +    {
789 +      custom_std_fds[no] = fd;
790 +      custom_std_fds_valid[no] = 1;
791 +    }
792 +  ESTREAM_LIST_UNLOCK;
793 +}
794 +
795 +
796 +/* Return the stream used for stdin, stdout or stderr.  */
797 +estream_t
798 +_es_get_std_stream (int fd)
799 +{
800 +  estream_list_t list_obj;
801 +  estream_t stream = NULL;
802 +
803 +  fd %= 3; /* We only allow 0, 1 or 2 but we don't want to return an error. */
804 +  ESTREAM_LIST_LOCK;
805 +  for (list_obj = estream_list; list_obj; list_obj = list_obj->cdr)
806 +    if (list_obj->car->intern->is_stdstream
807 +        && list_obj->car->intern->stdstream_fd == fd)
808 +      {
809 +       stream = list_obj->car;
810 +       break;
811 +      }
812 +  if (!stream)
813 +    {
814 +      /* Standard stream not yet created.  We first try to create them
815 +         from registered file descriptors.  */
816 +      if (!fd && custom_std_fds_valid[0])
817 +        stream = do_fdopen (custom_std_fds[0], "r", 1, 1);
818 +      else if (fd == 1 && custom_std_fds_valid[1])
819 +        stream = do_fdopen (custom_std_fds[1], "a", 1, 1);
820 +      else if (custom_std_fds_valid[2])
821 +        stream = do_fdopen (custom_std_fds[2], "a", 1, 1);
822 +      
823 +      if (!stream)
824 +        {
825 +          /* Second try is to use the standard C streams.  */
826 +          if (!fd)
827 +            stream = do_fpopen (stdin, "r", 1, 1);
828 +          else if (fd == 1)
829 +            stream = do_fpopen (stdout, "a", 1, 1);
830 +          else
831 +            stream = do_fpopen (stderr, "a", 1, 1);
832 +        }
833 +      
834 +      if (!stream) 
835 +        {
836 +          /* Last try: Create a bit bucket.  */
837 +          stream = do_fpopen (NULL, fd? "a":"r", 0, 1);
838 +          if (!stream)
839 +            {
840 +              fprintf (stderr, "fatal: error creating a dummy estream"
841 +                       " for %d: %s\n", fd, strerror (errno));
842 +              abort();
843 +            }
844 +        }
845 +
846 +      stream->intern->is_stdstream = 1;
847 +      stream->intern->stdstream_fd = fd;
848 +      if (fd == 2)
849 +        es_set_buffering (stream, NULL, _IOLBF, 0);
850 +      fname_set_internal (stream, 
851 +                          fd == 0? "[stdin]" :
852 +                          fd == 1? "[stdout]" : "[stderr]", 0);
853 +    }
854 +  ESTREAM_LIST_UNLOCK;
855 +  return stream;
856  }
857  
858  
859 @@ -2291,7 +2511,7 @@ es_freopen (const char *ES__RESTRICT pat
860         goto leave;
861  
862        create_called = 1;
863 -      es_initialize (stream, cookie, fd, estream_functions_file, modeflags);
864 +      es_initialize (stream, cookie, fd, estream_functions_fd, modeflags);
865  
866      leave:
867  
868 @@ -2300,18 +2520,22 @@ es_freopen (const char *ES__RESTRICT pat
869           if (create_called)
870             es_func_fd_destroy (cookie);
871        
872 -         es_destroy (stream);
873 +         es_destroy (stream, 0);
874           stream = NULL;
875         }
876        else
877 -       ESTREAM_UNLOCK (stream);
878 +        {
879 +          if (stream && path)
880 +            fname_set_internal (stream, path, 1);
881 +          ESTREAM_UNLOCK (stream);
882 +        }
883      }
884    else
885      {
886        /* FIXME?  We don't support re-opening at the moment.  */
887 -      errno = EINVAL;
888 +      _set_errno (EINVAL);
889        es_deinitialize (stream);
890 -      es_destroy (stream);
891 +      es_destroy (stream, 0);
892        stream = NULL;
893      }
894  
895 @@ -2324,7 +2548,7 @@ es_fclose (estream_t stream)
896  {
897    int err;
898  
899 -  err = es_destroy (stream);
900 +  err = es_destroy (stream, 0);
901  
902    return err;
903  }
904 @@ -2426,6 +2650,23 @@ es_clearerr (estream_t stream)
905  }
906  
907  
908 +static int
909 +do_fflush (estream_t stream)
910 +{
911 +  int err;
912 +  
913 +  if (stream->flags.writing)
914 +    err = es_flush (stream);
915 +  else
916 +    {
917 +      es_empty (stream);
918 +      err = 0;
919 +    }
920 +
921 +  return err;
922 +}
923 +
924 +
925  int
926  es_fflush (estream_t stream)
927  {
928 @@ -2434,17 +2675,11 @@ es_fflush (estream_t stream)
929    if (stream)
930      {
931        ESTREAM_LOCK (stream);
932 -      if (stream->flags.writing)
933 -       err = es_flush (stream);
934 -      else
935 -       {
936 -         es_empty (stream);
937 -         err = 0;
938 -       }
939 +      err = do_fflush (stream);
940        ESTREAM_UNLOCK (stream);
941      }
942    else
943 -    err = es_list_iterate (es_fflush);
944 +    err = es_list_iterate (do_fflush);
945  
946    return err ? EOF : 0;
947  }
948 @@ -2691,6 +2926,17 @@ es_fgets (char *ES__RESTRICT buffer, int
949  
950  
951  int
952 +es_fputs_unlocked (const char *ES__RESTRICT s, estream_t ES__RESTRICT stream)
953 +{
954 +  size_t length;
955 +  int err;
956 +
957 +  length = strlen (s);
958 +  err = es_writen (stream, s, length, NULL);
959 +  return err ? EOF : 0;
960 +}
961 +
962 +int
963  es_fputs (const char *ES__RESTRICT s, estream_t ES__RESTRICT stream)
964  {
965    size_t length;
966 @@ -2821,7 +3067,7 @@ es_read_line (estream_t stream, 
967      {
968        /* This should never happen. If it does, the function has been
969           called with wrong arguments. */
970 -      errno = EINVAL;
971 +      _set_errno (EINVAL);
972        return -1;
973      }
974    length -= 3; /* Reserve 3 bytes for CR,LF,EOL. */
975 @@ -2855,7 +3101,7 @@ es_read_line (estream_t stream, 
976                if (max_length)
977                  *max_length = 0;
978                ESTREAM_UNLOCK (stream);
979 -              errno = save_errno;
980 +              _set_errno (save_errno);
981                return -1;
982              }
983            buffer = *addr_of_buffer;
984 @@ -2885,6 +3131,15 @@ es_free (void *a)
985  
986  
987  int
988 +es_vfprintf_unlocked (estream_t ES__RESTRICT stream,
989 +                      const char *ES__RESTRICT format,
990 +                      va_list ap)
991 +{
992 +  return es_print (stream, format, ap);
993 +}
994 +
995 +
996 +int
997  es_vfprintf (estream_t ES__RESTRICT stream, const char *ES__RESTRICT format,
998              va_list ap)
999  {
1000 @@ -2898,9 +3153,9 @@ es_vfprintf (estream_t ES__RESTRICT stre
1001  }
1002  
1003  
1004 -static int
1005 +int
1006  es_fprintf_unlocked (estream_t ES__RESTRICT stream,
1007 -           const char *ES__RESTRICT format, ...)
1008 +                     const char *ES__RESTRICT format, ...)
1009  {
1010    int ret;
1011    
1012 @@ -2973,21 +3228,32 @@ tmpfd (void)
1013  {
1014  #ifdef HAVE_W32_SYSTEM
1015    int attempts, n;
1016 +#ifdef HAVE_W32CE_SYSTEM
1017 +  wchar_t buffer[MAX_PATH+9+12+1];
1018 +# define mystrlen(a) wcslen (a)
1019 +  wchar_t *name, *p;
1020 +#else
1021    char buffer[MAX_PATH+9+12+1];
1022 +# define mystrlen(a) strlen (a)
1023    char *name, *p;
1024 +#endif
1025    HANDLE file;
1026    int pid = GetCurrentProcessId ();
1027    unsigned int value;
1028    int i;
1029    
1030    n = GetTempPath (MAX_PATH+1, buffer);
1031 -  if (!n || n > MAX_PATH || strlen (buffer) > MAX_PATH)
1032 +  if (!n || n > MAX_PATH || mystrlen (buffer) > MAX_PATH)
1033      {
1034 -      errno = ENOENT;
1035 +      _set_errno (ENOENT);
1036        return -1;
1037      }
1038 -  p = buffer + strlen (buffer);
1039 +  p = buffer + mystrlen (buffer);
1040 +#ifdef HAVE_W32CE_SYSTEM
1041 +  wcscpy (p, L"_estream");
1042 +#else
1043    strcpy (p, "_estream");
1044 +#endif
1045    p += 8;
1046    /* We try to create the directory but don't care about an error as
1047       it may already exist and the CreateFile would throw an error
1048 @@ -3004,7 +3270,11 @@ tmpfd (void)
1049            *p++ = tohex (((value >> 28) & 0x0f));
1050            value <<= 4;
1051          }
1052 +#ifdef HAVE_W32CE_SYSTEM
1053 +      wcscpy (p, L".tmp");
1054 +#else
1055        strcpy (p, ".tmp");
1056 +#endif
1057        file = CreateFile (buffer,
1058                           GENERIC_READ | GENERIC_WRITE,
1059                           0,
1060 @@ -3014,17 +3284,21 @@ tmpfd (void)
1061                           NULL);
1062        if (file != INVALID_HANDLE_VALUE)
1063          {
1064 +#ifdef HAVE_W32CE_SYSTEM
1065 +          int fd = (int)file;
1066 +#else
1067            int fd = _open_osfhandle ((long)file, 0);
1068            if (fd == -1)
1069              {
1070                CloseHandle (file);
1071                return -1;
1072              }
1073 +#endif
1074            return fd;
1075          }
1076        Sleep (1); /* One ms as this is the granularity of GetTickCount.  */
1077      }
1078 -  errno = ENOENT;
1079 +  _set_errno (ENOENT);
1080    return -1;
1081  #else /*!HAVE_W32_SYSTEM*/
1082    FILE *fp;
1083 @@ -3077,7 +3351,7 @@ es_tmpfile (void)
1084      goto out;
1085  
1086    create_called = 1;
1087 -  err = es_create (&stream, cookie, fd, estream_functions_fd, modeflags);
1088 +  err = es_create (&stream, cookie, fd, estream_functions_fd, modeflags, 0);
1089  
1090   out:
1091  
1092 @@ -3100,8 +3374,8 @@ es_setvbuf (estream_t ES__RESTRICT strea
1093  {
1094    int err;
1095    
1096 -  if (((type == _IOFBF) || (type == _IOLBF) || (type == _IONBF))
1097 -      && (! ((! size) && (type != _IONBF))))
1098 +  if ((type == _IOFBF || type == _IOLBF || type == _IONBF)
1099 +      && (!buf || size || type == _IONBF))
1100      {
1101        ESTREAM_LOCK (stream);
1102        err = es_set_buffering (stream, buf, type, size);
1103 @@ -3109,7 +3383,7 @@ es_setvbuf (estream_t ES__RESTRICT strea
1104      }
1105    else
1106      {
1107 -      errno = EINVAL;
1108 +      _set_errno (EINVAL);
1109        err = -1;
1110      }
1111  
1112 @@ -3146,6 +3420,68 @@ es_opaque_get (estream_t stream)
1113    return opaque;
1114  }
1115  
1116 +
1117 +static void
1118 +fname_set_internal (estream_t stream, const char *fname, int quote)
1119 +{
1120 +  if (stream->intern->printable_fname
1121 +      && !stream->intern->printable_fname_inuse)
1122 +    {
1123 +      mem_free (stream->intern->printable_fname);
1124 +      stream->intern->printable_fname = NULL;
1125 +    }
1126 +  if (stream->intern->printable_fname)
1127 +    return; /* Can't change because it is in use.  */
1128 +
1129 +  if (*fname != '[')
1130 +    quote = 0;
1131 +  else
1132 +    quote = !!quote;
1133 +
1134 +  stream->intern->printable_fname = mem_alloc (strlen (fname) + quote + 1);
1135 +  if (fname)
1136 +    {
1137 +      if (quote)
1138 +        stream->intern->printable_fname[0] = '\\';
1139 +      strcpy (stream->intern->printable_fname+quote, fname);
1140 +    }
1141 +}
1142 +
1143 +
1144 +/* Set the filename attribute of STREAM.  There is no error return.
1145 +   as long as STREAM is valid.  This function is called internally by
1146 +   functions which open a filename.  */
1147 +void
1148 +es_fname_set (estream_t stream, const char *fname)
1149 +{
1150 +  if (fname)
1151 +    {
1152 +      ESTREAM_LOCK (stream);
1153 +      fname_set_internal (stream, fname, 1);
1154 +      ESTREAM_UNLOCK (stream);
1155 +    }
1156 +}
1157 +
1158 +
1159 +/* Return the filename attribute of STREAM.  In case no filename has
1160 +   been set, "[?]" will be returned.  The returned file name is valid
1161 +   as long as STREAM is valid.  */
1162 +const char *
1163 +es_fname_get (estream_t stream)
1164 +{
1165 +  const char *fname;
1166 +
1167 +  ESTREAM_LOCK (stream);
1168 +  fname = stream->intern->printable_fname;
1169 +  if (fname)
1170 +    stream->intern->printable_fname_inuse = 1;
1171 +  ESTREAM_UNLOCK (stream);
1172 +  if (!fname)
1173 +    fname = "[?]";
1174 +  return fname;
1175 +}
1176 +
1177 +
1178  /* Print a BUFFER to STREAM while replacing all control characters and
1179     the characters in DELIMITERS by standard C escape sequences.
1180     Returns 0 on success or -1 on error.  If BYTES_WRITTEN is not NULL
1181 --- common/estream.h    2009-09-21 18:53:51.000000000 +0200
1182 +++ common/estream.h    2010-06-07 11:59:23.000000000 +0200
1183 @@ -1,5 +1,5 @@
1184  /* estream.h - Extended stream I/O Library
1185 - * Copyright (C) 2004, 2005, 2006, 2007 g10 Code GmbH
1186 + * Copyright (C) 2004, 2005, 2006, 2007, 2010 g10 Code GmbH
1187   *
1188   * This file is part of Libestream.
1189   *
1190 @@ -15,6 +15,40 @@
1191   *
1192   * You should have received a copy of the GNU General Public License
1193   * along with Libestream; if not, see <http://www.gnu.org/licenses/>.
1194 + *
1195 + * ALTERNATIVELY, Libestream may be distributed under the terms of the
1196 + * following license, in which case the provisions of this license are
1197 + * required INSTEAD OF the GNU General Public License. If you wish to
1198 + * allow use of your version of this file only under the terms of the
1199 + * GNU General Public License, and not to allow others to use your
1200 + * version of this file under the terms of the following license,
1201 + * indicate your decision by deleting this paragraph and the license
1202 + * below.
1203 + *
1204 + * Redistribution and use in source and binary forms, with or without
1205 + * modification, are permitted provided that the following conditions
1206 + * are met:
1207 + * 1. Redistributions of source code must retain the above copyright
1208 + *    notice, and the entire permission notice in its entirety,
1209 + *    including the disclaimer of warranties.
1210 + * 2. Redistributions in binary form must reproduce the above copyright
1211 + *    notice, this list of conditions and the following disclaimer in the
1212 + *    documentation and/or other materials provided with the distribution.
1213 + * 3. The name of the author may not be used to endorse or promote
1214 + *    products derived from this software without specific prior
1215 + *    written permission.
1216 + *
1217 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1218 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1219 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1220 + * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
1221 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1222 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
1223 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1224 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1225 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1226 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1227 + * OF THE POSSIBILITY OF SUCH DAMAGE.
1228   */
1229  
1230  #ifndef ESTREAM_H
1231 @@ -46,6 +80,8 @@
1232  #define es_fdopen_nc          _ESTREAM_PREFIX(es_fdopen_nc)
1233  #define es_fpopen             _ESTREAM_PREFIX(es_fpopen)
1234  #define es_fpopen_nc          _ESTREAM_PREFIX(es_fpopen_nc)
1235 +#define _es_set_std_fd        _ESTREAM_PREFIX(_es_set_std_fd)
1236 +#define _es_get_std_stream    _ESTREAM_PREFIX(_es_get_std_stream)
1237  #define es_freopen            _ESTREAM_PREFIX(es_freopen)
1238  #define es_fopencookie        _ESTREAM_PREFIX(es_fopencookie)
1239  #define es_fclose             _ESTREAM_PREFIX(es_fclose)
1240 @@ -79,16 +115,21 @@
1241  #define es_fwrite             _ESTREAM_PREFIX(es_fwrite)
1242  #define es_fgets              _ESTREAM_PREFIX(es_fgets)
1243  #define es_fputs              _ESTREAM_PREFIX(es_fputs)
1244 +#define es_fputs_unlocked     _ESTREAM_PREFIX(es_fputs_unlocked)
1245  #define es_getline            _ESTREAM_PREFIX(es_getline)
1246  #define es_read_line          _ESTREAM_PREFIX(es_read_line)
1247  #define es_free               _ESTREAM_PREFIX(es_free)
1248 -#define es_fprf               _ESTREAM_PREFIX(es_fprf)
1249 -#define es_vfprf              _ESTREAM_PREFIX(es_vfprf)
1250 +#define es_fprintf            _ESTREAM_PREFIX(es_fprintf)
1251 +#define es_fprintf_unlocked   _ESTREAM_PREFIX(es_fprintf_unlocked)
1252 +#define es_vfprintf           _ESTREAM_PREFIX(es_vfprint)
1253 +#define es_vfprintf_unlocked  _ESTREAM_PREFIX(es_vfprint_unlocked)
1254  #define es_setvbuf            _ESTREAM_PREFIX(es_setvbuf)
1255  #define es_setbuf             _ESTREAM_PREFIX(es_setbuf)
1256  #define es_tmpfile            _ESTREAM_PREFIX(es_tmpfile)
1257  #define es_opaque_set         _ESTREAM_PREFIX(es_opaque_set)
1258  #define es_opaque_get         _ESTREAM_PREFIX(es_opaque_get)
1259 +#define es_fname_set          _ESTREAM_PREFIX(es_fname_set)
1260 +#define es_fname_get          _ESTREAM_PREFIX(es_fname_get)
1261  #define es_write_sanitized_utf8_buffer  \
1262                _ESTREAM_PREFIX(es_write_sanitized_utf8_buffer)
1263  #endif /*_ESTREAM_EXT_SYM_PREFIX*/
1264 @@ -213,6 +254,14 @@ int es_fclose (estream_t stream);
1265  int es_fileno (estream_t stream);
1266  int es_fileno_unlocked (estream_t stream);
1267  
1268 +void _es_set_std_fd (int no, int fd);
1269 +estream_t _es_get_std_stream (int fd);
1270 +
1271 +#define es_stdin  _es_get_std_stream (0)
1272 +#define es_stdout _es_get_std_stream (1)
1273 +#define es_stderr _es_get_std_stream (2)
1274 +
1275 +
1276  void es_flockfile (estream_t stream);
1277  int es_ftrylockfile (estream_t stream);
1278  void es_funlockfile (estream_t stream);
1279 @@ -277,6 +326,8 @@ size_t es_fwrite (const void *ES__RESTRI
1280  
1281  char *es_fgets (char *ES__RESTRICT s, int n, estream_t ES__RESTRICT stream);
1282  int es_fputs (const char *ES__RESTRICT s, estream_t ES__RESTRICT stream);
1283 +int es_fputs_unlocked (const char *ES__RESTRICT s,
1284 +                       estream_t ES__RESTRICT stream);
1285  
1286  ssize_t es_getline (char *ES__RESTRICT *ES__RESTRICT lineptr,
1287                     size_t *ES__RESTRICT n,
1288 @@ -289,9 +340,17 @@ void es_free (void *a);
1289  int es_fprintf (estream_t ES__RESTRICT stream,
1290                 const char *ES__RESTRICT format, ...)
1291       _ESTREAM_GCC_A_PRINTF(2,3);
1292 +int es_fprintf_unlocked (estream_t ES__RESTRICT stream,
1293 +                         const char *ES__RESTRICT format, ...)
1294 +     _ESTREAM_GCC_A_PRINTF(2,3);
1295 +
1296  int es_vfprintf (estream_t ES__RESTRICT stream,
1297                  const char *ES__RESTRICT format, va_list ap)
1298       _ESTREAM_GCC_A_PRINTF(2,0);
1299 +int es_vfprintf_unlocked (estream_t ES__RESTRICT stream,
1300 +                          const char *ES__RESTRICT format, va_list ap)
1301 +     _ESTREAM_GCC_A_PRINTF(2,0);
1302 +
1303  int es_setvbuf (estream_t ES__RESTRICT stream,
1304                 char *ES__RESTRICT buf, int mode, size_t size);
1305  void es_setbuf (estream_t ES__RESTRICT stream, char *ES__RESTRICT buf);
1306 @@ -301,6 +360,9 @@ estream_t es_tmpfile (void);
1307  void es_opaque_set (estream_t ES__RESTRICT stream, void *ES__RESTRICT opaque);
1308  void *es_opaque_get (estream_t stream);
1309  
1310 +void es_fname_set (estream_t stream, const char *fname);
1311 +const char *es_fname_get (estream_t stream);
1312 +
1313  
1314  #ifdef GNUPG_MAJOR_VERSION
1315  int es_write_sanitized_utf8_buffer (estream_t stream,
1316 @@ -309,7 +371,6 @@ int es_write_sanitized_utf8_buffer (estr
1317                                      size_t *bytes_written);
1318  #endif /*GNUPG_MAJOR_VERSION*/
1319  
1320 -
1321  #ifdef __cplusplus
1322  }
1323  #endif