emcsvr.cc
1 /******************************************************************** 2 * Description: emcsvr.cc 3 * Network server for EMC NML 4 * 5 * Derived from a work by Fred Proctor & Will Shackleford 6 * 7 * Author: 8 * License: GPL Version 2 9 * System: Linux 10 * 11 * Copyright (c) 2004 All rights reserved. 12 * 13 * Last change: 14 ********************************************************************/ 15 16 #include <stdio.h> // sscanf() 17 #include <math.h> // fabs() 18 #include <stdlib.h> // exit() 19 #include <string.h> // strncpy() 20 #include <unistd.h> // _exit() 21 #include <signal.h> 22 23 #include "rcs.hh" // EMC NML 24 #include "emc.hh" // EMC NML 25 #include "emc_nml.hh" // EMC NML 26 #include "emcglb.h" // emcGetArgs(), EMC_NMLFILE 27 #include "inifile.hh" 28 #include "rcs_print.hh" 29 #include "nml_oi.hh" 30 #include "timer.hh" 31 #include "nml_srv.hh" // run_nml_servers() 32 33 static int tool_channels = 1; 34 35 static int iniLoad(const char *filename) 36 { 37 IniFile inifile; 38 const char *inistring; 39 40 // open it 41 if (inifile.Open(filename) == false) { 42 return -1; 43 } 44 45 if (NULL != (inistring = inifile.Find("DEBUG", "EMC"))) { 46 // copy to global 47 if (1 != sscanf(inistring, "%x", &emc_debug)) { 48 emc_debug = 0; 49 } 50 } else { 51 // not found, use default 52 emc_debug = 0; 53 } 54 if (emc_debug & EMC_DEBUG_RCS) { 55 set_rcs_print_flag(PRINT_EVERYTHING); 56 max_rcs_errors_to_print = -1; 57 } 58 59 if (NULL != (inistring = inifile.Find("NML_FILE", "EMC"))) { 60 // copy to global 61 strcpy(emc_nmlfile, inistring); 62 } else { 63 // not found, use default 64 } 65 inifile.Find(&tool_channels,"TOOL_CHANNELS","EMC"); 66 // close it 67 inifile.Close(); 68 69 return 0; 70 } 71 72 // based on code from 73 // http://www.microhowto.info/howto/cause_a_process_to_become_a_daemon_in_c.html 74 static void daemonize() 75 { 76 pid_t pid = fork(); 77 if (pid < 0) { 78 perror("daemonize: fork()"); 79 } else if (pid) { 80 _exit(0); 81 } 82 83 if(setsid() < 0) 84 perror("daemonize: setsid()"); 85 86 // otherwise the parent may deliver a SIGHUP to this process when it 87 // terminates 88 signal(SIGHUP,SIG_IGN); 89 90 pid=fork(); 91 if (pid < 0) { 92 perror("daemonize: fork() 2"); 93 } else if (pid) { 94 _exit(0); 95 } 96 } 97 98 static RCS_CMD_CHANNEL *emcCommandChannel = NULL; 99 static RCS_STAT_CHANNEL *emcStatusChannel = NULL; 100 static NML *emcErrorChannel = NULL; 101 static RCS_CMD_CHANNEL *toolCommandChannel = NULL; 102 static RCS_STAT_CHANNEL *toolStatusChannel = NULL; 103 104 int main(int argc, char *argv[]) 105 { 106 double start_time; 107 108 // process command line args 109 if (0 != emcGetArgs(argc, argv)) { 110 rcs_print_error("Error in argument list\n"); 111 exit(1); 112 } 113 // get configuration information 114 iniLoad(emc_inifile); 115 116 set_rcs_print_destination(RCS_PRINT_TO_NULL); 117 118 rcs_print("after iniLoad()\n"); 119 120 121 start_time = etime(); 122 123 while (fabs(etime() - start_time) < 10.0 && 124 (emcCommandChannel == NULL || emcStatusChannel == NULL 125 || (tool_channels && (toolCommandChannel == NULL || toolStatusChannel == NULL)) 126 || emcErrorChannel == NULL) 127 ) { 128 if (NULL == emcCommandChannel) { 129 rcs_print("emcCommandChannel==NULL, attempt to create\n"); 130 emcCommandChannel = 131 new RCS_CMD_CHANNEL(emcFormat, "emcCommand", "emcsvr", 132 emc_nmlfile); 133 } 134 if (NULL == emcStatusChannel) { 135 rcs_print("emcStatusChannel==NULL, attempt to create\n"); 136 emcStatusChannel = 137 new RCS_STAT_CHANNEL(emcFormat, "emcStatus", "emcsvr", 138 emc_nmlfile); 139 } 140 if (NULL == emcErrorChannel) { 141 emcErrorChannel = 142 new NML(nmlErrorFormat, "emcError", "emcsvr", emc_nmlfile); 143 } 144 if (tool_channels) { 145 if (NULL == toolCommandChannel) { 146 toolCommandChannel = 147 new RCS_CMD_CHANNEL(emcFormat, "toolCmd", "emcsvr", 148 emc_nmlfile); 149 } 150 if (NULL == toolStatusChannel) { 151 toolStatusChannel = 152 new RCS_STAT_CHANNEL(emcFormat, "toolSts", "emcsvr", 153 emc_nmlfile); 154 } 155 } 156 157 if (!emcCommandChannel->valid()) { 158 delete emcCommandChannel; 159 emcCommandChannel = NULL; 160 } 161 if (!emcStatusChannel->valid()) { 162 delete emcStatusChannel; 163 emcStatusChannel = NULL; 164 } 165 if (!emcErrorChannel->valid()) { 166 delete emcErrorChannel; 167 emcErrorChannel = NULL; 168 } 169 if (tool_channels) { 170 if (!toolCommandChannel->valid()) { 171 delete toolCommandChannel; 172 toolCommandChannel = NULL; 173 } 174 if (!toolStatusChannel->valid()) { 175 delete toolStatusChannel; 176 toolStatusChannel = NULL; 177 } 178 } 179 esleep(0.200); 180 } 181 182 set_rcs_print_destination(RCS_PRINT_TO_STDERR); 183 184 if (NULL == emcCommandChannel) { 185 emcCommandChannel = 186 new RCS_CMD_CHANNEL(emcFormat, "emcCommand", "emcsvr", 187 emc_nmlfile); 188 } 189 if (NULL == emcStatusChannel) { 190 emcStatusChannel = 191 new RCS_STAT_CHANNEL(emcFormat, "emcStatus", "emcsvr", 192 emc_nmlfile); 193 } 194 if (NULL == emcErrorChannel) { 195 emcErrorChannel = 196 new NML(nmlErrorFormat, "emcError", "emcsvr", emc_nmlfile); 197 } 198 if (tool_channels) { 199 if (NULL == toolCommandChannel) { 200 toolCommandChannel = 201 new RCS_CMD_CHANNEL(emcFormat, "toolCmd", "emcsvr", 202 emc_nmlfile); 203 } 204 if (NULL == toolStatusChannel) { 205 toolStatusChannel = 206 new RCS_STAT_CHANNEL(emcFormat, "toolSts", "emcsvr", 207 emc_nmlfile); 208 } 209 } 210 daemonize(); 211 run_nml_servers(); 212 213 return 0; 214 } 215 216 // vim:sw=4:sts=4:et