build: split the non-gui startup routines into a new file
This will allow each to have its own main(), meaning that we can build a common base client and simply link in the correct startup object to create the appropriate binary.
This commit is contained in:
parent
a9380c72be
commit
c862d2ff22
6 changed files with 144 additions and 138 deletions
136
src/bitcoind.cpp
Normal file
136
src/bitcoind.cpp
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||||
|
// Copyright (c) 2009-2012 The Bitcoin developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include "init.h"
|
||||||
|
#include "bitcoinrpc.h"
|
||||||
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
|
|
||||||
|
void DetectShutdownThread(boost::thread_group* threadGroup)
|
||||||
|
{
|
||||||
|
bool shutdown = ShutdownRequested();
|
||||||
|
// Tell the main threads to shutdown.
|
||||||
|
while (!shutdown)
|
||||||
|
{
|
||||||
|
MilliSleep(200);
|
||||||
|
shutdown = ShutdownRequested();
|
||||||
|
}
|
||||||
|
if (threadGroup)
|
||||||
|
threadGroup->interrupt_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Start
|
||||||
|
//
|
||||||
|
bool AppInit(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
boost::thread_group threadGroup;
|
||||||
|
boost::thread* detectShutdownThread = NULL;
|
||||||
|
|
||||||
|
bool fRet = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Parameters
|
||||||
|
//
|
||||||
|
// If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main()
|
||||||
|
ParseParameters(argc, argv);
|
||||||
|
if (!boost::filesystem::is_directory(GetDataDir(false)))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error: Specified directory does not exist\n");
|
||||||
|
Shutdown();
|
||||||
|
}
|
||||||
|
ReadConfigFile(mapArgs, mapMultiArgs);
|
||||||
|
|
||||||
|
if (mapArgs.count("-?") || mapArgs.count("--help"))
|
||||||
|
{
|
||||||
|
// First part of help message is specific to bitcoind / RPC client
|
||||||
|
std::string strUsage = _("Bitcoin version") + " " + FormatFullVersion() + "\n\n" +
|
||||||
|
_("Usage:") + "\n" +
|
||||||
|
" bitcoind [options] " + "\n" +
|
||||||
|
" bitcoind [options] <command> [params] " + _("Send command to -server or bitcoind") + "\n" +
|
||||||
|
" bitcoind [options] help " + _("List commands") + "\n" +
|
||||||
|
" bitcoind [options] help <command> " + _("Get help for a command") + "\n";
|
||||||
|
|
||||||
|
strUsage += "\n" + HelpMessage();
|
||||||
|
|
||||||
|
fprintf(stdout, "%s", strUsage.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Command-line RPC
|
||||||
|
for (int i = 1; i < argc; i++)
|
||||||
|
if (!IsSwitchChar(argv[i][0]) && !boost::algorithm::istarts_with(argv[i], "bitcoin:"))
|
||||||
|
fCommandLine = true;
|
||||||
|
|
||||||
|
if (fCommandLine)
|
||||||
|
{
|
||||||
|
int ret = CommandLineRPC(argc, argv);
|
||||||
|
exit(ret);
|
||||||
|
}
|
||||||
|
#if !defined(WIN32)
|
||||||
|
fDaemon = GetBoolArg("-daemon", false);
|
||||||
|
if (fDaemon)
|
||||||
|
{
|
||||||
|
// Daemonize
|
||||||
|
pid_t pid = fork();
|
||||||
|
if (pid < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (pid > 0) // Parent process, pid is child process id
|
||||||
|
{
|
||||||
|
CreatePidFile(GetPidFile(), pid);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Child process falls through to rest of initialization
|
||||||
|
|
||||||
|
pid_t sid = setsid();
|
||||||
|
if (sid < 0)
|
||||||
|
fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
detectShutdownThread = new boost::thread(boost::bind(&DetectShutdownThread, &threadGroup));
|
||||||
|
fRet = AppInit2(threadGroup);
|
||||||
|
}
|
||||||
|
catch (std::exception& e) {
|
||||||
|
PrintExceptionContinue(&e, "AppInit()");
|
||||||
|
} catch (...) {
|
||||||
|
PrintExceptionContinue(NULL, "AppInit()");
|
||||||
|
}
|
||||||
|
if (!fRet) {
|
||||||
|
if (detectShutdownThread)
|
||||||
|
detectShutdownThread->interrupt();
|
||||||
|
threadGroup.interrupt_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (detectShutdownThread)
|
||||||
|
{
|
||||||
|
detectShutdownThread->join();
|
||||||
|
delete detectShutdownThread;
|
||||||
|
detectShutdownThread = NULL;
|
||||||
|
}
|
||||||
|
Shutdown();
|
||||||
|
|
||||||
|
return fRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void noui_connect();
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
bool fRet = false;
|
||||||
|
|
||||||
|
// Connect bitcoind signal handlers
|
||||||
|
noui_connect();
|
||||||
|
|
||||||
|
fRet = AppInit(argc, argv);
|
||||||
|
|
||||||
|
if (fRet && fDaemon)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return (fRet ? 0 : 1);
|
||||||
|
}
|
134
src/init.cpp
134
src/init.cpp
|
@ -121,19 +121,6 @@ void Shutdown()
|
||||||
//
|
//
|
||||||
// Signal handlers are very limited in what they are allowed to do, so:
|
// Signal handlers are very limited in what they are allowed to do, so:
|
||||||
//
|
//
|
||||||
void DetectShutdownThread(boost::thread_group* threadGroup)
|
|
||||||
{
|
|
||||||
bool shutdown = ShutdownRequested();
|
|
||||||
// Tell the main threads to shutdown.
|
|
||||||
while (!shutdown)
|
|
||||||
{
|
|
||||||
MilliSleep(200);
|
|
||||||
shutdown = ShutdownRequested();
|
|
||||||
}
|
|
||||||
if (threadGroup)
|
|
||||||
threadGroup->interrupt_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
void HandleSIGTERM(int)
|
void HandleSIGTERM(int)
|
||||||
{
|
{
|
||||||
fRequestShutdown = true;
|
fRequestShutdown = true;
|
||||||
|
@ -144,127 +131,6 @@ void HandleSIGHUP(int)
|
||||||
fReopenDebugLog = true;
|
fReopenDebugLog = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Start
|
|
||||||
//
|
|
||||||
#if !defined(QT_GUI)
|
|
||||||
bool AppInit(int argc, char* argv[])
|
|
||||||
{
|
|
||||||
boost::thread_group threadGroup;
|
|
||||||
boost::thread* detectShutdownThread = NULL;
|
|
||||||
|
|
||||||
bool fRet = false;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Parameters
|
|
||||||
//
|
|
||||||
// If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main()
|
|
||||||
ParseParameters(argc, argv);
|
|
||||||
if (!boost::filesystem::is_directory(GetDataDir(false)))
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error: Specified directory does not exist\n");
|
|
||||||
Shutdown();
|
|
||||||
}
|
|
||||||
ReadConfigFile(mapArgs, mapMultiArgs);
|
|
||||||
|
|
||||||
if (mapArgs.count("-?") || mapArgs.count("--help"))
|
|
||||||
{
|
|
||||||
// First part of help message is specific to bitcoind / RPC client
|
|
||||||
std::string strUsage = _("Bitcoin version") + " " + FormatFullVersion() + "\n\n" +
|
|
||||||
_("Usage:") + "\n" +
|
|
||||||
" bitcoind [options] " + "\n" +
|
|
||||||
" bitcoind [options] <command> [params] " + _("Send command to -server or bitcoind") + "\n" +
|
|
||||||
" bitcoind [options] help " + _("List commands") + "\n" +
|
|
||||||
" bitcoind [options] help <command> " + _("Get help for a command") + "\n";
|
|
||||||
|
|
||||||
strUsage += "\n" + HelpMessage();
|
|
||||||
|
|
||||||
fprintf(stdout, "%s", strUsage.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Command-line RPC
|
|
||||||
for (int i = 1; i < argc; i++)
|
|
||||||
if (!IsSwitchChar(argv[i][0]) && !boost::algorithm::istarts_with(argv[i], "bitcoin:"))
|
|
||||||
fCommandLine = true;
|
|
||||||
|
|
||||||
if (fCommandLine)
|
|
||||||
{
|
|
||||||
int ret = CommandLineRPC(argc, argv);
|
|
||||||
exit(ret);
|
|
||||||
}
|
|
||||||
#if !defined(WIN32)
|
|
||||||
fDaemon = GetBoolArg("-daemon", false);
|
|
||||||
if (fDaemon)
|
|
||||||
{
|
|
||||||
// Daemonize
|
|
||||||
pid_t pid = fork();
|
|
||||||
if (pid < 0)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (pid > 0) // Parent process, pid is child process id
|
|
||||||
{
|
|
||||||
CreatePidFile(GetPidFile(), pid);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// Child process falls through to rest of initialization
|
|
||||||
|
|
||||||
pid_t sid = setsid();
|
|
||||||
if (sid < 0)
|
|
||||||
fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
detectShutdownThread = new boost::thread(boost::bind(&DetectShutdownThread, &threadGroup));
|
|
||||||
fRet = AppInit2(threadGroup);
|
|
||||||
}
|
|
||||||
catch (std::exception& e) {
|
|
||||||
PrintExceptionContinue(&e, "AppInit()");
|
|
||||||
} catch (...) {
|
|
||||||
PrintExceptionContinue(NULL, "AppInit()");
|
|
||||||
}
|
|
||||||
if (!fRet) {
|
|
||||||
if (detectShutdownThread)
|
|
||||||
detectShutdownThread->interrupt();
|
|
||||||
threadGroup.interrupt_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (detectShutdownThread)
|
|
||||||
{
|
|
||||||
detectShutdownThread->join();
|
|
||||||
delete detectShutdownThread;
|
|
||||||
detectShutdownThread = NULL;
|
|
||||||
}
|
|
||||||
Shutdown();
|
|
||||||
|
|
||||||
return fRet;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern void noui_connect();
|
|
||||||
int main(int argc, char* argv[])
|
|
||||||
{
|
|
||||||
bool fRet = false;
|
|
||||||
|
|
||||||
// Connect bitcoind signal handlers
|
|
||||||
noui_connect();
|
|
||||||
|
|
||||||
fRet = AppInit(argc, argv);
|
|
||||||
|
|
||||||
if (fRet && fDaemon)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return (fRet ? 0 : 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool static InitError(const std::string &str)
|
bool static InitError(const std::string &str)
|
||||||
{
|
{
|
||||||
uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_ERROR);
|
uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_ERROR);
|
||||||
|
|
|
@ -71,6 +71,7 @@ OBJS= \
|
||||||
obj/key.o \
|
obj/key.o \
|
||||||
obj/db.o \
|
obj/db.o \
|
||||||
obj/init.o \
|
obj/init.o \
|
||||||
|
obj/bitcoind.o \
|
||||||
obj/keystore.o \
|
obj/keystore.o \
|
||||||
obj/main.o \
|
obj/main.o \
|
||||||
obj/net.o \
|
obj/net.o \
|
||||||
|
@ -116,7 +117,7 @@ TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp))
|
||||||
obj-test/%.o: test/%.cpp $(HEADERS)
|
obj-test/%.o: test/%.cpp $(HEADERS)
|
||||||
$(CXX) -c $(TESTDEFS) $(xCXXFLAGS) -o $@ $<
|
$(CXX) -c $(TESTDEFS) $(xCXXFLAGS) -o $@ $<
|
||||||
|
|
||||||
test_bitcoin.exe: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%))
|
test_bitcoin.exe: $(TESTOBJS) $(filter-out obj/init.o obj/bitcoind.o,$(OBJS:obj/%=obj/%))
|
||||||
$(CXX) $(xCXXFLAGS) $(xLDFLAGS) -o $@ $(LIBPATHS) $^ -lboost_unit_test_framework-mt-s $(LIBS)
|
$(CXX) $(xCXXFLAGS) $(xLDFLAGS) -o $@ $(LIBPATHS) $^ -lboost_unit_test_framework-mt-s $(LIBS)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,7 @@ OBJS= \
|
||||||
obj/key.o \
|
obj/key.o \
|
||||||
obj/db.o \
|
obj/db.o \
|
||||||
obj/init.o \
|
obj/init.o \
|
||||||
|
obj/bitcoind.o \
|
||||||
obj/keystore.o \
|
obj/keystore.o \
|
||||||
obj/main.o \
|
obj/main.o \
|
||||||
obj/net.o \
|
obj/net.o \
|
||||||
|
@ -127,7 +128,7 @@ TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp))
|
||||||
obj-test/%.o: test/%.cpp $(HEADERS)
|
obj-test/%.o: test/%.cpp $(HEADERS)
|
||||||
$(CXX) -c $(TESTDEFS) $(CFLAGS) -o $@ $<
|
$(CXX) -c $(TESTDEFS) $(CFLAGS) -o $@ $<
|
||||||
|
|
||||||
test_bitcoin.exe: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%))
|
test_bitcoin.exe: $(TESTOBJS) $(filter-out obj/init.o obj/bitcoind.o,$(OBJS:obj/%=obj/%))
|
||||||
$(CXX) $(CFLAGS) $(LDFLAGS) -o $@ $(LIBPATHS) $^ -lboost_unit_test_framework$(BOOST_SUFFIX) $(LIBS)
|
$(CXX) $(CFLAGS) $(LDFLAGS) -o $@ $(LIBPATHS) $^ -lboost_unit_test_framework$(BOOST_SUFFIX) $(LIBS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
|
|
@ -82,6 +82,7 @@ OBJS= \
|
||||||
obj/key.o \
|
obj/key.o \
|
||||||
obj/db.o \
|
obj/db.o \
|
||||||
obj/init.o \
|
obj/init.o \
|
||||||
|
obj/bitcoind.o \
|
||||||
obj/keystore.o \
|
obj/keystore.o \
|
||||||
obj/main.o \
|
obj/main.o \
|
||||||
obj/net.o \
|
obj/net.o \
|
||||||
|
@ -162,7 +163,7 @@ obj-test/%.o: test/%.cpp
|
||||||
-e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
|
-e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
|
||||||
rm -f $(@:%.o=%.d)
|
rm -f $(@:%.o=%.d)
|
||||||
|
|
||||||
test_bitcoin: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%))
|
test_bitcoin: $(TESTOBJS) $(filter-out obj/init.o obj/bitcoind.o,$(OBJS:obj/%=obj/%))
|
||||||
$(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) $(TESTLIBS)
|
$(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) $(TESTLIBS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
|
|
@ -121,6 +121,7 @@ OBJS= \
|
||||||
obj/key.o \
|
obj/key.o \
|
||||||
obj/db.o \
|
obj/db.o \
|
||||||
obj/init.o \
|
obj/init.o \
|
||||||
|
obj/bitcoind.o \
|
||||||
obj/keystore.o \
|
obj/keystore.o \
|
||||||
obj/main.o \
|
obj/main.o \
|
||||||
obj/net.o \
|
obj/net.o \
|
||||||
|
@ -187,7 +188,7 @@ obj-test/%.o: test/%.cpp
|
||||||
-e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
|
-e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
|
||||||
rm -f $(@:%.o=%.d)
|
rm -f $(@:%.o=%.d)
|
||||||
|
|
||||||
test_bitcoin: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%))
|
test_bitcoin: $(TESTOBJS) $(filter-out obj/init.o obj/bitcoind.o,$(OBJS:obj/%=obj/%))
|
||||||
$(LINK) $(xCXXFLAGS) -o $@ $(LIBPATHS) $^ $(TESTLIBS) $(xLDFLAGS) $(LIBS)
|
$(LINK) $(xCXXFLAGS) -o $@ $(LIBPATHS) $^ $(TESTLIBS) $(xLDFLAGS) $(LIBS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
|
Loading…
Reference in a new issue