diff options
author | Werner Koch <[email protected]> | 2010-06-07 13:33:02 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2010-06-07 13:33:02 +0000 |
commit | bbe388b5db35be6ffece8ebd42f11372af016763 (patch) | |
tree | 73e1fe9697b969be66bd89953125010e5721efe1 /common | |
parent | Print --version etc via estream (diff) | |
download | gnupg-bbe388b5db35be6ffece8ebd42f11372af016763.tar.gz gnupg-bbe388b5db35be6ffece8ebd42f11372af016763.zip |
Add unfinished gpgtar.
Collected changes and ports of bug fixes from stable.
Diffstat (limited to 'common')
-rw-r--r-- | common/ChangeLog | 21 | ||||
-rw-r--r-- | common/estream.c | 89 | ||||
-rw-r--r-- | common/estream.h | 5 | ||||
-rw-r--r-- | common/exechelp-posix.c | 21 | ||||
-rw-r--r-- | common/exechelp-w32.c | 35 | ||||
-rw-r--r-- | common/exechelp-w32ce.c | 5 | ||||
-rw-r--r-- | common/exechelp.h | 15 | ||||
-rw-r--r-- | common/logging.c | 6 |
8 files changed, 173 insertions, 24 deletions
diff --git a/common/ChangeLog b/common/ChangeLog index e6bb812dc..8d8f9af29 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,22 @@ +2010-06-07 Werner Koch <[email protected]> + + * estream.c (es_fname_get, es_fname_set): New. + (fname_set_internal): New. + (struct estream_internal): Add fields printable_fname and + printable_fname_inuse. + (_es_get_std_stream): Set stream name. + (es_fopen, es_freopen, es_deinitialize): Set fname. + + * exechelp-posix.c (gnupg_spawn_process): Allow passing INFILE or + OUTFILE as NULL. + * exechelp-w32.c (gnupg_spawn_process): Ditto. + * exechelp-w32ce.c (gnupg_spawn_process): Return an error for + INFILE or OUTFILE passed as NULL. + +2010-06-01 Werner Koch <[email protected]> + + * logging.c (log_get_stream): Make sture a log stream is available. + 2010-05-30 Werner Koch <[email protected]> * init.c (writestring_via_estream): New. @@ -15,7 +34,7 @@ (es_func_fd_destroy): Implement a dummy stream. * exechelp-w32ce.c (build_w32_commandline): Add args FD0_ISNULL - and FD1_ISNULL. Remove arg PGMNAME. Change callers. + and FD1_ISNULL. Remove arg PGMNAME. Change callers. (gnupg_spawn_process_detached): Implement. (gnupg_spawn_process_fd): Implement one special case for now. diff --git a/common/estream.c b/common/estream.c index 3a17910f7..56e362d68 100644 --- a/common/estream.c +++ b/common/estream.c @@ -211,6 +211,7 @@ struct estream_internal void *cookie; /* Cookie. */ void *opaque; /* Opaque data. */ unsigned int modeflags; /* Flags for the backend. */ + char *printable_fname; /* Malloced filename for es_fname_get. */ off_t offset; es_cookie_read_function_t func_read; es_cookie_write_function_t func_write; @@ -227,6 +228,7 @@ struct estream_internal unsigned int is_stdstream:1; /* This is a standard stream. */ unsigned int stdstream_fd:2; /* 0, 1 or 2 for a standard stream. */ unsigned int print_err: 1; /* Error in print_fun_writer. */ + unsigned int printable_fname_inuse: 1; /* es_fname_get has been used. */ int print_errno; /* Errno from print_fun_writer. */ size_t print_ntotal; /* Bytes written from in print_fun_writer. */ FILE *print_fp; /* Stdio stream used by print_fun_writer. */ @@ -266,8 +268,12 @@ static unsigned char custom_std_fds_valid[3]; #endif - +/* Local prototypes. */ +static void fname_set_internal (estream_t stream, const char *fname, int quote); + + + /* Macros. */ /* Calculate array dimension. */ @@ -1275,6 +1281,8 @@ es_initialize (estream_t stream, stream->intern->is_stdstream = 0; stream->intern->stdstream_fd = 0; stream->intern->deallocate_buffer = 0; + stream->intern->printable_fname = NULL; + stream->intern->printable_fname_inuse = 0; stream->data_len = 0; stream->data_offset = 0; @@ -1314,7 +1322,10 @@ es_deinitialize (estream_t stream) if (func_close) SET_UNLESS_NONZERO (err, tmp_err, (*func_close) (stream->intern->cookie)); - + mem_free (stream->intern->printable_fname); + stream->intern->printable_fname = NULL; + stream->intern->printable_fname_inuse = 0; + return err; } @@ -2190,6 +2201,9 @@ es_fopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode) if (err) goto out; + if (stream && path) + fname_set_internal (stream, path, 1); + out: if (err && create_called) @@ -2467,6 +2481,9 @@ _es_get_std_stream (int fd) stream->intern->stdstream_fd = fd; if (fd == 2) es_set_buffering (stream, NULL, _IOLBF, 0); + fname_set_internal (stream, + fd == 0? "[stdin]" : + fd == 1? "[stdout]" : "[stderr]", 0); } ESTREAM_LIST_UNLOCK; return stream; @@ -2515,7 +2532,11 @@ es_freopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode, stream = NULL; } else - ESTREAM_UNLOCK (stream); + { + if (stream && path) + fname_set_internal (stream, path, 1); + ESTREAM_UNLOCK (stream); + } } else { @@ -3407,6 +3428,68 @@ es_opaque_get (estream_t stream) return opaque; } + +static void +fname_set_internal (estream_t stream, const char *fname, int quote) +{ + if (stream->intern->printable_fname + && !stream->intern->printable_fname_inuse) + { + mem_free (stream->intern->printable_fname); + stream->intern->printable_fname = NULL; + } + if (stream->intern->printable_fname) + return; /* Can't change because it is in use. */ + + if (*fname != '[') + quote = 0; + else + quote = !!quote; + + stream->intern->printable_fname = mem_alloc (strlen (fname) + quote + 1); + if (fname) + { + if (quote) + stream->intern->printable_fname[0] = '\\'; + strcpy (stream->intern->printable_fname+quote, fname); + } +} + + +/* Set the filename attribute of STREAM. There is no error return. + as long as STREAM is valid. This function is called internally by + functions which open a filename. */ +void +es_fname_set (estream_t stream, const char *fname) +{ + if (fname) + { + ESTREAM_LOCK (stream); + fname_set_internal (stream, fname, 1); + ESTREAM_UNLOCK (stream); + } +} + + +/* Return the filename attribute of STREAM. In case no filename has + been set, "[?]" will be returned. The returned file name is valid + as long as STREAM is valid. */ +const char * +es_fname_get (estream_t stream) +{ + const char *fname; + + ESTREAM_LOCK (stream); + fname = stream->intern->printable_fname; + if (fname) + stream->intern->printable_fname_inuse = 1; + ESTREAM_UNLOCK (stream); + if (!fname) + fname = "[?]"; + return fname; +} + + /* Print a BUFFER to STREAM while replacing all control characters and the characters in DELIMITERS by standard C escape sequences. Returns 0 on success or -1 on error. If BYTES_WRITTEN is not NULL diff --git a/common/estream.h b/common/estream.h index f63864e67..6eb986fd6 100644 --- a/common/estream.h +++ b/common/estream.h @@ -128,6 +128,8 @@ #define es_tmpfile _ESTREAM_PREFIX(es_tmpfile) #define es_opaque_set _ESTREAM_PREFIX(es_opaque_set) #define es_opaque_get _ESTREAM_PREFIX(es_opaque_get) +#define es_fname_set _ESTREAM_PREFIX(es_fname_set) +#define es_fname_get _ESTREAM_PREFIX(es_fname_get) #define es_write_sanitized_utf8_buffer \ _ESTREAM_PREFIX(es_write_sanitized_utf8_buffer) #endif /*_ESTREAM_EXT_SYM_PREFIX*/ @@ -358,6 +360,9 @@ estream_t es_tmpfile (void); void es_opaque_set (estream_t ES__RESTRICT stream, void *ES__RESTRICT opaque); void *es_opaque_get (estream_t stream); +void es_fname_set (estream_t stream, const char *fname); +const char *es_fname_get (estream_t stream); + #ifdef GNUPG_MAJOR_VERSION int es_write_sanitized_utf8_buffer (estream_t stream, diff --git a/common/exechelp-posix.c b/common/exechelp-posix.c index aaf628715..1f4cca6c8 100644 --- a/common/exechelp-posix.c +++ b/common/exechelp-posix.c @@ -313,11 +313,22 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], *statusfile = NULL; *pid = (pid_t)(-1); - es_fflush (infile); - es_rewind (infile); - fd = es_fileno (infile); - fdout = es_fileno (outfile); - if (fd == -1 || fdout == -1) + + if (infile) + { + es_fflush (infile); + es_rewind (infile); + fd = es_fileno (infile); + } + else + fd = -1; + + if (outfile) + fdout = es_fileno (outfile); + else + fdout = -1; + + if ((infile && fd == -1) || (outfile && fdout == -1)) log_fatal ("no file descriptor for file passed to gnupg_spawn_process\n"); if (pipe (rp) == -1) diff --git a/common/exechelp-w32.c b/common/exechelp-w32.c index ed026e2ba..4616bec33 100644 --- a/common/exechelp-w32.c +++ b/common/exechelp-w32.c @@ -382,17 +382,30 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], int cr_flags; char *cmdline; int fd, fdout, rp[2]; + HANDLE nullhd[]; + int i; (void)preexec; /* Setup return values. */ *statusfile = NULL; *pid = (pid_t)(-1); - es_fflush (infile); - es_rewind (infile); - fd = _get_osfhandle (es_fileno (infile)); - fdout = _get_osfhandle (es_fileno (outfile)); - if (fd == -1 || fdout == -1) + + if (infile) + { + es_fflush (infile); + es_rewind (infile); + fd = _get_osfhandle (es_fileno (infile)); + } + else + fd = -1; + + if (outfile) + fdout = _get_osfhandle (es_fileno (outfile)); + else + fdout = -1; + + if ( (infile && fd == -1) || (outfile && fdout == -1)) log_fatal ("no file descriptor for file passed to gnupg_spawn_process\n"); /* Prepare security attributes. */ @@ -414,14 +427,17 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], return err; } + nullhd[0] = fd == -1? w32_open_null (0) : INVALID_HANDLE_VALUE; + nullhd[1] = outfd == -1? w32_open_null (1) : INVALID_HANDLE_VALUE; + /* Start the process. Note that we can't run the PREEXEC function because this would change our own environment. */ memset (&si, 0, sizeof si); si.cb = sizeof (si); si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; si.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_MINIMIZE; - si.hStdInput = fd_to_handle (fd); - si.hStdOutput = fd_to_handle (fdout); + si.hStdInput = fd == -1? nullhd[0] : fd_to_handle (fd); + si.hStdOutput = outfd == -1? nullhd[1] : fd_to_handle (fdout); si.hStdError = fd_to_handle (rp[1]); cr_flags = (CREATE_DEFAULT_ERROR_MODE @@ -450,6 +466,11 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], xfree (cmdline); cmdline = NULL; + /* Close the inherited handles to /dev/null. */ + for (i=0; i < DIM (nullhd); i++) + if (nullhd[i] != INVALID_HANDLE_VALUE) + CloseHandle (nullhd[i]); + /* Close the other end of the pipe. */ CloseHandle (fd_to_handle (rp[1])); diff --git a/common/exechelp-w32ce.c b/common/exechelp-w32ce.c index 809641c3e..d206052b5 100644 --- a/common/exechelp-w32ce.c +++ b/common/exechelp-w32ce.c @@ -501,6 +501,11 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], *statusfile = NULL; *pid = (pid_t)(-1); + /* A NULL INFILE or OUTFILE is only used by gpgtar thus we don't + need to implement this for CE. */ + if (!infile || !outfile) + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + es_fflush (infile); es_rewind (infile); diff --git a/common/exechelp.h b/common/exechelp.h index 168e779ba..56d0c1b9a 100644 --- a/common/exechelp.h +++ b/common/exechelp.h @@ -53,13 +53,14 @@ gpg_error_t gnupg_create_outbound_pipe (int filedes[2]); /* Fork and exec the PGMNAME, connect the file descriptor of INFILE to - stdin, write the output to OUTFILE, return a new stream in - STATUSFILE for stderr and the pid of the process in PID. The - arguments for the process are expected in the NULL terminated array - ARGV. The program name itself should not be included there. If - PREEXEC is not NULL, that function will be called right before the - exec. Calling gnupg_wait_process is required. Returns 0 on - success or an error code. + stdin, write the output to OUTFILE. INFILE or PUTFILE may be NULL + to connect thenm to /dev/null. Returns a new stream in STATUSFILE + for stderr and the pid of the process in PID. The arguments for the + process are expected in the NULL terminated array ARGV. The + program name itself should not be included there. If PREEXEC is + not NULL, that function will be called right before the exec. + Calling gnupg_wait_process is required. Returns 0 on success or an + error code. FLAGS is a bit vector: diff --git a/common/logging.c b/common/logging.c index f014d9fca..f9ac69202 100644 --- a/common/logging.c +++ b/common/logging.c @@ -402,7 +402,11 @@ log_get_fd () estream_t log_get_stream () { - assert (logstream); + if (!logstream) + { + log_set_file (NULL); /* Make sure a log stream has been set. */ + assert (logstream); + } return logstream; } |