diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.cpp | 19 | ||||
-rw-r--r-- | src/porting.cpp | 112 | ||||
-rw-r--r-- | src/porting.h | 5 |
3 files changed, 128 insertions, 8 deletions
diff --git a/src/main.cpp b/src/main.cpp index 0531a8540..43284611f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -811,6 +811,9 @@ int main(int argc, char *argv[]) _("Set password")))); allowed_options.insert(std::make_pair("go", ValueSpec(VALUETYPE_FLAG, _("Disable main menu")))); +#else + allowed_options.insert(std::make_pair("daemon", ValueSpec(VALUETYPE_FLAG, + _("Daemonize minetestserver")))); #endif Settings cmd_args; @@ -918,6 +921,12 @@ int main(int argc, char *argv[]) <<", "<<minetest_build_info <<std::endl; +#ifdef SERVER + if (cmd_args.exists("daemon")) { + porting::daemonize(); + } +#endif + /* Basic initialization */ @@ -1469,7 +1478,7 @@ int main(int argc, char *argv[]) ELL_ERROR, ELL_WARNING, ELL_INFORMATION, -#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8) +#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8) ELL_INFORMATION #else ELL_DEBUG @@ -1920,6 +1929,14 @@ int main(int argc, char *argv[]) debugstreams_deinit(); + +#ifdef SERVER + if (cmd_args.exists("daemon")) + { + porting::cleanup_pid(); + } +#endif + return retval; } diff --git a/src/porting.cpp b/src/porting.cpp index d1e3cdd70..ef461242d 100644 --- a/src/porting.cpp +++ b/src/porting.cpp @@ -33,8 +33,11 @@ with this program; if not, write to the Free Software Foundation, Inc., #include <sys/sysctl.h> #elif defined(_WIN32) #include <algorithm> +#elif defined(__LINUX) + #include <sys/types.h> #endif #if !defined(_WIN32) + #include <sys/stat.h> #include <unistd.h> #include <sys/utsname.h> #endif @@ -137,7 +140,8 @@ void signal_handler_init(void) /* Multithreading support */ -int getNumberOfProcessors() { +int getNumberOfProcessors() +{ #if defined(_SC_NPROCESSORS_ONLN) return sysconf(_SC_NPROCESSORS_ONLN); @@ -170,7 +174,8 @@ int getNumberOfProcessors() { } -bool threadBindToProcessor(threadid_t tid, int pnumber) { +bool threadBindToProcessor(threadid_t tid, int pnumber) +{ #if defined(_WIN32) HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, 0, tid); @@ -224,7 +229,8 @@ bool threadBindToProcessor(threadid_t tid, int pnumber) { } -bool threadSetPriority(threadid_t tid, int prio) { +bool threadSetPriority(threadid_t tid, int prio) +{ #if defined(_WIN32) HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, 0, tid); @@ -533,17 +539,20 @@ void initializePaths() static irr::IrrlichtDevice* device; -void initIrrlicht(irr::IrrlichtDevice * _device) { +void initIrrlicht(irr::IrrlichtDevice * _device) +{ device = _device; } #ifndef SERVER -v2u32 getWindowSize() { +v2u32 getWindowSize() +{ return device->getVideoDriver()->getScreenSize(); } -float getDisplayDensity() { +float getDisplayDensity() +{ float gui_scaling = g_settings->getFloat("gui_scaling"); // using Y here feels like a bug, this needs to be discussed later! if (getWindowSize().Y <= 800) { @@ -556,7 +565,8 @@ float getDisplayDensity() { return (4.0/3.0) * gui_scaling; } -v2u32 getDisplaySize() { +v2u32 getDisplaySize() +{ IrrlichtDevice *nulldevice = createDevice(video::EDT_NULL); core::dimension2d<u32> deskres = nulldevice->getVideoModeList()->getDesktopResolution(); @@ -566,5 +576,93 @@ v2u32 getDisplaySize() { } #endif +#ifdef SERVER +#ifdef _WIN32 +void daemonize() +{ + errorstream << "daemonize not implemented on windows" << std::endl; +} +#else // assume posix like os + +static std::string get_pidfile_path() +{ + // make it static to make sure it won't change after first call to this fct + static std::string path_pidfile = ""; + static bool initialized = false; + + if (initialized) + { + return path_pidfile; + } + + g_settings->getNoEx("pidfile", path_pidfile); + + if (path_pidfile == "") { +#ifdef RUN_IN_PLACE + path_pidfile = "pidfile.pid"; +#else + path_pidfile = "/var/run/minetest.pid"; +#endif + } + initialized = true; + return path_pidfile; +} + + +void daemonize() +{ + std::string path_pidfile = get_pidfile_path(); + + FILE* pidfile = fopen(path_pidfile.c_str(),"r"); + + if (pidfile) { + int pid = 0; + if (fscanf(pidfile, "%i", &pid) == 1) { + if (kill(pid, 0) == 0) { + errorstream << + "Minetestserver is already running with pid: " + << pid << std::endl; + exit(-1); + } + } else { + errorstream << "Pidfile \"" << path_pidfile << "\" " + "already exists but content is invalid" << std::endl << + "Delete it manually if you're sure minetest isn't running!" + << std::endl; + exit(-1); + } + fclose(pidfile); + pidfile = 0; + } + + pid_t pid = fork(); + + if (pid > 0) { + pidfile = fopen(path_pidfile.c_str(),"w+"); + if (pidfile) { + fprintf(pidfile,"%i",pid); + fclose(pidfile); + } else { + errorstream << "Failed to create pidfile: \"" << path_pidfile + << "\""<< std::endl; + } + exit (0); + } else if (pid == 0) { + fclose(stdout); + fclose(stderr); + return; + } + + errorstream << "Failed to daemonize minetest, exiting" << std::endl; + exit(-1); +} + +void cleanup_pid() +{ + unlink(get_pidfile_path().c_str()); +} +#endif +#endif + } //namespace porting diff --git a/src/porting.h b/src/porting.h index 937ca9464..be26e4282 100644 --- a/src/porting.h +++ b/src/porting.h @@ -336,6 +336,11 @@ v2u32 getDisplaySize(); v2u32 getWindowSize(); #endif +#ifdef SERVER +void daemonize(); +void cleanup_pid(); +#endif + } // namespace porting #endif // PORTING_HEADER |