[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [tor/master] Merge remote-tracking branch 'public/bug3122_memcmp_022' into bug3122_memcmp_023
commit 9fba014e3f7f89520841b65b8b038e5fb931b1d6
Merge: 6d5478a 8fb3833
Author: Nick Mathewson <nickm@xxxxxxxxxxxxxx>
Date: Wed May 11 16:39:45 2011 -0400
Merge remote-tracking branch 'public/bug3122_memcmp_022' into bug3122_memcmp_023
Conflicts in various places, mainly node-related. Resolved them in
favor of HEAD, with copying of tor_mem* operations from bug3122_memcmp_022.
src/common/Makefile.am
src/or/circuitlist.c
src/or/connection_edge.c
src/or/directory.c
src/or/microdesc.c
src/or/networkstatus.c
src/or/router.c
src/or/routerlist.c
src/test/test_util.c
changes/bug3122_memcmp | 7 +++
configure.in | 18 ++++++
src/common/Makefile.am | 2 +
src/common/address.c | 2 +-
src/common/compat.c | 4 +-
src/common/container.c | 10 ++--
src/common/container.h | 4 +-
src/common/crypto.c | 2 +-
src/common/di_ops.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++
src/common/di_ops.h | 30 ++++++++++
src/common/torgzip.c | 2 +-
src/common/util.c | 21 +++++---
src/common/util.h | 5 +-
src/or/circuitbuild.c | 12 ++--
src/or/circuitlist.c | 10 ++--
src/or/circuituse.c | 2 +-
src/or/connection_edge.c | 4 +-
src/or/connection_or.c | 10 ++--
src/or/control.c | 14 +++---
src/or/directory.c | 10 ++--
src/or/dirserv.c | 12 ++--
src/or/dirvote.c | 40 +++++++-------
src/or/eventdns.c | 4 +-
src/or/microdesc.c | 4 +-
src/or/networkstatus.c | 40 +++++++-------
src/or/onion.c | 4 +-
src/or/relay.c | 2 +-
src/or/rendclient.c | 6 +-
src/or/rendcommon.c | 8 ++--
src/or/rendmid.c | 2 +-
src/or/rendservice.c | 16 +++---
src/or/rephist.c | 4 +-
src/or/router.c | 6 +-
src/or/routerlist.c | 66 +++++++++++-----------
src/or/routerparse.c | 33 ++++++------
src/test/test_util.c | 55 +++++++++++++++++++
36 files changed, 429 insertions(+), 175 deletions(-)
diff --cc src/common/Makefile.am
index 20e3f5a,2d009bd..3a80eb8
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@@ -11,44 -11,12 +11,46 @@@ els
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)
-libor_crypto_a_SOURCES = crypto.c aes.c tortls.c torgzip.c
+libor_a_SOURCES = \
+ address.c \
+ compat.c \
+ container.c \
++ di_ops.c \
+ log.c \
+ memarea.c \
+ mempool.c \
+ util.c \
+ util_codedigest.c \
+ $(libor_extra_source)
+
+libor_crypto_a_SOURCES = \
+ aes.c \
+ crypto.c \
+ torgzip.c \
+ tortls.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 \
+ aes.h \
+ ciphers.inc \
+ compat.h \
+ compat_libevent.h \
+ container.h \
+ crypto.h \
++ di_ops.h \
+ ht.h \
+ memarea.h \
+ mempool.h \
+ strlcat.c \
+ strlcpy.c \
+ torgzip.h \
+ torint.h \
+ torlog.h \
+ tortls.h \
+ tortls_states.h \
+ util.h
common_sha1.i: $(libor_SOURCES) $(libor_crypto_a_SOURCES) $(noinst_HEADERS)
if test "@SHA1SUM@" != none; then \
diff --cc src/or/circuitlist.c
index 0aadcbf,8ec4618..7c5fd25
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@@ -1003,10 -1005,10 +1003,10 @@@ circuit_find_to_cannibalize(uint8_t pur
if (info) {
/* need to make sure we don't duplicate hops */
crypt_path_t *hop = circ->cpath;
- routerinfo_t *ri1 = router_get_by_digest(info->identity_digest);
+ const node_t *ri1 = node_get_by_id(info->identity_digest);
do {
- routerinfo_t *ri2;
+ const node_t *ri2;
- if (!memcmp(hop->extend_info->identity_digest,
+ if (tor_memeq(hop->extend_info->identity_digest,
info->identity_digest, DIGEST_LEN))
goto next;
if (ri1 &&
diff --cc src/or/connection_edge.c
index 4e45cbe,037920b..186137b
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@@ -3070,10 -3059,10 +3070,10 @@@ connection_ap_can_use_exit(edge_connect
* make sure the exit node of the existing circuit matches exactly.
*/
if (conn->chosen_exit_name) {
- routerinfo_t *chosen_exit =
- router_get_by_nickname(conn->chosen_exit_name, 1);
- if (!chosen_exit || tor_memneq(chosen_exit->cache_info.identity_digest,
- exit->cache_info.identity_digest, DIGEST_LEN)) {
+ const node_t *chosen_exit =
+ node_get_by_nickname(conn->chosen_exit_name, 1);
- if (!chosen_exit || memcmp(chosen_exit->identity,
++ if (!chosen_exit || tor_memneq(chosen_exit->identity,
+ exit->identity, DIGEST_LEN)) {
/* doesn't match */
// log_debug(LD_APP,"Requested node '%s', considering node '%s'. No.",
// conn->chosen_exit_name, exit->nickname);
diff --cc src/or/directory.c
index 313c6c5,309d997..56c4457
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@@ -3714,38 -3609,8 +3714,38 @@@ dir_routerdesc_download_failed(smartlis
* every 10 or 60 seconds (FOO_DESCRIPTOR_RETRY_INTERVAL) in main.c. */
}
+/* DOCDOC NM */
+static void
+dir_microdesc_download_failed(smartlist_t *failed,
+ int status_code)
+{
+ networkstatus_t *consensus
+ = networkstatus_get_latest_consensus_by_flavor(FLAV_MICRODESC);
+ routerstatus_t *rs;
+ download_status_t *dls;
+ time_t now = time(NULL);
+ int server = directory_fetches_from_authorities(get_options());
+
+ if (! consensus)
+ return;
+ SMARTLIST_FOREACH_BEGIN(failed, const char *, d) {
+ rs = router_get_mutable_consensus_status_by_descriptor_digest(consensus,d);
+ if (!rs)
+ continue;
+ dls = &rs->dl_status;
+ if (dls->n_download_failures >= MAX_MICRODESC_DOWNLOAD_FAILURES)
+ continue;
+ {
+ char buf[BASE64_DIGEST256_LEN+1];
+ digest256_to_base64(buf, d);
+ download_status_increment_failure(dls, status_code, buf,
+ server, now);
+ }
+ } SMARTLIST_FOREACH_END(d);
+}
+
- /** Helper. Compare two fp_pair_t objects, and return -1, 0, or 1 as
- * appropriate. */
+ /** Helper. Compare two fp_pair_t objects, and return negative, 0, or
+ * positive as appropriate. */
static int
_compare_pairs(const void **a, const void **b)
{
diff --cc src/or/microdesc.c
index 717488b,b87e0d9..f7f42a4
--- a/src/or/microdesc.c
+++ b/src/or/microdesc.c
@@@ -464,21 -414,7 +464,21 @@@ microdesc_cache_rebuild(microdesc_cache
SMARTLIST_FOREACH_BEGIN(wrote, microdesc_t *, md) {
tor_assert(md->saved_location == SAVED_IN_CACHE);
md->body = (char*)cache->cache_content->data + md->off;
- tor_assert(fast_memeq(md->body, "onion-key", 9));
+ if (PREDICT_UNLIKELY(
+ md->bodylen < 9 || memcmp(md->body, "onion-key", 9) != 0)) {
+ /* XXXX023 once bug 2022 is solved, we can kill this block and turn it
+ * into just the tor_assert(!memcmp) */
+ off_t avail = cache->cache_content->size - md->off;
+ char *bad_str;
+ tor_assert(avail >= 0);
+ bad_str = tor_strndup(md->body, MIN(128, (size_t)avail));
+ log_err(LD_BUG, "After rebuilding microdesc cache, offsets seem wrong. "
+ " At offset %d, I expected to find a microdescriptor starting "
+ " with \"onion-key\". Instead I got %s.",
+ (int)md->off, escaped(bad_str));
+ tor_free(bad_str);
- tor_assert(!memcmp(md->body, "onion-key", 9));
++ tor_assert(fast_memeq(md->body, "onion-key", 9));
+ }
} SMARTLIST_FOREACH_END(md);
smartlist_free(wrote);
diff --cc src/or/networkstatus.c
index 7fd3d36,1aa4e4a..837c8c2
--- a/src/or/networkstatus.c
+++ b/src/or/networkstatus.c
@@@ -939,12 -924,13 +939,12 @@@ compare_digest_to_routerstatus_entry(co
{
const char *key = _key;
const routerstatus_t *rs = *_member;
- return memcmp(key, rs->identity_digest, DIGEST_LEN);
+ return tor_memcmp(key, rs->identity_digest, DIGEST_LEN);
}
-/** Return the entry in <b>ns</b> for the identity digest <b>digest</b>, or
- * NULL if none was found. */
+/** As networkstatus_v2_find_entry, but do not return a const pointer */
routerstatus_t *
-networkstatus_v2_find_entry(networkstatus_v2_t *ns, const char *digest)
+networkstatus_v2_find_mutable_entry(networkstatus_v2_t *ns, const char *digest)
{
return smartlist_bsearch(ns->entries, digest,
compare_digest_to_routerstatus_entry);
@@@ -1519,14 -1493,13 +1519,14 @@@ notify_control_networkstatus_changed(co
}
changed = smartlist_create();
- SMARTLIST_FOREACH_JOIN(old_c->routerstatus_list, routerstatus_t *, rs_old,
- new_c->routerstatus_list, routerstatus_t *, rs_new,
- tor_memcmp(rs_old->identity_digest,
- rs_new->identity_digest, DIGEST_LEN),
- smartlist_add(changed, rs_new)) {
+ SMARTLIST_FOREACH_JOIN(
+ old_c->routerstatus_list, const routerstatus_t *, rs_old,
+ new_c->routerstatus_list, const routerstatus_t *, rs_new,
- memcmp(rs_old->identity_digest,
++ tor_memcmp(rs_old->identity_digest,
+ rs_new->identity_digest, DIGEST_LEN),
+ smartlist_add(changed, (void*) rs_new)) {
if (routerstatus_has_changed(rs_old, rs_new))
- smartlist_add(changed, rs_new);
+ smartlist_add(changed, (void*)rs_new);
} SMARTLIST_FOREACH_JOIN_END(rs_old, rs_new);
control_event_networkstatus_changed(changed);
@@@ -1550,9 -1523,10 +1550,9 @@@ networkstatus_copy_old_consensus_info(n
rs_new->identity_digest, DIGEST_LEN),
STMT_NIL) {
/* Okay, so we're looking at the same identity. */
- rs_new->name_lookup_warned = rs_old->name_lookup_warned;
rs_new->last_dir_503_at = rs_old->last_dir_503_at;
- if (!memcmp(rs_old->descriptor_digest, rs_new->descriptor_digest,
+ if (tor_memeq(rs_old->descriptor_digest, rs_new->descriptor_digest,
DIGEST_LEN)) {
/* And the same descriptor too! */
memcpy(&rs_new->dl_status, &rs_old->dl_status,sizeof(download_status_t));
@@@ -2003,11 -1957,12 +2003,11 @@@ routers_update_status_from_consensus_ne
SMARTLIST_FOREACH_JOIN(ns->routerstatus_list, routerstatus_t *, rs,
routers, routerinfo_t *, router,
- memcmp(rs->identity_digest,
+ tor_memcmp(rs->identity_digest,
router->cache_info.identity_digest, DIGEST_LEN),
{
+#if 0
/* We have no routerstatus for this router. Clear flags and skip it. */
- if (!namingdir)
- router->is_named = 0;
if (!authdir) {
if (router->purpose == ROUTER_PURPOSE_GENERAL)
router_clear_status_flags(router);
@@@ -2019,8 -1973,14 +2019,8 @@@
ds = router_get_trusteddirserver_by_digest(digest);
- if (!namingdir) {
- if (rs->is_named && !strcasecmp(router->nickname, rs->nickname))
- router->is_named = 1;
- else
- router->is_named = 0;
- }
/* Is it the same descriptor, or only the same identity? */
- if (!memcmp(router->cache_info.signed_descriptor_digest,
+ if (tor_memeq(router->cache_info.signed_descriptor_digest,
rs->descriptor_digest, DIGEST_LEN)) {
if (ns->valid_until > router->cache_info.last_listed_as_valid_until)
router->cache_info.last_listed_as_valid_until = ns->valid_until;
@@@ -2045,14 -2016,15 +2045,14 @@@
} SMARTLIST_FOREACH_JOIN_END(rs, router);
/* Now update last_listed_as_valid_until from v2 networkstatuses. */
- /* XXXX If this is slow, we need to rethink the code. */
SMARTLIST_FOREACH(networkstatus_v2_list, networkstatus_v2_t *, ns, {
time_t live_until = ns->published_on + V2_NETWORKSTATUS_ROUTER_LIFETIME;
- SMARTLIST_FOREACH_JOIN(ns->entries, routerstatus_t *, rs,
+ SMARTLIST_FOREACH_JOIN(ns->entries, const routerstatus_t *, rs,
routers, routerinfo_t *, ri,
- memcmp(rs->identity_digest,
+ tor_memcmp(rs->identity_digest,
ri->cache_info.identity_digest, DIGEST_LEN),
STMT_NIL) {
- if (!memcmp(ri->cache_info.signed_descriptor_digest,
+ if (tor_memeq(ri->cache_info.signed_descriptor_digest,
rs->descriptor_digest, DIGEST_LEN)) {
if (live_until > ri->cache_info.last_listed_as_valid_until)
ri->cache_info.last_listed_as_valid_until = live_until;
diff --cc src/or/router.c
index 6de069f,a7148ea..42b07cb
--- a/src/or/router.c
+++ b/src/or/router.c
@@@ -724,8 -721,8 +724,8 @@@ init_keys(void
type, ds->type);
ds->type = type;
}
- if (v3_digest_set && (ds->type & V3_AUTHORITY) &&
+ if (v3_digest_set && (ds->type & V3_DIRINFO) &&
- memcmp(v3_digest, ds->v3_identity_digest, DIGEST_LEN)) {
+ tor_memneq(v3_digest, ds->v3_identity_digest, DIGEST_LEN)) {
log_warn(LD_DIR, "V3 identity key does not match identity declared in "
"DirServer line. Adjusting.");
memcpy(ds->v3_identity_digest, v3_digest, DIGEST_LEN);
diff --cc src/or/routerlist.c
index 04f4214,6c649ab..8d25eaa
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@@ -1027,8 -1021,8 +1027,8 @@@ trusteddirserver_get_by_v3_auth_digest(
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
{
- if (!memcmp(ds->v3_identity_digest, digest, DIGEST_LEN) &&
+ if (tor_memeq(ds->v3_identity_digest, digest, DIGEST_LEN) &&
- (ds->type & V3_AUTHORITY))
+ (ds->type & V3_DIRINFO))
return ds;
});
@@@ -2280,19 -2265,9 +2280,19 @@@ hex_digest_nickname_matches(const char
return 0;
}
- return !memcmp(digest, identity_digest, DIGEST_LEN);
- if (base16_decode(digest, DIGEST_LEN, hexdigest, HEX_DIGEST_LEN)<0)
- return 0;
- return (tor_memeq(digest, identity_digest, DIGEST_LEN));
++ return tor_memeq(digest, identity_digest, DIGEST_LEN);
+}
+
+/* Return true iff <b>router</b> is listed as named in the current
+ * consensus. */
+static int
+router_is_named(const routerinfo_t *router)
+{
+ const char *digest =
+ networkstatus_get_router_digest_by_nickname(router->nickname);
+
+ return (digest &&
- !memcmp(digest, router->cache_info.identity_digest, DIGEST_LEN));
++ tor_memeq(digest, router->cache_info.identity_digest, DIGEST_LEN));
}
/** Return true iff the digest of <b>router</b>'s identity key,
@@@ -3224,23 -3205,23 +3224,23 @@@ router_set_status(const char *digest, i
tor_assert(digest);
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, d,
- if (!memcmp(d->digest, digest, DIGEST_LEN))
+ if (tor_memeq(d->digest, digest, DIGEST_LEN))
d->is_running = up);
- router = router_get_by_digest(digest);
- if (router) {
- log_debug(LD_DIR,"Marking router '%s/%s' as %s.",
- router->nickname, router->address, up ? "up" : "down");
- if (!up && router_is_me(router) && !we_are_hibernating())
+ node = node_get_mutable_by_id(digest);
+ if (node) {
+#if 0
+ char buf[MAX_VERBOSE_NICKNAME_LEN+1];
+ node_get_verbose_nickname(node,buf);
+ log_debug(LD_DIR,"Marking router %s as %s.",
+ buf, up ? "up" : "down");
+#endif
+ if (!up && node_is_me(node) && !we_are_hibernating())
log_warn(LD_NET, "We just marked ourself as down. Are your external "
"addresses reachable?");
- router->is_running = up;
- }
- status = router_get_consensus_status_by_id(digest);
- if (status && status->is_running != up) {
- status->is_running = up;
- control_event_networkstatus_changed_single(status);
+ node->is_running = up;
}
+
router_dir_info_changed();
}
@@@ -3347,16 -3328,15 +3347,16 @@@ router_add_to_routerlist(routerinfo_t *
SMARTLIST_FOREACH(networkstatus_v2_list, networkstatus_v2_t *, ns,
{
routerstatus_t *rs =
- networkstatus_v2_find_entry(ns, id_digest);
+ networkstatus_v2_find_mutable_entry(ns, id_digest);
- if (rs && !memcmp(rs->descriptor_digest,
+ if (rs && tor_memeq(rs->descriptor_digest,
router->cache_info.signed_descriptor_digest,
DIGEST_LEN))
rs->need_to_mirror = 0;
});
if (consensus) {
- routerstatus_t *rs = networkstatus_vote_find_entry(consensus, id_digest);
+ routerstatus_t *rs = networkstatus_vote_find_mutable_entry(
+ consensus, id_digest);
- if (rs && !memcmp(rs->descriptor_digest,
+ if (rs && tor_memeq(rs->descriptor_digest,
router->cache_info.signed_descriptor_digest,
DIGEST_LEN)) {
in_consensus = 1;
@@@ -4627,10 -4545,10 +4627,10 @@@ update_consensus_router_descriptor_down
is_vote ? &(((vote_routerstatus_t *)rsp)->status) : rsp;
signed_descriptor_t *sd;
if ((sd = router_get_by_descriptor_digest(rs->descriptor_digest))) {
- routerinfo_t *ri;
+ const routerinfo_t *ri;
++n_have;
- if (!(ri = router_get_by_digest(rs->identity_digest)) ||
+ if (!(ri = router_get_by_id_digest(rs->identity_digest)) ||
- memcmp(ri->cache_info.signed_descriptor_digest,
+ tor_memneq(ri->cache_info.signed_descriptor_digest,
sd->signed_descriptor_digest, DIGEST_LEN)) {
/* We have a descriptor with this digest, but either there is no
* entry in routerlist with the same ID (!ri), or there is one,
diff --cc src/test/test_util.c
index efbc47b,0da45df..f4b17c9
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@@ -1223,201 -1210,58 +1223,255 @@@ test_util_load_win_lib(void *ptr
#endif
static void
+clear_hex_errno(char *hex_errno)
+{
+ memset(hex_errno, '\0', HEX_ERRNO_SIZE + 1);
+}
+
+static void
+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];
+
+ (void)ptr;
+
+ clear_hex_errno(hex_errno);
+ format_helper_exit_status(0, 0, hex_errno);
+ tt_str_op(hex_errno, ==, " 0/0\n");
+
+ clear_hex_errno(hex_errno);
+ format_helper_exit_status(0, 0x7FFFFFFF, hex_errno);
+ tt_str_op(hex_errno, ==, " 0/7FFFFFFF\n");
+
+ clear_hex_errno(hex_errno);
+ format_helper_exit_status(0xFF, -0x80000000, hex_errno);
+ tt_str_op(hex_errno, ==, "FF/-80000000\n");
+
+ clear_hex_errno(hex_errno);
+ format_helper_exit_status(0x7F, 0, hex_errno);
+ tt_str_op(hex_errno, ==, " 7F/0\n");
+
+ clear_hex_errno(hex_errno);
+ format_helper_exit_status(0x08, -0x242, hex_errno);
+ tt_str_op(hex_errno, ==, " 8/-242\n");
+
+ done:
+ ;
+}
+
+#ifndef MS_WINDOWS
+/** Check that fgets waits until a full line, and not return a partial line, on
+ * a EAGAIN with a non-blocking pipe */
+static void
+test_util_fgets_eagain(void *ptr)
+{
+ int test_pipe[2] = {-1, -1};
+ int retval;
+ ssize_t retlen;
+ char *retptr;
+ FILE *test_stream = NULL;
+ char buf[10];
+
+ (void)ptr;
+
+ /* Set up a pipe to test on */
+ retval = pipe(test_pipe);
+ tt_int_op(retval, >=, 0);
+
+ /* Set up the read-end to be non-blocking */
+ retval = fcntl(test_pipe[0], F_SETFL, O_NONBLOCK);
+ tt_int_op(retval, >=, 0);
+
+ /* Open it as a stdio stream */
+ test_stream = fdopen(test_pipe[0], "r");
+ tt_ptr_op(test_stream, !=, NULL);
+
+ /* Send in a partial line */
+ retlen = write(test_pipe[1], "A", 1);
+ tt_int_op(retlen, ==, 1);
+ retptr = fgets(buf, sizeof(buf), test_stream);
+ tt_want(retptr == NULL);
+ tt_int_op(errno, ==, EAGAIN);
+
+ /* Send in the rest */
+ retlen = write(test_pipe[1], "B\n", 2);
+ tt_int_op(retlen, ==, 2);
+ retptr = fgets(buf, sizeof(buf), test_stream);
+ tt_ptr_op(retptr, ==, buf);
+ tt_str_op(buf, ==, "AB\n");
+
+ /* Send in a full line */
+ retlen = write(test_pipe[1], "CD\n", 3);
+ tt_int_op(retlen, ==, 3);
+ retptr = fgets(buf, sizeof(buf), test_stream);
+ tt_ptr_op(retptr, ==, buf);
+ tt_str_op(buf, ==, "CD\n");
+
+ /* Send in a partial line */
+ retlen = write(test_pipe[1], "E", 1);
+ tt_int_op(retlen, ==, 1);
+ retptr = fgets(buf, sizeof(buf), test_stream);
+ tt_ptr_op(retptr, ==, NULL);
+ tt_int_op(errno, ==, EAGAIN);
+
+ /* Send in the rest */
+ retlen = write(test_pipe[1], "F\n", 2);
+ tt_int_op(retlen, ==, 2);
+ retptr = fgets(buf, sizeof(buf), test_stream);
+ tt_ptr_op(retptr, ==, buf);
+ tt_str_op(buf, ==, "EF\n");
+
+ /* Send in a full line and close */
+ retlen = write(test_pipe[1], "GH", 2);
+ tt_int_op(retlen, ==, 2);
+ retval = close(test_pipe[1]);
+ test_pipe[1] = -1;
+ tt_int_op(retval, ==, 0);
+ retptr = fgets(buf, sizeof(buf), test_stream);
+ tt_ptr_op(retptr, ==, buf);
+ tt_str_op(buf, ==, "GH");
+
+ /* Check for EOF */
+ retptr = fgets(buf, sizeof(buf), test_stream);
+ tt_ptr_op(retptr, ==, NULL);
+ tt_int_op(feof(test_stream), >, 0);
+
+ done:
+ if (test_stream != NULL)
+ fclose(test_stream);
+ if (test_pipe[0] != -1)
+ close(test_pipe[0]);
+ if (test_pipe[1] != -1)
+ close(test_pipe[1]);
+}
+#endif
+
+#ifndef MS_WINDOWS
+/** Helper function for testing tor_spawn_background */
+static void
+run_util_spawn_background(const char *argv[], const char *expected_out,
+ const char *expected_err, int expected_exit)
+{
+ int stdout_pipe=-1, stderr_pipe=-1;
+ int retval, stat_loc;
+ pid_t pid;
+ ssize_t pos;
+ char stdout_buf[100], stderr_buf[100];
+
+ /* Start the program */
+ retval = tor_spawn_background(argv[0], &stdout_pipe, &stderr_pipe, argv);
+ tt_int_op(retval, >, 0);
+ tt_int_op(stdout_pipe, >, 0);
+ tt_int_op(stderr_pipe, >, 0);
+ pid = retval;
+
+ /* Check stdout */
+ pos = read_all(stdout_pipe, stdout_buf, sizeof(stdout_buf) - 1, 0);
+ stdout_buf[pos] = '\0';
+ tt_int_op(pos, ==, strlen(expected_out));
+ tt_str_op(stdout_buf, ==, expected_out);
+
+ /* Check it terminated correctly */
+ retval = waitpid(pid, &stat_loc, 0);
+ tt_int_op(retval, ==, pid);
+ tt_assert(WIFEXITED(stat_loc));
+ tt_int_op(WEXITSTATUS(stat_loc), ==, expected_exit);
+ tt_assert(!WIFSIGNALED(stat_loc));
+ tt_assert(!WIFSTOPPED(stat_loc));
+
+ /* Check stderr */
+ pos = read_all(stderr_pipe, stderr_buf, sizeof(stderr_buf) - 1, 0);
+ stderr_buf[pos] = '\0';
+ tt_int_op(pos, ==, strlen(expected_err));
+ tt_str_op(stderr_buf, ==, expected_err);
+
+ done:
+ ;
+}
+
+/** Check that we can launch a process and read the output */
+static void
+test_util_spawn_background_ok(void *ptr)
+{
+ const char *argv[] = {BUILDDIR "/src/test/test-child", "--test", NULL};
+ const char *expected_out = "OUT\n--test\nDONE\n";
+ const char *expected_err = "ERR\n";
+
+ (void)ptr;
+
+ run_util_spawn_background(argv, expected_out, expected_err, 0);
+}
+
+/** Check that failing to find the executable works as expected */
+static void
+test_util_spawn_background_fail(void *ptr)
+{
+ const char *argv[] = {BUILDDIR "/src/test/no-such-file", "--test", NULL};
+ const char *expected_out = "ERR: Failed to spawn background process "
+ "- code 9/2\n";
+ const char *expected_err = "";
+
+ (void)ptr;
+
+ run_util_spawn_background(argv, expected_out, expected_err, 255);
+}
+#endif
+
++
++static void
+ test_util_di_ops(void)
+ {
+ #define LT -1
+ #define GT 1
+ #define EQ 0
+ const struct {
+ const char *a; int want_sign; const char *b;
+ } examples[] = {
+ { "Foo", EQ, "Foo" },
+ { "foo", GT, "bar", },
+ { "foobar", EQ ,"foobar" },
+ { "foobar", LT, "foobaw" },
+ { "foobar", GT, "f00bar" },
+ { "foobar", GT, "boobar" },
+ { "", EQ, "" },
+ { NULL, 0, NULL },
+ };
+
+ int i;
+
+ for (i = 0; examples[i].a; ++i) {
+ size_t len = strlen(examples[i].a);
+ int eq1, eq2, neq1, neq2, cmp1, cmp2;
+ test_eq(len, strlen(examples[i].b));
+ /* We do all of the operations, with operands in both orders. */
+ eq1 = tor_memeq(examples[i].a, examples[i].b, len);
+ eq2 = tor_memeq(examples[i].b, examples[i].a, len);
+ neq1 = tor_memneq(examples[i].a, examples[i].b, len);
+ neq2 = tor_memneq(examples[i].b, examples[i].a, len);
+ cmp1 = tor_memcmp(examples[i].a, examples[i].b, len);
+ cmp2 = tor_memcmp(examples[i].b, examples[i].a, len);
+
+ /* Check for correctness of cmp1 */
+ if (cmp1 < 0 && examples[i].want_sign != LT)
+ test_fail();
+ else if (cmp1 > 0 && examples[i].want_sign != GT)
+ test_fail();
+ else if (cmp1 == 0 && examples[i].want_sign != EQ)
+ test_fail();
+
+ /* Check for consistency of everything else with cmp1 */
+ test_eq(eq1, eq2);
+ test_eq(neq1, neq2);
+ test_eq(cmp1, -cmp2);
+ test_eq(eq1, cmp1 == 0);
+ test_eq(neq1, !eq1);
+ }
+
+ done:
+ ;
+ }
+
#define UTIL_LEGACY(name) \
{ #name, legacy_test_helper, 0, &legacy_setup, test_util_ ## name }
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits