Advertisement
Ollie920049

main.cpp

May 3rd, 2012
332
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.61 KB | None | 0 0
  1. /*
  2.  * =====================================================================================
  3.  *       Filename:  main.cpp
  4.  *    Description:  Creates a child process responsible for starting a kdb daemon server
  5.  *                  The parent process launches the gui for QScanner.
  6.  *
  7.  *        Version:  1.0
  8.  *        Created:  23/04/12 15:42:19
  9.  *       Compiler:  "make" from QScanner root. Requires qt make installed
  10.  *                   $ sudo apt-get install libqt4-dev
  11.  *
  12.  *         Author:  Oliver Fletcher, ttolf@lboro.ac.uk
  13.  *     University:  Loughborough University
  14.  * =====================================================================================
  15.  */
  16.  
  17. #include <QApplication>
  18. #include "qgui.h"
  19. #include <fcntl.h>
  20.  
  21. using namespace std;
  22. string qLaunch;                                 /* Path to q executable */
  23. string qRoot;                                   /* Path to QScanner root */
  24. string qScanner;                                /* Path to Qscaner.q launch file */
  25.  
  26. /*
  27.  * ===  FUNCTION  ======================================================================
  28.  *         Name:  main
  29.  *  Description:  Creates a QApplication instance. Gets a child process ID and uses it
  30.  *                to launch the daemon server. It then executes the GUI putting the
  31.  *                system in a permanent loop. When the GUI is closed it returns
  32.  *                and connects to the KDB server sending a kill signal.
  33.  * =====================================================================================
  34.  */
  35. int main(int argc, char *argv[])
  36. {
  37.   QApplication app(argc,argv);                  /* Create GUI App */
  38.   qguiApp *dialog = new qguiApp;
  39.  
  40.   qScannerPath();                               /* Get current working directory */
  41.  
  42.   pid_t pID = fork();                           /* Create a child process id */
  43.   if(pID > 0){
  44.     launchDaemon();                             /* Launch the child process */
  45.   }
  46.   else {
  47.     dialog->show();
  48.     app.exec();                                 /* Execute the GUI (enter loop) */
  49.   }
  50.  
  51.   int c = khp("localhost",5000);                /* Kill the daemon */
  52.   k(-c,"\\\\",(K)0);
  53.   kclose(c);
  54.  
  55.   return 0;
  56. }
  57.  
  58. /*
  59.  * ===  FUNCTION  ======================================================================
  60.  *         Name:  open_or_die
  61.  *  Description:  Opens a files. Errors if the file fails to open
  62.  *       Source:  http://code.kx.com/wiki/Cookbook/Daemon
  63.  * =====================================================================================
  64.  */
  65. int open_or_die(char *path)
  66. {
  67.   int file, flags = O_CREAT | O_WRONLY | O_APPEND;
  68.   if ((NULL == path) || (-1 == (file = open (path, flags, 0666)))) {
  69.     (void) fprintf (stderr, "Failed to open file");
  70.  
  71.     return 0;
  72.   }
  73.   return file;
  74. }
  75.  
  76. /*
  77.  * ===  FUNCTION  ======================================================================
  78.  *         Name:  launchDaemon
  79.  *  Description:  Uses global variables qLaunch, qScanner, qRoot to execute the
  80.  *                server using the execv function. Redirects the program stdin, stdout
  81.  *                and stderr to log files.
  82.  *       Source:  http://code.kx.com/wiki/Cookbook/Daemon
  83.  * =====================================================================================
  84.  */
  85. void launchDaemon()
  86. {
  87.   //prepare c strings to char*
  88.   char *qlaunch = const_cast<char*> ( qLaunch.c_str() );
  89.   char *qscan = const_cast<char*> ( qScanner.c_str() );
  90.   char *qroot = const_cast<char*> ( qRoot.c_str() );
  91.  
  92.   char *command[] = { qlaunch , qscan  , qroot , "-p", "5000", (char *) 0};    
  93.  
  94.   //Make a token attempt to see if we'll be able to exec the command.
  95.   if (-1 == access (command[0], F_OK)) {
  96.     (void) fprintf (stderr, "Can't access %s, exiting.\n", command[0]);
  97.     exit(EXIT_FAILURE);
  98.   }
  99.  
  100.   // Try to open some files for pid, stdin, stdout, stderr.
  101.   FILE *pid_file = fopen ("logs/pid", "w+");
  102.   int stdin_file = open_or_die("/dev/null");
  103.   int stderr_file = open_or_die("logs/stderr");
  104.   int stdout_file = open_or_die("logs/stdout");
  105.  
  106.   // Nuke stdin and redirect stderr, stdout.
  107.   close (STDIN_FILENO);
  108.   dup2 (stdin_file, STDIN_FILENO);
  109.   close (STDOUT_FILENO);
  110.   dup2 (stdout_file, STDOUT_FILENO);
  111.   close (STDERR_FILENO);
  112.   dup2 (stderr_file, STDERR_FILENO);
  113.  
  114.   // Now daemonize..
  115.   if (0 != daemon (0, 1))  {
  116.     printf("Error: Can't daemonize.");
  117.     exit (EXIT_FAILURE);
  118.   }
  119.  
  120.   // Write the pid
  121.   fprintf (pid_file, "%d\n", getpid ());
  122.   fclose (pid_file);
  123.  
  124.   // And away we go..
  125.   execv (command[0], command);
  126. }
  127.  
  128. /*
  129.  * ===  FUNCTION  ======================================================================
  130.  *         Name:  qScannerPath
  131.  *  Description:  Used to find the path to the Q executable, QScanner root and QScanner
  132.  *                executable
  133.  *       Inputs:  None
  134.  *      Returns:  Global Variables
  135.  *                qLaunch -> /path/to/l32/q
  136.  *                qRoot   -> /path/to/QScanner (folder)
  137.  *                qScanner-> /path/to/QScanner/QScanner.q
  138.  * =====================================================================================
  139.  */
  140. void qScannerPath()
  141. {
  142.   char buff[1024];                            /* get executable path */
  143.   ssize_t len = readlink("/proc/self/exe", buff, sizeof(buff)-1);
  144.   string s;
  145.  
  146.   if (len != -1) {                            /* process into string */
  147.     buff[len] = '\0';
  148.     s = string(buff);
  149.   }
  150.   for(int i=0;i<2;i++){
  151.     s = s.substr(0,s.find_last_of("/"));      /* Remove two layers of folder depth */
  152.   }
  153.  
  154.   qLaunch  =  s + "/l32/q";                   /* Asign Global variables */
  155.   qRoot    =  s + "/QScanner";
  156.   qScanner =  s + "/QScanner/QScanner.q";
  157. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement