summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2012-06-25 11:51:19 -0400
committerNick Mathewson <nickm@torproject.org>2012-06-25 11:51:19 -0400
commit2703e072a1056edd3b68a16e045175e5bd268301 (patch)
treede5e7855794f9fae8f663ce280d72c9d9f07e79d
parenta6688c574e569a2a018038414198ab440344ba95 (diff)
parentffd7189b3fc015ce47e6ab27ac85d4eab2183a2b (diff)
downloadtor-2703e072a1056edd3b68a16e045175e5bd268301.tar.gz
tor-2703e072a1056edd3b68a16e045175e5bd268301.zip
Merge remote-tracking branch 'public/bug6225' into maint-0.2.3
-rw-r--r--src/common/util.c34
-rw-r--r--src/common/util.h4
-rw-r--r--src/test/test_util.c16
3 files changed, 37 insertions, 17 deletions
diff --git a/src/common/util.c b/src/common/util.c
index cb8ff85b40..e5b51b9a94 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -3264,8 +3264,11 @@ format_hex_number_for_helper_exit_status(unsigned int x, char *buf,
* in the processs of starting the child process did the failure occur (see
* CHILD_STATE_* macros for definition), and SAVED_ERRNO is the value of
* errno when the failure occurred.
+ *
+ * On success return the number of characters added to hex_errno, not counting
+ * the terminating NUL; return -1 on error.
*/
-void
+int
format_helper_exit_status(unsigned char child_state, int saved_errno,
char *hex_errno)
{
@@ -3273,6 +3276,7 @@ format_helper_exit_status(unsigned char child_state, int saved_errno,
int written, left;
char *cur;
size_t i;
+ int res = -1;
/* Fill hex_errno with spaces, and a trailing newline (memset may
not be signal handler safe, so we can't use it) */
@@ -3343,6 +3347,8 @@ format_helper_exit_status(unsigned char child_state, int saved_errno,
*cur++ = '\n';
*cur++ = '\0';
+ res = cur - hex_errno - 1;
+
goto done;
err:
@@ -3353,7 +3359,7 @@ format_helper_exit_status(unsigned char child_state, int saved_errno,
*hex_errno = '\0';
done:
- return;
+ return res;
}
/* Maximum number of file descriptors, if we cannot get it via sysconf() */
@@ -3695,15 +3701,20 @@ tor_spawn_background(const char *const filename, const char **argv,
child_state = CHILD_STATE_FAILEXEC;
error:
- /* XXX: are we leaking fds from the pipe? */
+ {
+ /* XXX: are we leaking fds from the pipe? */
+ int n;
- format_helper_exit_status(child_state, errno, hex_errno);
+ n = format_helper_exit_status(child_state, errno, hex_errno);
- /* Write the error message. GCC requires that we check the return
- value, but there is nothing we can do if it fails */
- /* TODO: Don't use STDOUT, use a pipe set up just for this purpose */
- nbytes = write(STDOUT_FILENO, error_message, error_message_length);
- nbytes = write(STDOUT_FILENO, hex_errno, sizeof(hex_errno));
+ if (n >= 0) {
+ /* Write the error message. GCC requires that we check the return
+ value, but there is nothing we can do if it fails */
+ /* TODO: Don't use STDOUT, use a pipe set up just for this purpose */
+ nbytes = write(STDOUT_FILENO, error_message, error_message_length);
+ nbytes = write(STDOUT_FILENO, hex_errno, n);
+ }
+ }
(void) nbytes;
@@ -4375,7 +4386,10 @@ get_string_from_pipe(FILE *stream, char *buf_out, size_t count)
}
} else {
len = strlen(buf_out);
- tor_assert(len>0);
+ if (len == 0) {
+ /* this probably means we got a NUL at the start of the string. */
+ return IO_STREAM_EAGAIN;
+ }
if (buf_out[len - 1] == '\n') {
/* Remove the trailing newline */
diff --git a/src/common/util.h b/src/common/util.h
index 6b7c6fb623..a2ab0ccac8 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -473,8 +473,8 @@ void tor_process_handle_destroy(process_handle_t *process_handle,
int format_hex_number_for_helper_exit_status(unsigned int x, char *buf,
int max_len);
-void format_helper_exit_status(unsigned char child_state,
- int saved_errno, char *hex_errno);
+int format_helper_exit_status(unsigned char child_state,
+ int saved_errno, char *hex_errno);
/* Space for hex values of child state, a slash, saved_errno (with
leading minus) and newline (no null) */
diff --git a/src/test/test_util.c b/src/test/test_util.c
index d71d280fa3..fab95953bd 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -2138,28 +2138,34 @@ test_util_exit_status(void *ptr)
{
/* Leave an extra byte for a \0 so we can do string comparison */
char hex_errno[HEX_ERRNO_SIZE + 1];
+ int n;
(void)ptr;
clear_hex_errno(hex_errno);
- format_helper_exit_status(0, 0, hex_errno);
+ n = format_helper_exit_status(0, 0, hex_errno);
test_streq("0/0\n", hex_errno);
+ test_eq(n, strlen(hex_errno));
clear_hex_errno(hex_errno);
- format_helper_exit_status(0, 0x7FFFFFFF, hex_errno);
+ n = format_helper_exit_status(0, 0x7FFFFFFF, hex_errno);
test_streq("0/7FFFFFFF\n", hex_errno);
+ test_eq(n, strlen(hex_errno));
clear_hex_errno(hex_errno);
- format_helper_exit_status(0xFF, -0x80000000, hex_errno);
+ n = format_helper_exit_status(0xFF, -0x80000000, hex_errno);
test_streq("FF/-80000000\n", hex_errno);
+ test_eq(n, strlen(hex_errno));
clear_hex_errno(hex_errno);
- format_helper_exit_status(0x7F, 0, hex_errno);
+ n = format_helper_exit_status(0x7F, 0, hex_errno);
test_streq("7F/0\n", hex_errno);
+ test_eq(n, strlen(hex_errno));
clear_hex_errno(hex_errno);
- format_helper_exit_status(0x08, -0x242, hex_errno);
+ n = format_helper_exit_status(0x08, -0x242, hex_errno);
test_streq("8/-242\n", hex_errno);
+ test_eq(n, strlen(hex_errno));
done:
;