summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/Makefile.am4
-rw-r--r--src/common/compat.c32
-rw-r--r--src/common/compat.h23
-rw-r--r--src/common/compat_libevent.c2
-rw-r--r--src/common/compat_libevent.h4
-rw-r--r--src/common/container.c2
-rw-r--r--src/common/crypto.c12
-rw-r--r--src/common/crypto.h1
-rw-r--r--src/common/log.c2
-rw-r--r--src/common/procmon.c336
-rw-r--r--src/common/procmon.h30
-rw-r--r--src/common/torlog.h1
-rw-r--r--src/common/util.c28
-rw-r--r--src/common/util.h4
14 files changed, 439 insertions, 42 deletions
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index 2d009bd4fa..6952591d67 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -12,11 +12,11 @@ libor_extra_source=
endif
libor_a_SOURCES = address.c log.c util.c compat.c container.c mempool.c \
- memarea.c di_ops.c util_codedigest.c $(libor_extra_source)
+ memarea.c di_ops.c procmon.c util_codedigest.c $(libor_extra_source)
libor_crypto_a_SOURCES = crypto.c aes.c tortls.c torgzip.c
libor_event_a_SOURCES = compat_libevent.c
-noinst_HEADERS = address.h torlog.h crypto.h util.h compat.h aes.h torint.h tortls.h strlcpy.c strlcat.c torgzip.h container.h ht.h mempool.h memarea.h ciphers.inc compat_libevent.h tortls_states.h di_ops.h
+noinst_HEADERS = address.h torlog.h crypto.h util.h compat.h aes.h torint.h tortls.h strlcpy.c strlcat.c torgzip.h container.h ht.h mempool.h memarea.h ciphers.inc compat_libevent.h tortls_states.h di_ops.h procmon.h
common_sha1.i: $(libor_SOURCES) $(libor_crypto_a_SOURCES) $(noinst_HEADERS)
if test "@SHA1SUM@" != none; then \
diff --git a/src/common/compat.c b/src/common/compat.c
index fc066da681..9377959eb4 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -841,7 +841,7 @@ socket_accounting_unlock(void)
* Windows, where close()ing a socket doesn't work. Returns 0 on success, -1
* on failure. */
int
-tor_close_socket(int s)
+tor_close_socket(tor_socket_t s)
{
int r = 0;
@@ -894,8 +894,10 @@ tor_close_socket(int s)
/** Helper: if DEBUG_SOCKET_COUNTING is enabled, remember that <b>s</b> is
* now an open socket. */
static INLINE void
-mark_socket_open(int s)
+mark_socket_open(tor_socket_t s)
{
+ /* XXXX This bitarray business will NOT work on windows: sockets aren't
+ small ints there. */
if (s > max_socket) {
if (max_socket == -1) {
open_sockets = bitarray_init_zero(s+128);
@@ -917,11 +919,11 @@ mark_socket_open(int s)
/** @} */
/** As socket(), but counts the number of open sockets. */
-int
+tor_socket_t
tor_open_socket(int domain, int type, int protocol)
{
- int s = socket(domain, type, protocol);
- if (s >= 0) {
+ tor_socket_t s = socket(domain, type, protocol);
+ if (SOCKET_OK(s)) {
socket_accounting_lock();
++n_sockets_open;
mark_socket_open(s);
@@ -931,11 +933,11 @@ tor_open_socket(int domain, int type, int protocol)
}
/** As socket(), but counts the number of open sockets. */
-int
+tor_socket_t
tor_accept_socket(int sockfd, struct sockaddr *addr, socklen_t *len)
{
- int s = accept(sockfd, addr, len);
- if (s >= 0) {
+ tor_socket_t s = accept(sockfd, addr, len);
+ if (SOCKET_OK(s)) {
socket_accounting_lock();
++n_sockets_open;
mark_socket_open(s);
@@ -958,7 +960,7 @@ get_n_open_sockets(void)
/** Turn <b>socket</b> into a nonblocking socket.
*/
void
-set_socket_nonblocking(int socket)
+set_socket_nonblocking(tor_socket_t socket)
{
#if defined(MS_WINDOWS)
unsigned long nonblocking = 1;
@@ -986,7 +988,7 @@ set_socket_nonblocking(int socket)
**/
/* It would be nicer just to set errno, but that won't work for windows. */
int
-tor_socketpair(int family, int type, int protocol, int fd[2])
+tor_socketpair(int family, int type, int protocol, tor_socket_t fd[2])
{
//don't use win32 socketpairs (they are always bad)
#if defined(HAVE_SOCKETPAIR) && !defined(MS_WINDOWS)
@@ -1011,9 +1013,9 @@ tor_socketpair(int family, int type, int protocol, int fd[2])
* for now, and really, when localhost is down sometimes, we
* have other problems too.
*/
- int listener = -1;
- int connector = -1;
- int acceptor = -1;
+ tor_socket_t listener = -1;
+ tor_socket_t connector = -1;
+ tor_socket_t acceptor = -1;
struct sockaddr_in listen_addr;
struct sockaddr_in connect_addr;
int size;
@@ -2577,11 +2579,11 @@ in_main_thread(void)
*/
#if defined(MS_WINDOWS)
int
-tor_socket_errno(int sock)
+tor_socket_errno(tor_socket_t sock)
{
int optval, optvallen=sizeof(optval);
int err = WSAGetLastError();
- if (err == WSAEWOULDBLOCK && sock >= 0) {
+ if (err == WSAEWOULDBLOCK && SOCKET_OK(sock)) {
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)&optval, &optvallen))
return err;
if (optval)
diff --git a/src/common/compat.h b/src/common/compat.h
index eff51ab30c..eb79b04449 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -390,15 +390,24 @@ int tor_fd_seekend(int fd);
typedef int socklen_t;
#endif
-int tor_close_socket(int s);
-int tor_open_socket(int domain, int type, int protocol);
-int tor_accept_socket(int sockfd, struct sockaddr *addr, socklen_t *len);
+#ifdef MS_WINDOWS
+#define tor_socket_t intptr_t
+#define SOCKET_OK(s) ((s) != INVALID_SOCKET)
+#else
+#define tor_socket_t int
+#define SOCKET_OK(s) ((s) >= 0)
+#endif
+
+int tor_close_socket(tor_socket_t s);
+tor_socket_t tor_open_socket(int domain, int type, int protocol);
+tor_socket_t tor_accept_socket(int sockfd, struct sockaddr *addr,
+ socklen_t *len);
int get_n_open_sockets(void);
#define tor_socket_send(s, buf, len, flags) send(s, buf, len, flags)
#define tor_socket_recv(s, buf, len, flags) recv(s, buf, len, flags)
-/** Implementatino of struct in6_addr for platforms that do not have it.
+/** Implementation of struct in6_addr for platforms that do not have it.
* Generally, these platforms are ones without IPv6 support, but we want to
* have a working in6_addr there anyway, so we can use it to parse IPv6
* addresses. */
@@ -464,8 +473,8 @@ int tor_inet_aton(const char *cp, struct in_addr *addr) ATTR_NONNULL((1,2));
const char *tor_inet_ntop(int af, const void *src, char *dst, size_t len);
int tor_inet_pton(int af, const char *src, void *dst);
int tor_lookup_hostname(const char *name, uint32_t *addr) ATTR_NONNULL((1,2));
-void set_socket_nonblocking(int socket);
-int tor_socketpair(int family, int type, int protocol, int fd[2]);
+void set_socket_nonblocking(tor_socket_t socket);
+int tor_socketpair(int family, int type, int protocol, tor_socket_t fd[2]);
int network_init(void);
/* For stupid historical reasons, windows sockets have an independent
@@ -492,7 +501,7 @@ int network_init(void);
((e) == WSAEMFILE || (e) == WSAENOBUFS)
/** Return true if e is EADDRINUSE or the local equivalent. */
#define ERRNO_IS_EADDRINUSE(e) ((e) == WSAEADDRINUSE)
-int tor_socket_errno(int sock);
+int tor_socket_errno(tor_socket_t sock);
const char *tor_socket_strerror(int e);
#else
#define ERRNO_IS_EAGAIN(e) ((e) == EAGAIN)
diff --git a/src/common/compat_libevent.c b/src/common/compat_libevent.c
index 3ad9be145d..6d89be804b 100644
--- a/src/common/compat_libevent.c
+++ b/src/common/compat_libevent.c
@@ -48,7 +48,7 @@ typedef uint32_t le_version_t;
* it is. */
#define LE_OLD V(0,0,0)
/** Represents a version of libevent so weird we can't figure out what version
- * it it. */
+ * it is. */
#define LE_OTHER V(0,0,99)
static le_version_t tor_get_libevent_version(const char **v_out);
diff --git a/src/common/compat_libevent.h b/src/common/compat_libevent.h
index fdf5e0a18f..1decc8d5f9 100644
--- a/src/common/compat_libevent.h
+++ b/src/common/compat_libevent.h
@@ -9,11 +9,15 @@
struct event;
struct event_base;
+
#ifdef HAVE_EVENT2_EVENT_H
#include <event2/util.h>
#else
+#ifndef EVUTIL_SOCKET_DEFINED
+#define EVUTIL_SOCKET_DEFINED
#define evutil_socket_t int
#endif
+#endif
void configure_libevent_logging(void);
void suppress_libevent_log_msg(const char *msg);
diff --git a/src/common/container.c b/src/common/container.c
index ca49cbb170..da44b7fe68 100644
--- a/src/common/container.c
+++ b/src/common/container.c
@@ -210,7 +210,7 @@ smartlist_string_isin_case(const smartlist_t *sl, const char *element)
int
smartlist_string_num_isin(const smartlist_t *sl, int num)
{
- char buf[16];
+ char buf[32]; /* long enough for 64-bit int, and then some. */
tor_snprintf(buf,sizeof(buf),"%d", num);
return smartlist_string_isin(sl, buf);
}
diff --git a/src/common/crypto.c b/src/common/crypto.c
index ff117e929f..1ecc24ce23 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -733,6 +733,18 @@ crypto_pk_key_is_private(const crypto_pk_env_t *key)
return PRIVATE_KEY_OK(key);
}
+/** Return true iff <b>env</b> contains a public key whose public exponent
+ * equals 65537.
+ */
+int
+crypto_pk_public_exponent_ok(crypto_pk_env_t *env)
+{
+ tor_assert(env);
+ tor_assert(env->key);
+
+ return BN_is_word(env->key->e, 65537);
+}
+
/** Compare the public-key components of a and b. Return -1 if a\<b, 0
* if a==b, and 1 if a\>b.
*/
diff --git a/src/common/crypto.h b/src/common/crypto.h
index 05185f3f18..54c7a67a3b 100644
--- a/src/common/crypto.h
+++ b/src/common/crypto.h
@@ -122,6 +122,7 @@ size_t crypto_pk_keysize(crypto_pk_env_t *env);
crypto_pk_env_t *crypto_pk_dup_key(crypto_pk_env_t *orig);
crypto_pk_env_t *crypto_pk_copy_full(crypto_pk_env_t *orig);
int crypto_pk_key_is_private(const crypto_pk_env_t *key);
+int crypto_pk_public_exponent_ok(crypto_pk_env_t *env);
int crypto_pk_public_encrypt(crypto_pk_env_t *env, char *to, size_t tolen,
const char *from, size_t fromlen, int padding);
diff --git a/src/common/log.c b/src/common/log.c
index d14563c885..ac98f13539 100644
--- a/src/common/log.c
+++ b/src/common/log.c
@@ -390,7 +390,7 @@ logv(int severity, log_domain_mask_t domain, const char *funcname,
/** Output a message to the log. It gets logged to all logfiles that
* care about messages with <b>severity</b> in <b>domain</b>. The content
- * is formatted printf style basedc on <b>format</b> and extra arguments.
+ * is formatted printf-style based on <b>format</b> and extra arguments.
* */
void
tor_log(int severity, log_domain_mask_t domain, const char *format, ...)
diff --git a/src/common/procmon.c b/src/common/procmon.c
new file mode 100644
index 0000000000..8fcc1afb7c
--- /dev/null
+++ b/src/common/procmon.c
@@ -0,0 +1,336 @@
+
+/**
+ * \file procmon.c
+ * \brief Process-termination monitor functions
+ **/
+
+#include "procmon.h"
+
+#include "util.h"
+
+#ifdef HAVE_EVENT2_EVENT_H
+#include <event2/event.h>
+#else
+#include <event.h>
+#endif
+
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#ifdef MS_WINDOWS
+#include <windows.h>
+
+/* Windows does not define pid_t, but _getpid() returns an int. */
+typedef int pid_t;
+#endif
+
+/* Define to 1 if process-termination monitors on this OS and Libevent
+ version must poll for process termination themselves. */
+#define PROCMON_POLLS 1
+/* Currently we need to poll in some way on all systems. */
+
+#ifdef PROCMON_POLLS
+static void tor_process_monitor_poll_cb(evutil_socket_t unused1, short unused2,
+ void *procmon_);
+#endif
+
+/* This struct may contain pointers into the original process
+ * specifier string, but it should *never* contain anything which
+ * needs to be freed. */
+struct parsed_process_specifier_t {
+ pid_t pid;
+};
+
+/** Parse the process specifier given in <b>process_spec</b> into
+ * *<b>ppspec</b>. Return 0 on success; return -1 and store an error
+ * message into *<b>msg</b> on failure. The caller must not free the
+ * returned error message. */
+static int
+parse_process_specifier(const char *process_spec,
+ struct parsed_process_specifier_t *ppspec,
+ const char **msg)
+{
+ long pid_l;
+ int pid_ok = 0;
+ char *pspec_next;
+
+ /* If we're lucky, long will turn out to be large enough to hold a
+ * PID everywhere that Tor runs. */
+ pid_l = tor_parse_long(process_spec, 0, 1, LONG_MAX, &pid_ok, &pspec_next);
+
+ /* Reserve room in the ‘process specifier’ for additional
+ * (platform-specific) identifying information beyond the PID, to
+ * make our process-existence checks a bit less racy in a future
+ * version. */
+ if ((*pspec_next != 0) && (*pspec_next != ' ') && (*pspec_next != ':')) {
+ pid_ok = 0;
+ }
+
+ ppspec->pid = (pid_t)(pid_l);
+ if (!pid_ok || (pid_l != (long)(ppspec->pid))) {
+ *msg = "invalid PID";
+ goto err;
+ }
+
+ return 0;
+ err:
+ return -1;
+}
+
+struct tor_process_monitor_t {
+ /** Log domain for warning messages. */
+ log_domain_mask_t log_domain;
+
+ /** All systems: The best we can do in general is poll for the
+ * process's existence by PID periodically, and hope that the kernel
+ * doesn't reassign the same PID to another process between our
+ * polls. */
+ pid_t pid;
+
+#ifdef MS_WINDOWS
+ /** Windows-only: Should we poll hproc? If false, poll pid
+ * instead. */
+ int poll_hproc;
+
+ /** Windows-only: Get a handle to the process (if possible) and
+ * periodically check whether the process we have a handle to has
+ * ended. */
+ HANDLE hproc;
+ /* XXX023 We can and should have Libevent watch hproc for us,
+ * if/when some version of Libevent 2.x can be told to do so. */
+#endif
+
+ /* XXX023 On Linux, we can and should receive the 22nd
+ * (space-delimited) field (‘starttime’) of /proc/$PID/stat from the
+ * owning controller and store it, and poll once in a while to see
+ * whether it has changed -- if so, the kernel has *definitely*
+ * reassigned the owning controller's PID and we should exit. On
+ * FreeBSD, we can do the same trick using either the 8th
+ * space-delimited field of /proc/$PID/status on the seven FBSD
+ * systems whose admins have mounted procfs, or the start-time field
+ * of the process-information structure returned by kvmgetprocs() on
+ * any system. The latter is ickier. */
+ /* XXX023 On FreeBSD (and possibly other kqueue systems), we can and
+ * should arrange to receive EVFILT_PROC NOTE_EXIT notifications for
+ * pid, so we don't have to do such a heavyweight poll operation in
+ * order to avoid the PID-reassignment race condition. (We would
+ * still need to poll our own kqueue periodically until some version
+ * of Libevent 2.x learns to receive these events for us.) */
+
+ /** A Libevent event structure, to either poll for the process's
+ * existence or receive a notification when the process ends. */
+ struct event *e;
+
+ /** A callback to be called when the process ends. */
+ tor_procmon_callback_t cb;
+ void *cb_arg; /**< A user-specified pointer to be passed to cb. */
+};
+
+/** Verify that the process specifier given in <b>process_spec</b> is
+ * syntactically valid. Return 0 on success; return -1 and store an
+ * error message into *<b>msg</b> on failure. The caller must not
+ * free the returned error message. */
+int
+tor_validate_process_specifier(const char *process_spec,
+ const char **msg)
+{
+ struct parsed_process_specifier_t ppspec;
+
+ tor_assert(msg != NULL);
+ *msg = NULL;
+
+ return parse_process_specifier(process_spec, &ppspec, msg);
+}
+
+#ifdef HAVE_EVENT2_EVENT_H
+#define PERIODIC_TIMER_FLAGS EV_PERSIST
+#else
+#define PERIODIC_TIMER_FLAGS (0)
+#endif
+
+static struct timeval poll_interval_tv = {15, 0};
+/* Note: If you port this file to plain Libevent 2, you can make
+ * poll_interval_tv const. It has to be non-const here because in
+ * libevent 1.x, event_add expects a pointer to a non-const struct
+ * timeval. */
+
+/** Create a process-termination monitor for the process specifier
+ * given in <b>process_spec</b>. Return a newly allocated
+ * tor_process_monitor_t on success; return NULL and store an error
+ * message into *<b>msg</b> on failure. The caller must not free
+ * the returned error message.
+ *
+ * When the monitored process terminates, call
+ * <b>cb</b>(<b>cb_arg</b>).
+ */
+tor_process_monitor_t *
+tor_process_monitor_new(struct event_base *base,
+ const char *process_spec,
+ log_domain_mask_t log_domain,
+ tor_procmon_callback_t cb, void *cb_arg,
+ const char **msg)
+{
+ tor_process_monitor_t *procmon = tor_malloc(sizeof(tor_process_monitor_t));
+ struct parsed_process_specifier_t ppspec;
+
+ tor_assert(msg != NULL);
+ *msg = NULL;
+
+ if (procmon == NULL) {
+ *msg = "out of memory";
+ goto err;
+ }
+
+ procmon->log_domain = log_domain;
+
+ if (parse_process_specifier(process_spec, &ppspec, msg))
+ goto err;
+
+ procmon->pid = ppspec.pid;
+
+#ifdef MS_WINDOWS
+ procmon->hproc = OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE,
+ FALSE,
+ procmon->pid);
+
+ if (procmon->hproc != NULL) {
+ procmon->poll_hproc = 1;
+ log_info(procmon->log_domain, "Successfully opened handle to process %d; "
+ "monitoring it.",
+ (int)(procmon->pid));
+ } else {
+ /* If we couldn't get a handle to the process, we'll try again the
+ * first time we poll. */
+ log_info(procmon->log_domain, "Failed to open handle to process %d; will "
+ "try again later.",
+ (int)(procmon->pid));
+ }
+#endif
+
+ procmon->cb = cb;
+ procmon->cb_arg = cb_arg;
+
+#ifdef PROCMON_POLLS
+ procmon->e = tor_event_new(base, -1 /* no FD */, PERIODIC_TIMER_FLAGS,
+ tor_process_monitor_poll_cb, procmon);
+ /* Note: If you port this file to plain Libevent 2, check that
+ * procmon->e is non-NULL. We don't need to here because
+ * tor_evtimer_new never returns NULL. */
+
+ evtimer_add(procmon->e, &poll_interval_tv);
+#else
+#error OOPS?
+#endif
+
+ return procmon;
+ err:
+ tor_process_monitor_free(procmon);
+ return NULL;
+}
+
+#ifdef PROCMON_POLLS
+/** Libevent callback to poll for the existence of the process
+ * monitored by <b>procmon_</b>. */
+static void
+tor_process_monitor_poll_cb(evutil_socket_t unused1, short unused2,
+ void *procmon_)
+{
+ tor_process_monitor_t *procmon = (tor_process_monitor_t *)(procmon_);
+ int its_dead_jim;
+
+ (void)unused1; (void)unused2;
+
+ tor_assert(procmon != NULL);
+
+#ifdef MS_WINDOWS
+ if (procmon->poll_hproc) {
+ DWORD exit_code;
+ if (!GetExitCodeProcess(procmon->hproc, &exit_code)) {
+ char *errmsg = format_win32_error(GetLastError());
+ log_warn(procmon->log_domain, "Error \"%s\" occurred while polling "
+ "handle for monitored process %d; assuming it's dead."
+ errmsg, procmon->pid);
+ tor_free(errmsg);
+ its_dead_jim = 1;
+ } else {
+ its_dead_jim = (exit_code != STILL_ACTIVE);
+ }
+ } else {
+ /* All we can do is try to open the process, and look at the error
+ * code if it fails again. */
+ procmon->hproc = OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE,
+ FALSE,
+ procmon->pid);
+
+ if (procmon->hproc != NULL) {
+ log_info(procmon->log_domain, "Successfully opened handle to monitored "
+ "process %d.",
+ procmon->pid);
+ its_dead_jim = 0;
+ procmon->poll_hproc = 1;
+ } else {
+ DWORD err_code = GetLastError();
+ char *errmsg = format_win32_error(err_code);
+
+ /* When I tested OpenProcess's error codes on Windows 7, I
+ * received error code 5 (ERROR_ACCESS_DENIED) for PIDs of
+ * existing processes that I could not open and error code 87
+ * (ERROR_INVALID_PARAMETER) for PIDs that were not in use.
+ * Since the nonexistent-process error code is sane, I'm going
+ * to assume that all errors other than ERROR_INVALID_PARAMETER
+ * mean that the process we are monitoring is still alive. */
+ its_dead_jim = (err_code == ERROR_INVALID_PARAMETER);
+
+ if (!its_dead_jim)
+ log_info(procmon->log_domain, "Failed to open handle to monitored "
+ "process %d, and error code %d (%s) is not 'invalid "
+ "parameter' -- assuming the process is still alive.",
+ procmon->pid,
+ err_code, err_msg);
+
+ tor_free(err_msg);
+ }
+ }
+#else
+ /* Unix makes this part easy, if a bit racy. */
+ its_dead_jim = kill(procmon->pid, 0);
+ its_dead_jim = its_dead_jim && (errno == ESRCH);
+#endif
+
+ log(its_dead_jim ? LOG_NOTICE : LOG_INFO,
+ procmon->log_domain, "Monitored process %d is %s.",
+ (int)procmon->pid,
+ its_dead_jim ? "dead" : "still alive");
+
+ if (its_dead_jim) {
+ procmon->cb(procmon->cb_arg);
+#ifndef HAVE_EVENT2_EVENT_H
+ } else {
+ evtimer_add(procmon->e, &poll_interval_tv);
+#endif
+ }
+}
+#endif
+
+/** Free the process-termination monitor <b>procmon</b>. */
+void
+tor_process_monitor_free(tor_process_monitor_t *procmon)
+{
+ if (procmon == NULL)
+ return;
+
+#ifdef MS_WINDOWS
+ if (procmon->hproc != NULL)
+ CloseHandle(procmon->hproc);
+#endif
+
+ if (procmon->e != NULL)
+ tor_event_free(procmon->e);
+
+ tor_free(procmon);
+}
+
diff --git a/src/common/procmon.h b/src/common/procmon.h
new file mode 100644
index 0000000000..02eb2da61c
--- /dev/null
+++ b/src/common/procmon.h
@@ -0,0 +1,30 @@
+
+/**
+ * \file procmon.h
+ * \brief Headers for procmon.c
+ **/
+
+#ifndef TOR_PROCMON_H
+#define TOR_PROCMON_H
+
+#include "compat.h"
+#include "compat_libevent.h"
+
+#include "torlog.h"
+
+typedef struct tor_process_monitor_t tor_process_monitor_t;
+
+typedef void (*tor_procmon_callback_t)(void *);
+
+int tor_validate_process_specifier(const char *process_spec,
+ const char **msg);
+tor_process_monitor_t *tor_process_monitor_new(struct event_base *base,
+ const char *process_spec,
+ log_domain_mask_t log_domain,
+ tor_procmon_callback_t cb,
+ void *cb_arg,
+ const char **msg);
+void tor_process_monitor_free(tor_process_monitor_t *procmon);
+
+#endif
+
diff --git a/src/common/torlog.h b/src/common/torlog.h
index 000e32ddab..541a0d1738 100644
--- a/src/common/torlog.h
+++ b/src/common/torlog.h
@@ -146,7 +146,6 @@ void change_callback_log_severity(int loglevelMin, int loglevelMax,
void flush_pending_log_callbacks(void);
void log_set_application_name(const char *name);
-/* Outputs a message to stdout */
void tor_log(int severity, log_domain_mask_t domain, const char *format, ...)
CHECK_PRINTF(3,4);
#define log tor_log /* hack it so we don't conflict with log() as much */
diff --git a/src/common/util.c b/src/common/util.c
index 1bb116b212..6f323dd20c 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -775,13 +775,17 @@ tor_digest256_is_zero(const char *digest)
if (next) *next = endptr; \
return 0
-/** Extract a long from the start of s, in the given numeric base. If
- * there is unconverted data and next is provided, set *next to the
- * first unconverted character. An error has occurred if no characters
- * are converted; or if there are unconverted characters and next is NULL; or
- * if the parsed value is not between min and max. When no error occurs,
- * return the parsed value and set *ok (if provided) to 1. When an error
- * occurs, return 0 and set *ok (if provided) to 0.
+/** Extract a long from the start of <b>s</b>, in the given numeric
+ * <b>base</b>. If <b>base</b> is 0, <b>s</b> is parsed as a decimal,
+ * octal, or hex number in the syntax of a C integer literal. If
+ * there is unconverted data and <b>next</b> is provided, set
+ * *<b>next</b> to the first unconverted character. An error has
+ * occurred if no characters are converted; or if there are
+ * unconverted characters and <b>next</b> is NULL; or if the parsed
+ * value is not between <b>min</b> and <b>max</b>. When no error
+ * occurs, return the parsed value and set *<b>ok</b> (if provided) to
+ * 1. When an error occurs, return 0 and set *<b>ok</b> (if provided)
+ * to 0.
*/
long
tor_parse_long(const char *s, int base, long min, long max,
@@ -1568,7 +1572,7 @@ rate_limit_log(ratelim_t *lim, time_t now)
* was returned by open(). Return the number of bytes written, or -1
* on error. Only use if fd is a blocking fd. */
ssize_t
-write_all(int fd, const char *buf, size_t count, int isSocket)
+write_all(tor_socket_t fd, const char *buf, size_t count, int isSocket)
{
size_t written = 0;
ssize_t result;
@@ -1578,7 +1582,7 @@ write_all(int fd, const char *buf, size_t count, int isSocket)
if (isSocket)
result = tor_socket_send(fd, buf+written, count-written, 0);
else
- result = write(fd, buf+written, count-written);
+ result = write((int)fd, buf+written, count-written);
if (result<0)
return -1;
written += result;
@@ -1592,7 +1596,7 @@ write_all(int fd, const char *buf, size_t count, int isSocket)
* open(). Return the number of bytes read, or -1 on error. Only use
* if fd is a blocking fd. */
ssize_t
-read_all(int fd, char *buf, size_t count, int isSocket)
+read_all(tor_socket_t fd, char *buf, size_t count, int isSocket)
{
size_t numread = 0;
ssize_t result;
@@ -1604,7 +1608,7 @@ read_all(int fd, char *buf, size_t count, int isSocket)
if (isSocket)
result = tor_socket_recv(fd, buf+numread, count-numread, 0);
else
- result = read(fd, buf+numread, count-numread);
+ result = read((int)fd, buf+numread, count-numread);
if (result<0)
return -1;
else if (result == 0)
@@ -2092,7 +2096,7 @@ read_file_to_str(const char *filename, int flags, struct stat *stat_out)
int save_errno = errno;
if (errno == ENOENT && (flags & RFTS_IGNORE_MISSING))
severity = LOG_INFO;
- log_fn(severity, LD_FS,"Could not open \"%s\": %s ",filename,
+ log_fn(severity, LD_FS,"Could not open \"%s\": %s",filename,
strerror(errno));
errno = save_errno;
return NULL;
diff --git a/src/common/util.h b/src/common/util.h
index f32709accd..ebbcf78bdc 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -276,8 +276,8 @@ typedef struct ratelim_t {
char *rate_limit_log(ratelim_t *lim, time_t now);
/* File helpers */
-ssize_t write_all(int fd, const char *buf, size_t count, int isSocket);
-ssize_t read_all(int fd, char *buf, size_t count, int isSocket);
+ssize_t write_all(tor_socket_t fd, const char *buf, size_t count, int isSocket);
+ssize_t read_all(tor_socket_t fd, char *buf, size_t count, int isSocket);
/** Return values from file_status(); see that function's documentation
* for details. */