Skip to content

Commit 34904a0

Browse files
sapiersapier
sapier
authored and
sapier
committedMay 31, 2014
Add daemon support for linux like operating systems
1 parent d76b8c6 commit 34904a0

File tree

3 files changed

+128
-8
lines changed

3 files changed

+128
-8
lines changed
 

Diff for: ‎src/main.cpp

+18-1
Original file line numberDiff line numberDiff line change
@@ -811,6 +811,9 @@ int main(int argc, char *argv[])
811811
_("Set password"))));
812812
allowed_options.insert(std::make_pair("go", ValueSpec(VALUETYPE_FLAG,
813813
_("Disable main menu"))));
814+
#else
815+
allowed_options.insert(std::make_pair("daemon", ValueSpec(VALUETYPE_FLAG,
816+
_("Daemonize minetestserver"))));
814817
#endif
815818

816819
Settings cmd_args;
@@ -918,6 +921,12 @@ int main(int argc, char *argv[])
918921
<<", "<<minetest_build_info
919922
<<std::endl;
920923

924+
#ifdef SERVER
925+
if (cmd_args.exists("daemon")) {
926+
porting::daemonize();
927+
}
928+
#endif
929+
921930
/*
922931
Basic initialization
923932
*/
@@ -1469,7 +1478,7 @@ int main(int argc, char *argv[])
14691478
ELL_ERROR,
14701479
ELL_WARNING,
14711480
ELL_INFORMATION,
1472-
#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
1481+
#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
14731482
ELL_INFORMATION
14741483
#else
14751484
ELL_DEBUG
@@ -1920,6 +1929,14 @@ int main(int argc, char *argv[])
19201929

19211930
debugstreams_deinit();
19221931

1932+
1933+
#ifdef SERVER
1934+
if (cmd_args.exists("daemon"))
1935+
{
1936+
porting::cleanup_pid();
1937+
}
1938+
#endif
1939+
19231940
return retval;
19241941
}
19251942

Diff for: ‎src/porting.cpp

