2 Copyright 2004-2021 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>
51 #ifdef VOMP_PLATTFORM_NMT
53 #include "osddirectfb.h"
59 #ifndef WIN32 // FIXME do we need any if WIN32 stuff in here? windows has own winmain file
60 void threadSignalReceiverFunction();
63 [[ noreturn ]] void shutdown(int code);
64 const std::string& getCommandLineServer(); // NCONFIG
71 // Temporary, will move to Config system NCONFIG
72 std::string argvServer;
74 #ifdef HANDLE_VT_SWITCHING
76 struct vt_mode old_vtmode;
79 static const char* TAG = "Main";
81 // Linux main function and sighandler
83 int main(int argc, char** argv)
85 bool daemonize = true;
86 bool debugEnabled = false;
90 config = new Config();
91 if (!config->loadFile())
93 printf("Parse error in config.json\n");
99 while ((c = getopt(argc, argv, "cdns:")) != -1)
107 debugEnabled = true; // and...
116 printf("Unknown option\n");
119 printf("Option error\n");
124 // Start Log --------------------------------------------------------------------------------------------------
128 printf("Failed to create Log object\n");
132 if (!logger->init(Log::DEBUG, "dummy", debugEnabled ? 1 : 0)) // NCONFIG x2
134 printf("Could not initialise log object. Aborting.\n");
138 logger->log("Main", Log::INFO, "Old log starting up...");
142 loggerNT = new LogNT();
145 printf("Failed to create LogNT object\n");
149 std::string logFileName("stdout");
150 config->getString("log", "filename", logFileName);
151 if (!loggerNT->init(logFileName, debugEnabled ? 1 : 0)) // NCONFIG x2
153 printf("Could not initialise log object. Aborting.\n");
157 //logger->log("Main", Log::INFO, "Starting up...");
158 loggerNT->info(TAG, "Starting up...");
160 // Daemonize --------------------------------------------------------------------------------------------------
162 if (daemonize) // NCONFIG
165 pid_t forkTest = fork();
167 { printf("Cannot fork (1).\n"); exit(1); }
168 if (forkTest != 0) _exit(0); // PID returned, I am the parent
169 // otherwise, I am the child
173 { printf("Cannot fork (2).\n"); exit(1); }
174 if (forkTest != 0) _exit(0); // PID returned, I am the parent
175 // otherwise, I am the child
181 // Set up signal handling ------------------------------------------------------------------------------------------
186 int sigBlockResult = pthread_sigmask(SIG_SETMASK, &set, NULL);
189 //logger->log("Main", Log::EMERG, "Could not block signals: %i", sigBlockResult);
190 loggerNT->crit(TAG, "Could not block signals: {}", sigBlockResult);
194 // Start signal receiver thread
195 std::thread threadSignalReceiver(threadSignalReceiverFunction);
196 threadSignalReceiver.detach();
198 loggerNT->info(TAG, "Signal handlers set up successfully");
200 // VT Switching -----------------------------------------------------------------------------------------------
202 #ifdef HANDLE_VT_SWITCHING
206 (fdtty = open("/dev/tty", O_WRONLY),0) == -1 // FIXME. Why the ,0 ? Surely this kills the log line below
211 loggerNT->warn(TAG, "Could not open /dev/tty. Please change permissions");
216 if (ioctl(fdtty, VT_OPENQRY, &free_vt) == -1 || free_vt == -1)
218 loggerNT->crit(TAG, "Could not retrieve free virtual console, please change permissions");
222 ioctl(fdtty, VT_ACTIVATE, free_vt);
223 ioctl(fdtty, VT_WAITACTIVE, free_vt);
224 ioctl(fdtty, VT_LOCKSWITCH, 1);
229 // Test area ------------------------------------------------------------------------------------------------------
233 // Run control ----------------------------------------------------------------------------------------------------
235 control = new Control();
238 loggerNT->crit(TAG, "Control module failed to create");
242 if (!control->init(crashed))
244 loggerNT->crit(TAG, "Control module failed to initialise");
256 // -------------------------------------------------------------------------------------------------------------------
258 void threadSignalReceiverFunction()
265 if(sigwait(&set, &sig))
267 loggerNT->crit(TAG, "Sigwait returned fail - signal handler exiting");
271 loggerNT->info(TAG, "Signal received: {}", sig);
273 if ((sig == SIGINT) || (sig == SIGTERM)) control->stop();
279 // -------------------------------------------------------------------------------------------------------------------
281 [[ noreturn ]] void shutdown(int code)
283 // FIXME, send a del all to boxstack first, then get rid of it after control?
284 if (control) // shut down control here in case views have posted messages
288 loggerNT->info(TAG, "Control module shut down");
291 #ifdef HANDLE_VT_SWITCHING
292 ioctl(fdtty, VT_UNLOCKSWITCH, 1);
298 loggerNT->info(TAG, "Log module shutting down... bye!\n\n");
311 // -------------------------------------------------------------------------------------------------------------------
313 long long getTimeMS()
316 clock_gettime(VOMP_LINUX_CLOCK, &ts);
317 return ts.tv_sec * 1000 + ts.tv_nsec / 1000000LL;
320 int getClockRealTime(struct timespec *tp) // FIXME - del if all goes chrono
322 return clock_gettime(CLOCK_REALTIME, tp);
325 const std::string& getCommandLineServer() // NCONFIG