Looking at the tor daemon source code

Karl gmkarl at gmail.com
Mon Oct 12 15:36:04 PDT 2020

tor]$ grep -r 'main(' src/app
src/app/config/or_options_st.h:  int LogMessageDomains; /**< Boolean:
Should we log the domain(s) in which
src/app/main/main.c:/* Main entry point for the Tor process.  Called
from tor_main(), and by
src/app/main/main.c:tor_run_main(const tor_main_configuration_t *tor_cfg)
src/app/main/ntmain.c:static void nt_service_main(void);
src/app/main/ntmain.c:   *    from those given to main() function.
src/app/main/ntmain.c:      nt_service_main();
src/app/main/tor_main.c: * \brief Stub module containing a main() function.
src/app/main/tor_main.c: * tests, which have their own main()s, can
link against main.c.
src/app/main/tor_main.c:int tor_main(int argc, char *argv[]);
src/app/main/tor_main.c:/** We keep main() in a separate file so that
our unit tests can use
src/app/main/tor_main.c:main(int argc, char *argv[])
src/app/main/tor_main.c:  r = tor_main(argc, argv);
$ cat src/app/main/tor_main.c

This is likely the main entry code for Tor.  (Hey, tell me when it's
time to shut up, if you're a hacker.) These files are like the genes
of tor: they make it all work when you finally 'conceive' the tor
process by running it, the kernel having electronic sex (I'm a prude
myself) with the harddrive, sending its data regions through the
various processes of the system loader, until the kernel process grows
into a confused little application.  And they were handmade by
software developers like the famous Jacob Appelbaum, who is
unfortunately the same age as me!  He doesn't have _that_ big a beard,
but he does have glasses, so his beard is big enough to be a coder.

/* Copyright 2001-2004 Roger Dingledine.
 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
 * Copyright (c) 2007-2020, The Tor Project, Inc. */
/* See LICENSE for licensing information */
This stuff people put at the top of their source code to support
various lawyer heroes they know.  Often richard stallman gets a big
chunk up here.  Tor is kind and refers us to another file for details
rather than making us scroll past it all.

#include "orconfig.h"
#include <stdlib.h>
Header files.  orconfig.h looks like some of that system-specific
stuff that `./configure` might have generated.  The #ifdef/#endif's
basically indicate that ./configure can enable or disable the region
between them.  "stdlib" is used for a wide variety of functions.

 * \file tor_main.c
 * \brief Stub module containing a main() function.
 * We keep the main function in a separate module so that the unit
 * tests, which have their own main()s, can link against main.c.

int tor_main(int argc, char *argv[]);
This is a very clear description of the file we are looking at.  The
commenting style is well-accepted, and quite easy for developers to
look at it, because it is so normal.

The comment implies that the _real_ guts are going to be in main.c .
We can look at that file after this one.

/** We keep main() in a separate file so that our unit tests can use
 * functions from main.c.
main(int argc, char *argv[])
Here they said a very similar thing, but put the comment on the main
function instead of the tor_main function.  This is because
programmers can get very confused after spending their lives staring
at blinking rectangles instead of talking to other people.  It's
possible a software developer would only see the thing they are
looking for, and not the things around it!  Additionally, software
developers learn to be very obsessive compulsive about rigorous
consistency in the structures they design, because if they don't do
that when working inside a computer the computer can develop a bad
issue of smoke leaving its cpu.  Comments don't affect the cpu.

  int r;
This defines a variable "r", saying it is an integer, and that nobody
knows what it will be used for quite yet.

  int restart_count = getenv("TOR_DEBUG_RESTART") ? 1 : 0;
Here's that mysterious use of `<stdlib.h>`!  `getenv` is a function
from stdlib that gets a variable from the environment.  If this
feature is enabled, the user can set `TOR_DEBUG_RESTART` to control
the value of restart_count, _without changing or recompiling any
code_!  Miraculous!

  r = tor_main(argc, argv);
This hands off control of the system to the tor_main function and is
the _only thing_ actually being done here.  There's no need to look
any more at this file.  It's basically saying that `tor_main` is the
real `main`, over and over again.

tor]$ grep -r 'tor_main(' .
./ChangeLog:      return from the tor_main() function, rather than calling the
./ReleaseNotes:      return from the tor_main() function, rather than
calling the
./src/app/main/main.c:/* Main entry point for the Tor process.  Called
from tor_main(), and by
./src/app/main/tor_main.c:int tor_main(int argc, char *argv[]);
./src/app/main/tor_main.c:  r = tor_main(argc, argv);
./src/feature/api/tor_api.c:tor_main(int argc, char *argv[])
./src/feature/api/tor_api.h:int tor_main(int argc, char **argv);

`tor_main` appears to be in tor_api.c .  If you want to memorize the
basics of how tor works, that's the next file to look in.  That's all
for now, folks!

More information about the cypherpunks mailing list