+105-7
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
3333
#include <sys/sysctl.h>
3434
#elif defined(_WIN32)
3535
#include <algorithm>
36+
#elif defined(__LINUX)
37+
#include <sys/types.h>
3638
#endif
3739
#if !defined(_WIN32)
40+
#include <sys/stat.h>
3841
#include <unistd.h>
3942
#include <sys/utsname.h>
4043
#endif
@@ -137,7 +140,8 @@ void signal_handler_init(void)
137140
/*
138141
Multithreading support
139142
*/
140-
int getNumberOfProcessors() {
143+
int getNumberOfProcessors()
144+
{
141145
#if defined(_SC_NPROCESSORS_ONLN)
142146

143147
return sysconf(_SC_NPROCESSORS_ONLN);
@@ -170,7 +174,8 @@ int getNumberOfProcessors() {
170174
}
171175

172176

173-
bool threadBindToProcessor(threadid_t tid, int pnumber) {
177+
bool threadBindToProcessor(threadid_t tid, int pnumber)
178+
{
174179
#if defined(_WIN32)
175180

176181
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, 0, tid);
@@ -224,7 +229,8 @@ bool threadBindToProcessor(threadid_t tid, int pnumber) {
224229
}
225230

226231

227-
bool threadSetPriority(threadid_t tid, int prio) {
232+
bool threadSetPriority(threadid_t tid, int prio)
233+
{
228234
#if defined(_WIN32)
229235

230236
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, 0, tid);
@@ -533,17 +539,20 @@ void initializePaths()
533539

534540
static irr::IrrlichtDevice* device;
535541

536-
void initIrrlicht(irr::IrrlichtDevice * _device) {
542+
void initIrrlicht(irr::IrrlichtDevice * _device)
543+
{
537544
device = _device;
538545
}
539546

540547
#ifndef SERVER
541-
v2u32 getWindowSize() {
548+
v2u32 getWindowSize()
549+
{
542550
return device->getVideoDriver()->getScreenSize();
543551
}
544552

545553

546-
float getDisplayDensity() {
554+
float getDisplayDensity()
555+
{
547556
float gui_scaling = g_settings->getFloat("gui_scaling");
548557
// using Y here feels like a bug, this needs to be discussed later!
549558
if (getWindowSize().Y <= 800) {
@@ -556,7 +565,8 @@ float getDisplayDensity() {
556565
return (4.0/3.0) * gui_scaling;
557566
}
558567

559-
v2u32 getDisplaySize() {
568+
v2u32 getDisplaySize()
569+
{
560570
IrrlichtDevice *nulldevice = createDevice(video::EDT_NULL);
561571

562572
core::dimension2d<u32> deskres = nulldevice->getVideoModeList()->getDesktopResolution();
@@ -566,5 +576,93 @@ v2u32 getDisplaySize() {
566576
}
567577
#endif
568578

579+
#ifdef SERVER
580+
#ifdef _WIN32
581+
void daemonize()
582+
{
583+
errorstream << "daemonize not implemented on windows" << std::endl;
584+
}
585+
#else // assume posix like os
586+
587+
static std::string get_pidfile_path()
588+
{
589+
// make it static to make sure it won't change after first call to this fct
590+
static std::string path_pidfile = "";
591+
static bool initialized = false;
592+
593+
if (initialized)
594+
{
595+
return path_pidfile;
596+
}
597+
598+
g_settings->getNoEx("pidfile", path_pidfile);
599+
600+
if (path_pidfile == "") {
601+
#ifdef RUN_IN_PLACE
602+
path_pidfile = "pidfile.pid";
603+
#else
604+
path_pidfile = "/var/run/minetest.pid";
605+
#endif
606+
}
607+
initialized = true;
608+
return path_pidfile;
609+
}
610+
611+
612+
void daemonize()
613+
{
614+
std::string path_pidfile = get_pidfile_path();
615+
616+
FILE* pidfile = fopen(path_pidfile.c_str(),"r");
617+
618+
if (pidfile) {
619+
int pid = 0;
620+
if (fscanf(pidfile, "%i", &pid) == 1) {
621+
if (kill(pid, 0) == 0) {
622+
errorstream <<
623+
"Minetestserver is already running with pid: "
624+
<< pid << std::endl;
625+
exit(-1);
626+
}
627+
} else {
628+
errorstream << "Pidfile \"" << path_pidfile << "\" "
629+
"already exists but content is invalid" << std::endl <<
630+
"Delete it manually if you're sure minetest isn't running!"
631+
<< std::endl;
632+
exit(-1);
633+
}
634+
fclose(pidfile);
635+
pidfile = 0;
636+
}
637+
638+
pid_t pid = fork();
639+
640+
if (pid > 0) {
641+
pidfile = fopen(path_pidfile.c_str(),"w+");
642+
if (pidfile) {
643+
fprintf(pidfile,"%i",pid);
644+
fclose(pidfile);
645+
} else {
646+
errorstream << "Failed to create pidfile: \"" << path_pidfile
647+
<< "\""<< std::endl;
648+
}
649+
exit (0);
650+
} else if (pid == 0) {
651+
fclose(stdout);
652+
fclose(stderr);
653+
return;
654+
}
655+
656+
errorstream << "Failed to daemonize minetest, exiting" << std::endl;
657+
exit(-1);
658+
}
659+
660+
void cleanup_pid()
661+
{
662+
unlink(get_pidfile_path().c_str());
663+
}
664+
#endif
665+
#endif
666+
569667
} //namespace porting
570668

Diff for: ‎src/porting.h

+5
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,11 @@ v2u32 getDisplaySize();
336336
v2u32 getWindowSize();
337337
#endif
338338

339+
#ifdef SERVER
340+
void daemonize();
341+
void cleanup_pid();
342+
#endif
343+
339344
} // namespace porting
340345

341346
#endif // PORTING_HEADER

0 commit comments

Comments
 (0)
Please sign in to comment.