2 Copyright 2004-2020 Chris Tallon
4 This file is part of VOMP.
6 VOMP is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 VOMP is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with VOMP. If not, see <https://www.gnu.org/licenses/>.
26 #include <sys/types.h>
40 #ifdef HANDLE_VT_SWITCHING
41 #include <sys/ioctl.h>
50 #ifdef VOMP_PLATTFORM_NMT
52 #include "osddirectfb.h"
58 #ifndef WIN32 // FIXME do we need any if WIN32 stuff in here? windows has own winmain file
59 void threadSignalReceiverFunction();
62 [[ noreturn ]] void shutdown(int code);
63 const std::string& getCommandLineServer(); // NCONFIG
69 // Temporary, will move to Config system NCONFIG
70 std::string argvServer;
72 #ifdef HANDLE_VT_SWITCHING
74 struct vt_mode old_vtmode;
77 // Linux main function and sighandler
79 int main(int argc, char** argv)
81 bool daemonize = true;
82 bool debugEnabled = false;
86 config = new Config();
87 if (!config->loadFile())
89 printf("Parse error in config.json\n");
95 while ((c = getopt(argc, argv, "cdns:")) != -1)
103 debugEnabled = true; // and...
112 printf("Unknown option\n");
115 printf("Option error\n");
120 // Start Log --------------------------------------------------------------------------------------------------
124 printf("Failed to create Log object\n");
128 if (!logger->init(Log::DEBUG, "dummy", debugEnabled ? 1 : 0)) // NCONFIG x2
130 printf("Could not initialise log object. Aborting.\n");
134 logger->log("Main", Log::INFO, "Starting up...");
136 // Daemonize --------------------------------------------------------------------------------------------------
138 if (daemonize) // NCONFIG
141 pid_t forkTest = fork();
143 { printf("Cannot fork (1).\n"); exit(1); }
144 if (forkTest != 0) _exit(0); // PID returned, I am the parent
145 // otherwise, I am the child
149 { printf("Cannot fork (2).\n"); exit(1); }
150 if (forkTest != 0) _exit(0); // PID returned, I am the parent
151 // otherwise, I am the child
157 // Set up signal handling ------------------------------------------------------------------------------------------
162 int sigBlockResult = pthread_sigmask(SIG_SETMASK, &set, NULL);
165 logger->log("Main", Log::EMERG, "Could not block signals: %i", sigBlockResult);
169 // Start signal receiver thread
170 std::thread threadSignalReceiver(threadSignalReceiverFunction);
171 threadSignalReceiver.detach();
173 logger->log("Main", Log::INFO, "Signal handlers set up successfully");
175 // VT Switching -----------------------------------------------------------------------------------------------
177 #ifdef HANDLE_VT_SWITCHING
181 (fdtty = open("/dev/tty", O_WRONLY),0) == -1 // FIXME. Why the ,0 ? Surely this kills the log line below
186 logger->log("Main", Log::EMERG, "Could not open /dev/tty. Please change permissions");
191 if (ioctl(fdtty, VT_OPENQRY, &free_vt) == -1 || free_vt == -1)
193 logger->log("Main", Log::EMERG, "Could not retrieve free virtual console, please change permissions");
197 ioctl(fdtty, VT_ACTIVATE, free_vt);
198 ioctl(fdtty, VT_WAITACTIVE, free_vt);
199 ioctl(fdtty, VT_LOCKSWITCH, 1);
204 // Test area ------------------------------------------------------------------------------------------------------
208 // Run control ----------------------------------------------------------------------------------------------------
210 control = new Control();
213 logger->log("Main", Log::EMERG, "Control module failed to create");
217 if (!control->init(crashed))
219 logger->log("Main", Log::EMERG, "Control module failed to initialise");
231 // -------------------------------------------------------------------------------------------------------------------
233 void threadSignalReceiverFunction()
240 if(sigwait(&set, &sig))
242 logger->log("Main", Log::CRIT, "Sigwait returned fail - signal handler exiting");
246 logger->log("Main", Log::NOTICE, "Signal received: %i", sig);
248 if ((sig == SIGINT) || (sig == SIGTERM)) control->stop();
254 // -------------------------------------------------------------------------------------------------------------------
256 [[ noreturn ]] void shutdown(int code)
258 // FIXME, send a del all to boxstack first, then get rid of it after control?
259 if (control) // shut down control here in case views have posted messages
263 logger->log("Main", Log::NOTICE, "Control module shut down");
266 #ifdef HANDLE_VT_SWITCHING
267 ioctl(fdtty, VT_UNLOCKSWITCH, 1);
273 logger->log("Main", Log::NOTICE, "Log module shutting down... bye!\n\n");
286 // -------------------------------------------------------------------------------------------------------------------
288 long long getTimeMS()
291 clock_gettime(VOMP_LINUX_CLOCK, &ts);
292 return ts.tv_sec * 1000 + ts.tv_nsec / 1000000LL;
295 int getClockRealTime(struct timespec *tp) // FIXME - del if all goes chrono
297 return clock_gettime(CLOCK_REALTIME, tp);
300 const std::string& getCommandLineServer() // NCONFIG