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/>.
28 #include <sys/types.h>
42 #ifdef HANDLE_VT_SWITCHING
43 #include <sys/ioctl.h>
52 #ifdef VOMP_PLATTFORM_NMT
54 #include "osddirectfb.h"
60 #ifndef WIN32 // FIXME do we need any if WIN32 stuff in here? windows has own winmain file
61 void threadSignalReceiverFunction();
64 [[ noreturn ]] void shutdown(int code);
70 #ifdef HANDLE_VT_SWITCHING
72 struct vt_mode old_vtmode;
75 static const char* TAG = "Main";
77 // Linux main function and sighandler
79 int main(int argc, char** argv)
83 config = new Config();
84 if (!config->loadFile())
86 printf("Parse error in config.json\n");
91 while ((c = getopt(argc, argv, "hclf:ns:p:")) != -1)
99 config->set("log", "enabled", true);
102 config->set("log", "filename", optarg);
105 config->set("main", "daemonize", false);
108 config->set("server", "address", optarg);
111 config->set("server", "port", std::atoi(optarg));
115 printf("Vompclient\n\n");
117 printf(" -l Enable logging\n");
118 printf(" -f F Log to file F instead of stdout\n");
119 printf(" -n Disable daemonize\n");
120 printf(" -s S Connect to server S\n");
121 printf(" -p P .. at port P\n");
124 printf("Option error\n");
129 // Start Log --------------------------------------------------------------------------------------------------
131 loggerNT = new LogNT();
134 printf("Failed to create LogNT object\n");
138 std::string logFileName;
139 config->getString("log", "filename", logFileName);
141 config->getBool("log", "enabled", logEnabled);
143 config->getBool("main", "daemonize", daemonize);
145 if (logEnabled && daemonize && !logFileName.compare("stdout"))
147 printf("Cannot daemonize and log to stdout\n");
151 if (!loggerNT->init(logFileName, logEnabled))
153 printf("Could not initialise log object. Aborting.\n");
157 loggerNT->info(TAG, "Starting up...");
159 // Daemonize --------------------------------------------------------------------------------------------------
161 // Would read config for daemonize here, but actually it's just above in the log section
162 // to detect attempts to log to stdout while daemonized
166 pid_t forkTest = fork();
168 { printf("Cannot fork (1).\n"); exit(1); }
169 if (forkTest != 0) _exit(0); // PID returned, I am the parent
170 // otherwise, I am the child
174 { printf("Cannot fork (2).\n"); exit(1); }
175 if (forkTest != 0) _exit(0); // PID returned, I am the parent
176 // otherwise, I am the child
182 // Set up signal handling ------------------------------------------------------------------------------------------
187 int sigBlockResult = pthread_sigmask(SIG_SETMASK, &set, NULL);
190 //logger->log("Main", Log::EMERG, "Could not block signals: %i", sigBlockResult);
191 loggerNT->crit(TAG, "Could not block signals: {}", sigBlockResult);
195 // Start signal receiver thread
196 std::thread threadSignalReceiver(threadSignalReceiverFunction);
197 threadSignalReceiver.detach();
199 loggerNT->info(TAG, "Signal handlers set up successfully");
201 // VT Switching -----------------------------------------------------------------------------------------------
203 #ifdef HANDLE_VT_SWITCHING
207 (fdtty = open("/dev/tty", O_WRONLY),0) == -1 // FIXME. Why the ,0 ? Surely this kills the log line below
212 loggerNT->warn(TAG, "Could not open /dev/tty. Please change permissions");
217 if (ioctl(fdtty, VT_OPENQRY, &free_vt) == -1 || free_vt == -1)
219 loggerNT->crit(TAG, "Could not retrieve free virtual console, please change permissions");
223 ioctl(fdtty, VT_ACTIVATE, free_vt);
224 ioctl(fdtty, VT_WAITACTIVE, free_vt);
225 ioctl(fdtty, VT_LOCKSWITCH, 1);
230 // Test area ------------------------------------------------------------------------------------------------------
234 // Run control ----------------------------------------------------------------------------------------------------
236 control = new Control();
239 loggerNT->crit(TAG, "Control module failed to create");
243 if (!control->init(crashed))
245 loggerNT->crit(TAG, "Control module failed to initialise");
257 // -------------------------------------------------------------------------------------------------------------------
259 void threadSignalReceiverFunction()
266 if(sigwait(&set, &sig))
268 loggerNT->crit(TAG, "Sigwait returned fail - signal handler exiting");
272 loggerNT->info(TAG, "Signal received: {}", sig);
274 if ((sig == SIGINT) || (sig == SIGTERM)) control->stop();
280 // -------------------------------------------------------------------------------------------------------------------
282 [[ noreturn ]] void shutdown(int code)
284 // FIXME, send a del all to boxstack first, then get rid of it after control?
285 if (control) // shut down control here in case views have posted messages
289 loggerNT->info(TAG, "Control module shut down");
292 #ifdef HANDLE_VT_SWITCHING
293 ioctl(fdtty, VT_UNLOCKSWITCH, 1);
299 loggerNT->info(TAG, "Log module shutting down... bye!\n\n");
300 #warning loggerNT has no shutdown
301 //loggerNT->shutdown();
313 // -------------------------------------------------------------------------------------------------------------------
315 int getClockRealTime(struct timespec *tp) // FIXME - del if all goes chrono
317 return clock_gettime(CLOCK_REALTIME, tp);