aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2010-06-07 13:33:02 +0000
committerWerner Koch <[email protected]>2010-06-07 13:33:02 +0000
commitbbe388b5db35be6ffece8ebd42f11372af016763 (patch)
tree73e1fe9697b969be66bd89953125010e5721efe1 /common
parentPrint --version etc via estream (diff)
downloadgnupg-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/ChangeLog21
-rw-r--r--common/estream.c89
-rw-r--r--common/estream.h5
-rw-r--r--common/exechelp-posix.c21
-rw-r--r--common/exechelp-w32.c35
-rw-r--r--common/exechelp-w32ce.c5
-rw-r--r--common/exechelp.h15
-rw-r--r--common/logging.c6
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;
}