diff options
author | Werner Koch <wk@gnupg.org> | 2007-06-25 13:54:43 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2007-06-25 13:54:43 +0200 |
commit | 831cd76256290541a102bc660442918c95a65e6c (patch) | |
tree | c5b54be81f3530fee16f7d6ecf832a235bdba222 /common | |
parent | Implemented the --gen-key command as we can't use the gpgsm-gencert.sh under ... (diff) | |
download | gnupg2-831cd76256290541a102bc660442918c95a65e6c.tar.xz gnupg2-831cd76256290541a102bc660442918c95a65e6c.zip |
Fixed a problem in estream-printf.c.
Changes for Windows (gpgsm -k does now work).
Minor cleanups.
Diffstat (limited to 'common')
-rw-r--r-- | common/ChangeLog | 42 | ||||
-rw-r--r-- | common/estream-printf.c | 35 | ||||
-rw-r--r-- | common/estream.c | 375 | ||||
-rw-r--r-- | common/estream.h | 16 | ||||
-rw-r--r-- | common/homedir.c | 107 | ||||
-rw-r--r-- | common/iobuf.c | 28 | ||||
-rw-r--r-- | common/iobuf.h | 2 | ||||
-rw-r--r-- | common/sysutils.c | 29 | ||||
-rw-r--r-- | common/sysutils.h | 1 |
9 files changed, 472 insertions, 163 deletions
diff --git a/common/ChangeLog b/common/ChangeLog index e80e70359..c5fc79d92 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,45 @@ +2007-06-25 Werner Koch <wk@g10code.com> + + * sysutils.c (translate_sys2libc_fd): New using the code from iobuf.c. + * iobuf.c: Include sysutils.h. + (iobuf_translate_file_handle): Remove. + (translate_file_handle): Use new function. + + * estream-printf.c [TEST]: Header including fixes. + (do_format): Do not append a trailing Nul. This avoids spurious + Nuls in the es_printf output. + (estream_vsnprintf, estream_vasprintf): Take this in account. + + * estream.h (struct es__stream): Change FLAGS to a bit structure. + (ES__FLAG_WRITING): Replace by a bit from FLAGS. * estream.c + (struct estream_internal): Rename FLAGS to MODEFLAGS so that they + are not confused with the estream flags. + (es_initialize, es_create): Add arg MODEFLAGS so that we can setup + the intial writemode. Changed all callers to pass them. + (es_convert_mode): Set O_BINARY. + (es_func_fd_create, es_func_fp_create, es_func_file_create) [W32]: + Call setmode if requested. + +2007-06-24 Werner Koch <wk@g10code.com> + + * estream.c (do_fpopen, es_fpopen, es_fpopen_nc): New. + (es_func_fp_create, es_func_fp_read, es_func_fp_write) + (es_func_fp_seek, es_func_fp_destroy): New. + +2007-06-22 Werner Koch <wk@g10code.com> + + * estream.c (es_fdopen): Factored code out to.. + (do_fdopen): .. new. + (es_fdopen_nc): New. + (estream_cookie_fd): Add field NO_CLOSE. + (es_func_fd_create): Add arg NO_CLOSE and changed all callers. + (es_func_fd_destroy): Handle the new flag. + + * homedir.c (gnupg_libexecdir) [W32]: Factor code out to .. + (w32_rootdir): .. new. + (gnupg_sysconfdir, gnupg_libdir, gnupg_datadir) [W32]: Return + name based on w32_rootdir(). + 2007-06-21 Werner Koch <wk@g10code.com> * membuf.h (get_membuf_len): New. diff --git a/common/estream-printf.c b/common/estream-printf.c index fce56867c..76d346953 100644 --- a/common/estream-printf.c +++ b/common/estream-printf.c @@ -60,19 +60,20 @@ #endif #ifdef TEST # include <locale.h> -#endif -#ifdef _ESTREAM_PRINTF_EXTRA_INCLUDE -#include _ESTREAM_PRINTF_EXTRA_INCLUDE +#else +# ifdef _ESTREAM_PRINTF_EXTRA_INCLUDE +# include _ESTREAM_PRINTF_EXTRA_INCLUDE +# endif #endif #include "estream-printf.h" /* Allow redefinition of asprintf used malloc functions. */ -#ifdef _ESTREAM_PRINTF_MALLOC +#if defined(_ESTREAM_PRINTF_MALLOC) && !defined(TEST) #define my_printf_malloc(a) _ESTREAM_PRINTF_MALLOC((a)) #else #define my_printf_malloc(a) malloc((a)) #endif -#ifdef _ESTREAM_PRINTF_FREE +#if defined(_ESTREAM_PRINTF_FREE) && !defined(TEST) #define my_printf_free(a) _ESTREAM_PRINTF_FREE((a)) #else #define my_printf_free(a) free((a)) @@ -1329,7 +1330,7 @@ pr_bytes_so_far (estream_printf_out_t outfnc, void *outfncarg, /* Run the actual formatting. OUTFNC and OUTFNCARG are the output functions. FORMAT is format string ARGSPECS is the parsed format string, ARGSPECS_LEN the number of items in ARGSPECS. VALUETABLE - holds the values and may be directly addressed using the poistion + holds the values and may be directly addressed using the position arguments given by ARGSPECS. MYERRNO is used for the "%m" conversion. NBYTES well be updated to reflect the number of bytes send to the output function. */ @@ -1449,8 +1450,8 @@ do_format (estream_printf_out_t outfnc, void *outfncarg, } /* Print out any trailing stuff. */ - s++; /* Need to output a terminating nul; take it from format. */ - rc = outfnc (outfncarg, format, (n=s - format)); + n = s - format; + rc = n? outfnc (outfncarg, format, n) : 0; if (!rc) *nbytes += n; @@ -1619,10 +1620,8 @@ plain_stdio_out (void *outfncarg, const char *buf, size_t buflen) { FILE *fp = (FILE*)outfncarg; - fputs ("OUT->", fp); if ( fwrite (buf, buflen, 1, fp) != 1 ) return -1; - fputs ("<-\n", fp); return 0; } @@ -1715,6 +1714,8 @@ estream_vsnprintf (char *buf, size_t bufsize, parm.used = 0; parm.buffer = bufsize?buf:NULL; rc = estream_format (fixed_buffer_out, &parm, format, arg_ptr); + if (!rc) + rc = fixed_buffer_out (&parm, "", 1); /* Print terminating Nul. */ if (rc == -1) return -1; if (bufsize && buf && parm.count >= parm.size) @@ -1807,7 +1808,9 @@ estream_vasprintf (char **bufp, const char *format, va_list arg_ptr) } rc = estream_format (dynamic_buffer_out, &parm, format, arg_ptr); - + if (!rc) + rc = dynamic_buffer_out (&parm, "", 1); /* Print terminating Nul. */ + /* Fixme: Should we shrink the resulting buffer? */ if (rc != -1 && parm.error_flag) { rc = -1; @@ -1820,9 +1823,9 @@ estream_vasprintf (char **bufp, const char *format, va_list arg_ptr) *bufp = NULL; return -1; } - + assert (parm.used); /* We have at least the terminating Nul. */ *bufp = parm.buffer; - return parm.used - 1; /* Do not include the nul. */ + return parm.used - 1; /* Do not include that Nul. */ } /* A replacement for asprintf. As with the BSD of asprintf version -1 @@ -1891,8 +1894,7 @@ one_test (const char *format, ...) static void run_tests (void) { -#if 0 - one_test ("%d %% %'d", 17, 19681977); + /*one_test ("%d %% %'d", 17, 19681977);*/ one_test ("%d %% %d", 17, 768114563); one_test ("%d %% %d", 17, -768114563); @@ -2011,7 +2013,8 @@ run_tests (void) one_test ("%50s", "the quick brown fox jumps over the lazy dogs back"); one_test ("%51s", "the quick brown fox jumps over the lazy dogs back"); one_test ("%-51s", "the quick brown fox jumps over the lazy dogs back"); -#endif + + one_test ("/%s=", "CN"); one_test ("%f", 3.1415926535); one_test ("%f", -3.1415926535); diff --git a/common/estream.c b/common/estream.c index 131ddc232..5b953b5d2 100644 --- a/common/estream.c +++ b/common/estream.c @@ -67,6 +67,10 @@ void *memrchr (const void *block, int c, size_t size); +#ifndef O_BINARY +#define O_BINARY 0 +#endif + /* Generally used types. */ typedef void *(*func_realloc_t) (void *mem, size_t size); @@ -139,8 +143,6 @@ typedef void *estream_mutex_t; #define ES_DEFAULT_OPEN_MODE (S_IRUSR | S_IWUSR) -#define ES_FLAG_WRITING ES__FLAG_WRITING - /* An internal stream object. */ struct estream_internal @@ -148,9 +150,9 @@ struct estream_internal unsigned char buffer[BUFFER_BLOCK_SIZE]; unsigned char unread_buffer[BUFFER_UNREAD_SIZE]; estream_mutex_t lock; /* Lock. */ - void *cookie; /* Cookie. */ - void *opaque; /* Opaque data. */ - unsigned int flags; /* Flags. */ + void *cookie; /* Cookie. */ + void *opaque; /* Opaque data. */ + unsigned int modeflags; /* Flags for the backend. */ off_t offset; es_cookie_read_function_t func_read; es_cookie_write_function_t func_write; @@ -325,7 +327,7 @@ es_init_do (void) /* Cookie for memory objects. */ typedef struct estream_cookie_mem { - unsigned int flags; /* Open flags. */ + unsigned int modeflags; /* Open flags. */ unsigned char *memory; /* Data. */ size_t memory_size; /* Size of MEMORY. */ size_t offset; /* Current offset in MEMORY. */ @@ -349,7 +351,7 @@ es_func_mem_create (void *ES__RESTRICT *ES__RESTRICT cookie, unsigned int append_zero, unsigned int dont_free, char **ptr, size_t *size, func_realloc_t func_realloc, func_free_t func_free, - unsigned int flags) + unsigned int modeflags) { estream_cookie_mem_t mem_cookie; int err; @@ -359,7 +361,7 @@ es_func_mem_create (void *ES__RESTRICT *ES__RESTRICT cookie, err = -1; else { - mem_cookie->flags = flags; + mem_cookie->modeflags = modeflags; mem_cookie->memory = data; mem_cookie->memory_size = data_n; mem_cookie->offset = 0; @@ -416,7 +418,7 @@ es_func_mem_write (void *cookie, const void *buffer, size_t size) { /* Regular write. */ - if (mem_cookie->flags & O_APPEND) + if (mem_cookie->modeflags & O_APPEND) /* Append to data. */ mem_cookie->offset = mem_cookie->data_len; @@ -593,17 +595,20 @@ static es_cookie_io_functions_t estream_functions_mem = es_func_mem_destroy }; + + /* Implementation of fd I/O. */ /* Cookie for fd objects. */ typedef struct estream_cookie_fd { - int fd; + int fd; /* The file descriptor we are using for actual output. */ + int no_close; /* If set we won't close the file descriptor. */ } *estream_cookie_fd_t; /* Create function for fd objects. */ static int -es_func_fd_create (void **cookie, int fd, unsigned int flags) +es_func_fd_create (void **cookie, int fd, unsigned int modeflags, int no_close) { estream_cookie_fd_t fd_cookie; int err; @@ -613,7 +618,13 @@ es_func_fd_create (void **cookie, int fd, unsigned int flags) err = -1; else { +#ifdef HAVE_DOSISH_SYSTEM + /* Make sure it is in binary mode if requested. */ + if ( (modeflags & O_BINARY) ) + setmode (fd, O_BINARY); +#endif fd_cookie->fd = fd; + fd_cookie->no_close = no_close; *cookie = fd_cookie; err = 0; } @@ -680,7 +691,7 @@ es_func_fd_destroy (void *cookie) if (fd_cookie) { - err = close (fd_cookie->fd); + err = fd_cookie->no_close? 0 : close (fd_cookie->fd); ES_MEM_FREE (fd_cookie); } else @@ -689,6 +700,7 @@ es_func_fd_destroy (void *cookie) return err; } + static es_cookie_io_functions_t estream_functions_fd = { es_func_fd_read, @@ -697,12 +709,132 @@ static es_cookie_io_functions_t estream_functions_fd = es_func_fd_destroy }; + + + +/* Implementation of FILE* I/O. */ + +/* Cookie for fp objects. */ +typedef struct estream_cookie_fp +{ + FILE *fp; /* The file pointer we are using for actual output. */ + int no_close; /* If set we won't close the file pointer. */ +} *estream_cookie_fp_t; + +/* Create function for fd objects. */ +static int +es_func_fp_create (void **cookie, FILE *fp, unsigned int modeflags, int no_close) +{ + estream_cookie_fp_t fp_cookie; + int err; + + fp_cookie = ES_MEM_ALLOC (sizeof *fp_cookie); + if (!fp_cookie) + err = -1; + else + { +#ifdef HAVE_DOSISH_SYSTEM + /* Make sure it is in binary mode if requested. */ + if ( (modeflags & O_BINARY) ) + setmode (fileno (fp), O_BINARY); +#endif + fp_cookie->fp = fp; + fp_cookie->no_close = no_close; + *cookie = fp_cookie; + err = 0; + } + + return err; +} + +/* Read function for FILE* objects. */ +static ssize_t +es_func_fp_read (void *cookie, void *buffer, size_t size) + +{ + estream_cookie_fp_t file_cookie = cookie; + ssize_t bytes_read; + + bytes_read = fread (buffer, 1, size, file_cookie->fp); + if (!bytes_read && ferror (file_cookie->fp)) + return -1; + return bytes_read; +} + +/* Write function for FILE* objects. */ +static ssize_t +es_func_fp_write (void *cookie, const void *buffer, size_t size) + +{ + estream_cookie_fp_t file_cookie = cookie; + size_t bytes_written; + + bytes_written = fwrite (buffer, 1, size, file_cookie->fp); + if (bytes_written != size) + return -1; + return bytes_written; +} + +/* Seek function for FILE* objects. */ +static int +es_func_fp_seek (void *cookie, off_t *offset, int whence) +{ + estream_cookie_fp_t file_cookie = cookie; + long int offset_new; + + if ( fseek (file_cookie->fp, (long int)*offset, whence) ) + { + fprintf (stderr, "\nfseek failed: errno=%d (%s)\n", errno,strerror (errno)); + return -1; + } + + offset_new = ftell (file_cookie->fp); + if (offset_new == -1) + { + fprintf (stderr, "\nftell failed: errno=%d (%s)\n", errno,strerror (errno)); + return -1; + } + *offset = offset_new; + return 0; +} + +/* Destroy function for fd objects. */ +static int +es_func_fp_destroy (void *cookie) +{ + estream_cookie_fp_t fp_cookie = cookie; + int err; + + if (fp_cookie) + { + fflush (fp_cookie->fp); + err = fp_cookie->no_close? 0 : fclose (fp_cookie->fp); + ES_MEM_FREE (fp_cookie); + } + else + err = 0; + + return err; +} + + +static es_cookie_io_functions_t estream_functions_fp = + { + es_func_fp_read, + es_func_fp_write, + es_func_fp_seek, + es_func_fp_destroy + }; + + + + /* Implementation of file I/O. */ /* Create function for file objects. */ static int es_func_file_create (void **cookie, int *filedes, - const char *path, unsigned int flags) + const char *path, unsigned int modeflags) { estream_cookie_fd_t file_cookie; int err; @@ -718,12 +850,17 @@ es_func_file_create (void **cookie, int *filedes, goto out; } - fd = open (path, flags, ES_DEFAULT_OPEN_MODE); + fd = open (path, modeflags, ES_DEFAULT_OPEN_MODE); if (fd == -1) { err = -1; goto out; } +#ifdef HAVE_DOSISH_SYSTEM + /* Make sure it is in binary mode if requested. */ + if ( (modeflags & O_BINARY) ) + setmode (fd, O_BINARY); +#endif file_cookie->fd = fd; *cookie = file_cookie; @@ -750,16 +887,10 @@ static es_cookie_io_functions_t estream_functions_file = /* Stream primitives. */ static int -es_convert_mode (const char *mode, unsigned int *flags) +es_convert_mode (const char *mode, unsigned int *modeflags) { - /* FIXME: We need to allow all mode flags permutations and for - binary mode we need to do a - - #ifdef HAVE_DOSISH_SYSTEM - setmode (fd, O_BINARY); - #endif - */ + /* FIXME: We need to allow all mode flags permutations. */ struct { const char *mode; @@ -767,33 +898,34 @@ es_convert_mode (const char *mode, unsigned int *flags) } mode_flags[] = { { "r", O_RDONLY }, { "rb", - O_RDONLY }, + O_RDONLY | O_BINARY }, { "w", O_WRONLY | O_TRUNC | O_CREAT }, { "wb", - O_WRONLY | O_TRUNC | O_CREAT }, + O_WRONLY | O_TRUNC | O_CREAT | O_BINARY }, { "a", O_WRONLY | O_APPEND | O_CREAT }, { "ab", - O_WRONLY | O_APPEND | O_CREAT }, + O_WRONLY | O_APPEND | O_CREAT | O_BINARY }, { "r+", O_RDWR }, { "rb+", - O_RDWR }, + O_RDWR | O_BINARY }, { "r+b", - O_RDONLY | O_WRONLY }, + O_RDONLY | O_WRONLY | O_BINARY }, { "w+", O_RDWR | O_TRUNC | O_CREAT }, { "wb+", - O_RDWR | O_TRUNC | O_CREAT }, + O_RDWR | O_TRUNC | O_CREAT | O_BINARY }, { "w+b", - O_RDWR | O_TRUNC | O_CREAT }, + O_RDWR | O_TRUNC | O_CREAT | O_BINARY }, { "a+", O_RDWR | O_CREAT | O_APPEND }, { "ab+", - O_RDWR | O_CREAT | O_APPEND }, + O_RDWR | O_CREAT | O_APPEND | O_BINARY }, { "a+b", - O_RDWR | O_CREAT | O_APPEND } }; + O_RDWR | O_CREAT | O_APPEND | O_BINARY } + }; unsigned int i; int err; @@ -808,7 +940,7 @@ es_convert_mode (const char *mode, unsigned int *flags) else { err = 0; - *flags = mode_flags[i].flags; + *modeflags = mode_flags[i].flags; } return err; @@ -868,7 +1000,7 @@ es_flush (estream_t stream) es_cookie_write_function_t func_write = stream->intern->func_write; int err; - assert (stream->flags & ES_FLAG_WRITING); + assert (stream->flags.writing); if (stream->data_offset) { @@ -935,7 +1067,7 @@ es_flush (estream_t stream) static void es_empty (estream_t stream) { - assert (! (stream->flags & ES_FLAG_WRITING)); + assert (!stream->flags.writing); stream->data_len = 0; stream->data_offset = 0; stream->unread_data_len = 0; @@ -944,7 +1076,8 @@ es_empty (estream_t stream) /* Initialize STREAM. */ static void es_initialize (estream_t stream, - void *cookie, int fd, es_cookie_io_functions_t functions) + void *cookie, int fd, es_cookie_io_functions_t functions, + unsigned int modeflags) { stream->intern->cookie = cookie; stream->intern->opaque = NULL; @@ -967,7 +1100,15 @@ es_initialize (estream_t stream, stream->data_offset = 0; stream->data_flushed = 0; stream->unread_data_len = 0; - stream->flags = 0; + /* Depending on the modeflags we set whether we start in writing or + reading mode. This is required in case we are working on a + wronly stream which is not seeekable (like stdout). Without this + pre-initialization we would do a seek at the first write call and + as this will fail no utput will be delivered. */ + if ((modeflags & O_WRONLY) || (modeflags & O_RDWR) ) + stream->flags.writing = 1; + else + stream->flags.writing = 0; } /* Deinitialize STREAM. */ @@ -988,7 +1129,7 @@ es_deinitialize (estream_t stream) func_close = stream->intern->func_close; err = 0; - if (stream->flags & ES_FLAG_WRITING) + if (stream->flags.writing) SET_UNLESS_NONZERO (err, tmp_err, es_flush (stream)); if (func_close) SET_UNLESS_NONZERO (err, tmp_err, (*func_close) (stream->intern->cookie)); @@ -1000,7 +1141,7 @@ es_deinitialize (estream_t stream) /* Create a new stream object, initialize it. */ static int es_create (estream_t *stream, void *cookie, int fd, - es_cookie_io_functions_t functions) + es_cookie_io_functions_t functions, unsigned int modeflags) { estream_internal_t stream_internal_new; estream_t stream_new; @@ -1030,7 +1171,7 @@ es_create (estream_t *stream, void *cookie, int fd, stream_new->intern = stream_internal_new; ESTREAM_MUTEX_INITIALIZE (stream_new->intern->lock); - es_initialize (stream_new, cookie, fd, functions); + es_initialize (stream_new, cookie, fd, functions, modeflags); err = es_list_add (stream_new); if (err) @@ -1186,13 +1327,13 @@ es_readn (estream_t ES__RESTRICT stream, data_read = 0; err = 0; - if (stream->flags & ES_FLAG_WRITING) + if (stream->flags.writing) { /* Switching to reading mode -> flush output. */ err = es_flush (stream); if (err) goto out; - stream->flags &= ~ES_FLAG_WRITING; + stream->flags.writing = 0; } /* Read unread data first. */ @@ -1274,14 +1415,14 @@ es_seek (estream_t ES__RESTRICT stream, off_t offset, int whence, goto out; } - if (stream->flags & ES_FLAG_WRITING) + if (stream->flags.writing) { /* Flush data first in order to prevent flushing it to the wrong offset. */ err = es_flush (stream); if (err) goto out; - stream->flags &= ~ES_FLAG_WRITING; + stream->flags.writing = 0; } off = offset; @@ -1451,7 +1592,7 @@ es_writen (estream_t ES__RESTRICT stream, data_written = 0; err = 0; - if (! (stream->flags & ES_FLAG_WRITING)) + if (!stream->flags.writing) { /* Switching to writing mode -> discard input data and seek to position at which reading has stopped. We can do this only @@ -1489,8 +1630,8 @@ es_writen (estream_t ES__RESTRICT stream, if (bytes_written) *bytes_written = data_written; if (data_written) - if (! (stream->flags & ES_FLAG_WRITING)) - stream->flags |= ES_FLAG_WRITING; + if (!stream->flags.writing) + stream->flags.writing = 1; return err; } @@ -1502,13 +1643,13 @@ es_peek (estream_t ES__RESTRICT stream, unsigned char **ES__RESTRICT data, { int err; - if (stream->flags & ES_FLAG_WRITING) + if (stream->flags.writing) { /* Switching to reading mode -> flush output. */ err = es_flush (stream); if (err) goto out; - stream->flags &= ~ES_FLAG_WRITING; + stream->flags.writing = 0; } if (stream->data_offset == stream->data_len) @@ -1572,12 +1713,13 @@ doreadline (estream_t ES__RESTRICT stream, size_t max_length, line_stream_cookie = NULL; err = es_func_mem_create (&line_stream_cookie, NULL, 0, 0, BUFFER_BLOCK_SIZE, - 1, 0, 0, NULL, 0, ES_MEM_REALLOC, ES_MEM_FREE, O_RDWR); + 1, 0, 0, NULL, 0, ES_MEM_REALLOC, ES_MEM_FREE, + O_RDWR); if (err) goto out; err = es_create (&line_stream, line_stream_cookie, -1, - estream_functions_mem); + estream_functions_mem, O_RDWR); if (err) goto out; @@ -1738,7 +1880,7 @@ es_set_buffering (estream_t ES__RESTRICT stream, int err; /* Flush or empty buffer depending on mode. */ - if (stream->flags & ES_FLAG_WRITING) + if (stream->flags.writing) { err = es_flush (stream); if (err) @@ -1839,7 +1981,7 @@ es_init (void) estream_t es_fopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode) { - unsigned int flags; + unsigned int modeflags; int create_called; estream_t stream; void *cookie; @@ -1850,16 +1992,16 @@ es_fopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode) cookie = NULL; create_called = 0; - err = es_convert_mode (mode, &flags); + err = es_convert_mode (mode, &modeflags); if (err) goto out; - err = es_func_file_create (&cookie, &fd, path, flags); + err = es_func_file_create (&cookie, &fd, path, modeflags); if (err) goto out; create_called = 1; - err = es_create (&stream, cookie, fd, estream_functions_file); + err = es_create (&stream, cookie, fd, estream_functions_file, modeflags); if (err) goto out; @@ -1878,7 +2020,7 @@ es_mopen (unsigned char *ES__RESTRICT data, size_t data_n, size_t data_len, func_realloc_t func_realloc, func_free_t func_free, const char *ES__RESTRICT mode) { - unsigned int flags; + unsigned int modeflags; int create_called; estream_t stream; void *cookie; @@ -1888,18 +2030,18 @@ es_mopen (unsigned char *ES__RESTRICT data, size_t data_n, size_t data_len, stream = NULL; create_called = 0; - err = es_convert_mode (mode, &flags); + err = es_convert_mode (mode, &modeflags); if (err) goto out; err = es_func_mem_create (&cookie, data, data_n, data_len, BUFFER_BLOCK_SIZE, grow, 0, 0, - NULL, 0, func_realloc, func_free, flags); + NULL, 0, func_realloc, func_free, modeflags); if (err) goto out; create_called = 1; - err = es_create (&stream, cookie, -1, estream_functions_mem); + err = es_create (&stream, cookie, -1, estream_functions_mem, modeflags); out: @@ -1913,25 +2055,25 @@ es_mopen (unsigned char *ES__RESTRICT data, size_t data_n, size_t data_len, estream_t es_open_memstream (char **ptr, size_t *size) { - unsigned int flags; + unsigned int modeflags; int create_called; estream_t stream; void *cookie; int err; - flags = O_RDWR; + modeflags = O_RDWR; create_called = 0; stream = NULL; cookie = 0; err = es_func_mem_create (&cookie, NULL, 0, 0, BUFFER_BLOCK_SIZE, 1, 1, 1, - ptr, size, ES_MEM_REALLOC, ES_MEM_FREE, flags); + ptr, size, ES_MEM_REALLOC, ES_MEM_FREE, modeflags); if (err) goto out; create_called = 1; - err = es_create (&stream, cookie, -1, estream_functions_mem); + err = es_create (&stream, cookie, -1, estream_functions_mem, modeflags); out: @@ -1947,18 +2089,18 @@ es_fopencookie (void *ES__RESTRICT cookie, const char *ES__RESTRICT mode, es_cookie_io_functions_t functions) { - unsigned int flags; + unsigned int modeflags; estream_t stream; int err; stream = NULL; - flags = 0; + modeflags = 0; - err = es_convert_mode (mode, &flags); + err = es_convert_mode (mode, &modeflags); if (err) goto out; - err = es_create (&stream, cookie, -1, functions); + err = es_create (&stream, cookie, -1, functions, modeflags); if (err) goto out; @@ -1969,9 +2111,9 @@ es_fopencookie (void *ES__RESTRICT cookie, estream_t -es_fdopen (int filedes, const char *mode) +do_fdopen (int filedes, const char *mode, int no_close) { - unsigned int flags; + unsigned int modeflags; int create_called; estream_t stream; void *cookie; @@ -1981,16 +2123,16 @@ es_fdopen (int filedes, const char *mode) cookie = NULL; create_called = 0; - err = es_convert_mode (mode, &flags); + err = es_convert_mode (mode, &modeflags); if (err) goto out; - err = es_func_fd_create (&cookie, filedes, flags); + err = es_func_fd_create (&cookie, filedes, modeflags, no_close); if (err) goto out; create_called = 1; - err = es_create (&stream, cookie, filedes, estream_functions_fd); + err = es_create (&stream, cookie, filedes, estream_functions_fd, modeflags); out: @@ -1999,7 +2141,78 @@ es_fdopen (int filedes, const char *mode) return stream; } + +estream_t +es_fdopen (int filedes, const char *mode) +{ + return do_fdopen (filedes, mode, 0); +} + +/* A variant of es_fdopen which does not close FILEDES at the end. */ +estream_t +es_fdopen_nc (int filedes, const char *mode) +{ + return do_fdopen (filedes, mode, 1); +} + + +estream_t +do_fpopen (FILE *fp, const char *mode, int no_close) +{ + unsigned int modeflags; + int create_called; + estream_t stream; + void *cookie; + int err; + + stream = NULL; + cookie = NULL; + create_called = 0; + + err = es_convert_mode (mode, &modeflags); + if (err) + goto out; + + fflush (fp); + err = es_func_fp_create (&cookie, fp, modeflags, no_close); + if (err) + goto out; + + create_called = 1; + err = es_create (&stream, cookie, fileno (fp), estream_functions_fp, + modeflags); + + out: + + if (err && create_called) + (*estream_functions_fp.func_close) (cookie); + + return stream; +} + +/* Create an estream from the stdio stream FP. This mechanism is + useful in case the stdio streams have special properties and may + not be mixed with fd based functions. This is for example the case + under Windows where the 3 standard streams are associated with the + console whereas a duped and fd-opened stream of one of this stream + won't be associated with the console. As this messes things up it + is easier to keep on using the standard I/O stream as a backend for + estream. */ +estream_t +es_fpopen (FILE *fp, const char *mode) +{ + return do_fpopen (fp, mode, 0); +} + + +/* Same as es_fpopen but does not close FP at the end. */ +estream_t +es_fpopen_nc (FILE *fp, const char *mode) +{ + return do_fpopen (fp, mode, 1); +} + estream_t es_freopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode, @@ -2009,7 +2222,7 @@ es_freopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode, if (path) { - unsigned int flags; + unsigned int modeflags; int create_called; void *cookie; int fd; @@ -2021,16 +2234,16 @@ es_freopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode, es_deinitialize (stream); - err = es_convert_mode (mode, &flags); + err = es_convert_mode (mode, &modeflags); if (err) goto leave; - err = es_func_file_create (&cookie, &fd, path, flags); + err = es_func_file_create (&cookie, &fd, path, modeflags); if (err) goto leave; create_called = 1; - es_initialize (stream, cookie, fd, estream_functions_file); + es_initialize (stream, cookie, fd, estream_functions_file, modeflags); leave: @@ -2173,7 +2386,7 @@ es_fflush (estream_t stream) if (stream) { ESTREAM_LOCK (stream); - if (stream->flags & ES_FLAG_WRITING) + if (stream->flags.writing) err = es_flush (stream); else { @@ -2686,7 +2899,7 @@ tmpfd (void) estream_t es_tmpfile (void) { - unsigned int flags; + unsigned int modeflags; int create_called; estream_t stream; void *cookie; @@ -2695,7 +2908,7 @@ es_tmpfile (void) create_called = 0; stream = NULL; - flags = O_RDWR | O_TRUNC | O_CREAT; + modeflags = O_RDWR | O_TRUNC | O_CREAT; cookie = NULL; fd = tmpfd (); @@ -2705,12 +2918,12 @@ es_tmpfile (void) goto out; } - err = es_func_fd_create (&cookie, fd, flags); + err = es_func_fd_create (&cookie, fd, modeflags, 0); if (err) goto out; create_called = 1; - err = es_create (&stream, cookie, fd, estream_functions_fd); + err = es_create (&stream, cookie, fd, estream_functions_fd, modeflags); out: diff --git a/common/estream.h b/common/estream.h index b5694370e..79bfbb71b 100644 --- a/common/estream.h +++ b/common/estream.h @@ -45,6 +45,9 @@ #define es_mopen _ESTREAM_PREFIX(es_mopen) #define es_open_memstream _ESTREAM_PREFIX(es_open_memstream) #define es_fdopen _ESTREAM_PREFIX(es_fdopen) +#define es_fdopen_nc _ESTREAM_PREFIX(es_fdopen_nc) +#define es_fpopen _ESTREAM_PREFIX(es_fpopen) +#define es_fpopen_nc _ESTREAM_PREFIX(es_fpopen_nc) #define es_freopen _ESTREAM_PREFIX(es_freopen) #define es_fopencookie _ESTREAM_PREFIX(es_fopencookie) #define es_fclose _ESTREAM_PREFIX(es_fclose) @@ -136,8 +139,10 @@ struct es__stream size_t unread_data_len; /* Various flags. */ -#define ES__FLAG_WRITING (1 << 0) - unsigned int flags; + struct { + unsigned int writing: 1; + unsigned int reserved: 7; + } flags; /* A pointer to our internal data for this stream. */ struct estream_internal *intern; @@ -197,6 +202,9 @@ estream_t es_mopen (unsigned char *ES__RESTRICT data, const char *ES__RESTRICT mode); estream_t es_open_memstream (char **ptr, size_t *size); estream_t es_fdopen (int filedes, const char *mode); +estream_t es_fdopen_nc (int filedes, const char *mode); +estream_t es_fpopen (FILE *fp, const char *mode); +estream_t es_fpopen_nc (FILE *fp, const char *mode); estream_t es_freopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode, estream_t ES__RESTRICT stream); @@ -232,14 +240,14 @@ int _es_getc_underflow (estream_t stream); int _es_putc_overflow (int c, estream_t stream); #define es_getc_unlocked(stream) \ - (((! ((stream)->flags & 1)) \ + (((!(stream)->flags.writing) \ && ((stream)->data_offset < (stream)->data_len) \ && (! (stream)->unread_data_len)) \ ? ((int) (stream)->buffer[((stream)->data_offset)++]) \ : _es_getc_underflow ((stream))) #define es_putc_unlocked(c, stream) \ - ((((stream)->flags & 1) \ + (((stream)->flags.writing \ && ((stream)->data_offset < (stream)->buffer_size) \ && (c != '\n')) \ ? ((int) ((stream)->buffer[((stream)->data_offset)++] = (c))) \ diff --git a/common/homedir.c b/common/homedir.c index 654c96bec..e0c511cc9 100644 --- a/common/homedir.c +++ b/common/homedir.c @@ -126,38 +126,10 @@ default_homedir (void) } -/* Return the name of the sysconfdir. This is a static string. This - function is required because under Windows we can't simply compile - it in. */ -const char * -gnupg_sysconfdir (void) -{ #ifdef HAVE_W32_SYSTEM -#warning get the sysconfdir from somewhere else - return GNUPG_SYSCONFDIR; -#else /*!HAVE_W32_SYSTEM*/ - return GNUPG_SYSCONFDIR; -#endif /*!HAVE_W32_SYSTEM*/ -} - - -const char * -gnupg_bindir (void) -{ -#ifdef HAVE_W32_SYSTEM - return gnupg_libexecdir (); -#else /*!HAVE_W32_SYSTEM*/ - return GNUPG_BINDIR; -#endif /*!HAVE_W32_SYSTEM*/ -} - - -/* Return the name of the libexec directory. The name is allocated in - a static area on the first use. This function won't fail. */ -const char * -gnupg_libexecdir (void) +static const char * +w32_rootdir (void) { -#ifdef HAVE_W32_SYSTEM static int got_dir; static char dir[MAX_PATH+5]; @@ -184,17 +156,75 @@ gnupg_libexecdir (void) if (*dir) return dir; /* Fallback to the hardwired value. */ + return GNUPG_LIBEXECDIR; +} #endif /*HAVE_W32_SYSTEM*/ + + + +/* Return the name of the sysconfdir. This is a static string. This + function is required because under Windows we can't simply compile + it in. */ +const char * +gnupg_sysconfdir (void) +{ +#ifdef HAVE_W32_SYSTEM + static char *name; + + if (!name) + { + const char *s1, *s2; + s1 = w32_rootdir (); + s2 = DIRSEP_S "etc" DIRSEP_S "gnupg"; + name = xmalloc (strlen (s1) + strlen (s2) + 1); + strcpy (stpcpy (name, s1), s2); + } + return name; +#else /*!HAVE_W32_SYSTEM*/ + return GNUPG_SYSCONFDIR; +#endif /*!HAVE_W32_SYSTEM*/ +} + + +const char * +gnupg_bindir (void) +{ +#ifdef HAVE_W32_SYSTEM + return w32_rootdir (); +#else /*!HAVE_W32_SYSTEM*/ + return GNUPG_BINDIR; +#endif /*!HAVE_W32_SYSTEM*/ +} + + +/* Return the name of the libexec directory. The name is allocated in + a static area on the first use. This function won't fail. */ +const char * +gnupg_libexecdir (void) +{ +#ifdef HAVE_W32_SYSTEM + return w32_rootdir (); +#else /*!HAVE_W32_SYSTEM*/ return GNUPG_LIBEXECDIR; +#endif /*!HAVE_W32_SYSTEM*/ } const char * gnupg_libdir (void) { #ifdef HAVE_W32_SYSTEM -#warning get the libdir from somewhere else - return GNUPG_LIBDIR; + static char *name; + + if (!name) + { + const char *s1, *s2; + s1 = w32_rootdir (); + s2 = DIRSEP_S "lib" DIRSEP_S "gnupg"; + name = xmalloc (strlen (s1) + strlen (s2) + 1); + strcpy (stpcpy (name, s1), s2); + } + return name; #else /*!HAVE_W32_SYSTEM*/ return GNUPG_LIBDIR; #endif /*!HAVE_W32_SYSTEM*/ @@ -204,8 +234,17 @@ const char * gnupg_datadir (void) { #ifdef HAVE_W32_SYSTEM -#warning get the datadir from somewhere else - return GNUPG_DATADIR; + static char *name; + + if (!name) + { + const char *s1, *s2; + s1 = w32_rootdir (); + s2 = DIRSEP_S "share" DIRSEP_S "gnupg"; + name = xmalloc (strlen (s1) + strlen (s2) + 1); + strcpy (stpcpy (name, s1), s2); + } + return name; #else /*!HAVE_W32_SYSTEM*/ return GNUPG_DATADIR; #endif /*!HAVE_W32_SYSTEM*/ diff --git a/common/iobuf.c b/common/iobuf.c index 40af196da..f395405f6 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -40,6 +40,7 @@ #endif /* __riscos__ */ #include "util.h" +#include "sysutils.h" #include "iobuf.h" /* The size of the internal buffers. @@ -2350,37 +2351,12 @@ iobuf_read_line (iobuf_t a, byte ** addr_of_buffer, return nbytes; } -/* This is the non iobuf specific function */ -int -iobuf_translate_file_handle (int fd, int for_write) -{ -#ifdef _WIN32 - { - int x; - - if (fd <= 2) - return fd; /* do not do this for error, stdin, stdout, stderr */ - - x = _open_osfhandle (fd, for_write ? 1 : 0); - if (x == -1) - log_error ("failed to translate osfhandle %p\n", (void *) fd); - else - { - /*log_info ("_open_osfhandle %p yields %d%s\n", - (void*)fd, x, for_write? " for writing":"" ); */ - fd = x; - } - } -#endif - return fd; -} - static int translate_file_handle (int fd, int for_write) { #ifdef _WIN32 #ifdef FILE_FILTER_USES_STDIO - fd = iobuf_translate_file_handle (fd, for_write); + fd = translate_sys2libc_fd (fd, for_write); #else { int x; diff --git a/common/iobuf.h b/common/iobuf.h index fa11f3905..f20ea28fa 100644 --- a/common/iobuf.h +++ b/common/iobuf.h @@ -136,8 +136,6 @@ const char *iobuf_get_fname (iobuf_t a); void iobuf_set_partial_block_mode (iobuf_t a, size_t len); -int iobuf_translate_file_handle (int fd, int for_write); - void iobuf_skip_rest (iobuf_t a, unsigned long n, int partial); diff --git a/common/sysutils.c b/common/sysutils.c index ff1fe1ba4..a3fc8cb07 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -272,3 +272,32 @@ gnupg_sleep (unsigned int seconds) # endif #endif } + + +/* This function is a NOP for POSIX systems but required under Windows + as the file handles as returned by OS calls (like CreateFile) are + different from the libc file descriptors (like open). This function + translates system file handles to libc file handles. FOR_WRITE + gives the direction of the handle. */ +int +translate_sys2libc_fd (int fd, int for_write) +{ +#ifdef HAVE_W32_SYSTEM + int x; + + if (fd <= 2) + return fd; /* Do not do this for error, stdin, stdout, stderr. + (This also ignores an fd of -1.) */ + + x = _open_osfhandle (fd, for_write ? 1 : 0); + if (x == -1) + log_error ("failed to translate osfhandle %p\n", (void *) fd); + else + { +/* log_info ("_open_osfhandle %p yields %d%s\n", */ +/* (void*)fd, x, for_write? " for writing":"" ); */ + fd = x; + } +#endif /* HAVE_W32_SYSTEM */ + return fd; +} diff --git a/common/sysutils.h b/common/sysutils.h index 0e295f5d1..3ed702aa7 100644 --- a/common/sysutils.h +++ b/common/sysutils.h @@ -28,6 +28,7 @@ int enable_core_dumps (void); const unsigned char *get_session_marker (size_t *rlen); int check_permissions (const char *path,int extension,int checkonly); void gnupg_sleep (unsigned int seconds); +int translate_sys2libc_fd (int fd, int for_write); #ifdef HAVE_W32_SYSTEM |