GRASS Programmer's Manual  6.4.2(2012)
lib/driver/main.c
Go to the documentation of this file.
00001 
00002 /****************************************************************************
00003  *
00004  * MODULE:       driver
00005  * AUTHOR(S):    Glynn Clements <glynn gclements.plus.com>(original contributor)
00006  *               Jachym Cepicky <jachym les-ejk.cz>
00007  * PURPOSE:      graphics monitor driver
00008  * COPYRIGHT:    (C) 2006-2007 by the GRASS Development Team
00009  *
00010  *               This program is free software under the GNU General Public
00011  *               License (>=v2). Read the file COPYING that comes with GRASS
00012  *               for details.
00013  *
00014  *****************************************************************************/
00015 #include <stdio.h>
00016 #include <string.h>
00017 #include <stdlib.h>
00018 #include <signal.h>
00019 #include <setjmp.h>
00020 #include <unistd.h>
00021 
00022 #include <grass/gis.h>
00023 #include <grass/glocale.h>
00024 #include "driverlib.h"
00025 #include "driver.h"
00026 #include "pad.h"
00027 
00028 static jmp_buf save;
00029 
00030 static RETSIGTYPE handle_sigpipe(int sig)
00031 {
00032     longjmp(save, 1);
00033 }
00034 
00035 static RETSIGTYPE handle_sigterm(int sig)
00036 {
00037     COM_Graph_close();
00038 }
00039 
00040 int LIB_main(int argc, char **argv)
00041 {
00042     char *me;
00043     int _wfd;
00044     int _rfd;
00045     int eof;
00046 
00047     char c;
00048     pid_t pid;
00049     int foreground;
00050     int listenfd;
00051 
00052 #ifndef __MINGW32__
00053     struct sigaction sigact;
00054 #endif
00055 
00056     /* The calling syntax is as follows:
00057        monitor_name [-] ["input_fifo output_fifo"]
00058 
00059        The "-", if present, causes the monitor to run in foreground.
00060        Otherwise, once it has been determined that the monitor is not
00061        already running, we will fork and the parent will exit, so that
00062        the monitor is left running in background.
00063      */
00064 
00065     if (argc < 2) {
00066         G_warning("Usage:  %s <name> [-]", argv[0]);
00067         return 1;
00068     }
00069 
00070     /* whoami */
00071     me = argv[1];
00072 
00073     foreground = (argc >= 3 && argv[2][0] == '-');
00074 
00075 #ifndef __MINGW32__
00076 #ifdef SIGPIPE
00077     sigact.sa_handler = handle_sigpipe;
00078     sigemptyset(&sigact.sa_mask);
00079     sigact.sa_flags = 0;
00080     sigaction(SIGPIPE, &sigact, NULL);
00081 #endif
00082     sigact.sa_handler = handle_sigterm;
00083     sigemptyset(&sigact.sa_mask);
00084     sigact.sa_flags = 0;
00085     sigaction(SIGTERM, &sigact, NULL);
00086 #endif
00087 
00088     listenfd = prepare_connection_sock(me);
00089 
00090     G_message(_("Graphics driver [%s] started"), me);
00091 
00092 #ifndef __MINGW32__
00093     if (!foreground) {
00094         pid = fork();
00095         if (pid) {
00096             if (pid > 0) {      /* parent exits */
00097                 exit(0);
00098             }
00099             else {              /* weren't able to fork */
00100 
00101                 G_fatal_error("Error - Could not fork to start [%s]", me);
00102                 exit(EXIT_FAILURE);
00103             }
00104         }
00105         else {
00106             /* change process groups to be shielded from keyboard signals */
00107 #ifdef SETPGRP_VOID
00108             setpgrp();
00109 #else
00110             setpgrp(0, getpid());
00111 #endif
00112         }
00113     }                           /* monitor runs */
00114 #endif
00115 
00116     while (1) {                 /* re-open upon EOF */
00117         for (;;) {
00118             if (get_connection_sock(listenfd, &_rfd, &_wfd, COM_Work_stream())
00119                 >= 0)
00120                 break;
00121 
00122             COM_Do_work(0);
00123         }
00124 
00125         command_init(_rfd, _wfd);
00126 
00127         COM_Client_Open();
00128 
00129         eof = 0;
00130 
00131         while (eof <= 0) {
00132             COM_Do_work(1);
00133 
00134             if (setjmp(save)) {
00135                 G_warning("Monitor <%s>: Caught SIGPIPE", me);
00136                 break;
00137             }
00138 
00139             if (get_command(&c) != 0)
00140                 break;
00141 
00142             if (process_command(c)) {
00143                 G_warning("Monitor <%s>: Premature EOF", me);
00144                 break;
00145             }
00146         }
00147 
00148         /* read encountered EOF. close socket now */
00149         close(_wfd);
00150         close(_rfd);
00151         _rfd = _wfd = -1;       /* Set to invalid file descriptor number */
00152 
00153         COM_Client_Close();
00154     }
00155 
00156     return 0;
00157 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines