1:/*--------------------------------------------------------------------------- 2: 3: FILENAME: 4: template2.c 5: 6: PURPOSE: 7: Provide the 2nd radlib template process entry point. 8: 9: REVISION HISTORY: 10: Date Engineer Revision Remarks 11: 01/01/2004 Your Name 0 Original 12: 13: NOTES: 14: All references to "template" should be replaced by a meaningful 15: process name, including the file names and data structures. 16: 17:----------------------------------------------------------------------------*/ 18: 19:// System include files 20:#include <sys/types.h> 21:#include <sys/wait.h> 22:#include <unistd.h> 23: 24:// radlib include files 25: 26:// Local include files 27:#include "template.h" 28: 29: 30:// global memory declarations 31: 32:// global memory referenced 33: 34:// static (local) memory declarations 35: 36:// declare the process work area 37:static TEMPLATE_WORK templateWork; 38: 39: 40:// methods 41: 42:static void msgHandler 43:( 44: char *srcQueueName, 45: UINT msgType, 46: void *msg, 47: UINT length, 48: void *userData 49:) 50:{ 51: STIM stim; 52: 53: stim.type = STIM_QMSG; 54: stim.srcQueueName = srcQueueName; 55: stim.msgType = msgType; 56: stim.msg = msg; 57: stim.length = length; 58: 59: radStatesProcess (templateWork.stateMachine, &stim); 60: 61: return; 62:} 63: 64:static void evtHandler 65:( 66: UINT eventsRx, 67: UINT rxData, 68: void *userData 69:) 70:{ 71: STIM stim; 72: 73: stim.type = STIM_EVENT; 74: stim.eventsRx = eventsRx; 75: stim.eventData = rxData; 76: 77: radStatesProcess (templateWork.stateMachine, &stim); 78: 79: return; 80:} 81: 82:// process initialization 83:static int templateSysInit (void) 84:{ 85: char devPath[256], temp[32]; 86: char *installPath; 87: struct stat fileData; 88: FILE *pidfile; 89: 90: // get the install path 91: installPath = getenv ("APPLICATION_RUN_DIRECTORY"); 92: if (installPath == NULL) 93: { 94: installPath = "."; 95: } 96: chdir (installPath); 97: 98: 99: // check for our pid file, don't run if it is there 100: sprintf (devPath, "%s/%s", installPath, TEMPLATE2_LOCK_FILENAME); 101: if (stat (devPath, &fileData) == 0) 102: { 103: printf ("lock file %s exists, older copy may be running - aborting!\n", 104: devPath); 105: return -1; 106: } 107: 108: 109: // create our device directory if it is not there 110: sprintf (devPath, "%s/dev", installPath); 111: if (stat (devPath, &fileData) != 0) 112: { 113: if (mkdir (devPath, 0755) != 0) 114: { 115: printf ("Cannot create device dir: %s - aborting!\n", 116: devPath); 117: return -1; 118: } 119: } 120: 121: return 0; 122:} 123: 124:// system exit 125:static int templateSysExit (void) 126:{ 127: char devPath[256]; 128: char *installPath; 129: struct stat fileData; 130: 131: // get the install path 132: installPath = getenv ("APPLICATION_RUN_DIRECTORY"); 133: if (installPath == NULL) 134: { 135: installPath = "."; 136: } 137: 138: // delete our pid file 139: sprintf (devPath, "%s/%s", installPath, TEMPLATE2_LOCK_FILENAME); 140: if (stat (devPath, &fileData) == 0) 141: { 142: printf ("\nlock file %s exists, deleting it...\n", 143: devPath); 144: if (unlink (devPath) == -1) 145: { 146: printf ("lock file %s delete failed!\n", 147: devPath); 148: } 149: } 150: 151: return 0; 152:} 153: 154:static void defaultSigHandler (int signum) 155:{ 156: switch (signum) 157: { 158: case SIGPIPE: 159: // if you are using sockets or pipes, you will need to catch this 160: // we have a far end socket disconnection, we'll handle it in the 161: // "read/write" code 162: signal (signum, defaultSigHandler); 163: break; 164: 165: case SIGILL: 166: case SIGBUS: 167: case SIGFPE: 168: case SIGSEGV: 169: case SIGXFSZ: 170: case SIGSYS: 171: // unrecoverable signal - we must exit right now! 172: radMsgLog (PRI_CATASTROPHIC, "template2d: recv sig %d: bailing out!", signum); 173: abort (); 174: 175: case SIGCHLD: 176: wait (NULL); 177: signal (signum, defaultSigHandler); 178: break; 179: 180: default: 181: // can we allow the process to exit normally? 182: if (radProcessGetExitFlag()) 183: { 184: // NO! - we gotta bail here! 185: radMsgLog (PRI_HIGH, "template2d: recv sig %d: exiting now!", signum); 186: exit (0); 187: } 188: 189: // we can allow the process to exit normally... 190: radMsgLog (PRI_HIGH, "template2d: recv sig %d: exiting!", signum); 191: 192: radProcessSetExitFlag (); 193: 194: signal (signum, defaultSigHandler); 195: break; 196: } 197: 198: return; 199:} 200: 201: 202:// the main entry point for the template process 203:int main (int argc, char *argv[]) 204:{ 205: void (*alarmHandler)(int); 206: STIM stim; 207: int i; 208: char qname[256], cfgname[256], instance[32], value[32]; 209: char pidName[256]; 210: char *installPath; 211: CF_ID configFileId; 212: struct stat fileStatus; 213: FILE *pidfile; 214: 215: 216: // initialize some system stuff first 217: if (templateSysInit () == -1) 218: { 219: radMsgLogInit (PROC_NAME_TEMPLATE2, TRUE, TRUE); 220: radMsgLog (PRI_CATASTROPHIC, "system init failed!\n"); 221: radMsgLogExit (); 222: exit (1); 223: } 224: 225: // create some file paths for later use 226: installPath = getenv ("APPLICATION_RUN_DIRECTORY"); 227: if (installPath == NULL) 228: { 229: installPath = "."; 230: } 231: sprintf (qname, "%s/dev/%s", installPath, PROC_NAME_TEMPLATE2); 232: sprintf (cfgname, "%s/%s", installPath, TEMPLATE_CONFIG_FILENAME); 233: sprintf (pidName, "%s/%s", installPath, TEMPLATE2_LOCK_FILENAME); 234: 235: memset (&templateWork, 0, sizeof (templateWork)); 236: 237: 238: 239: // call the global radlib system init function 240: if (radSystemInit (TEMPLATE_SYSTEM_ID) == ERROR) 241: { 242: radMsgLogInit (PROC_NAME_TEMPLATE2, TRUE, TRUE); 243: radMsgLog (PRI_CATASTROPHIC, "%s: radSystemInit failed!"); 244: radMsgLogExit (); 245: exit (1); 246: } 247: 248: 249: // call the radlib process init function 250: if (radProcessInit (PROC_NAME_TEMPLATE2, 251: qname, 252: 0, // no timers 253: TRUE, // TRUE => daemon 254: msgHandler, 255: evtHandler, 256: NULL) 257: == ERROR) 258: { 259: radMsgLogInit (PROC_NAME_TEMPLATE2, TRUE, TRUE); 260: radMsgLog (PRI_CATASTROPHIC, "radProcessInit failed: %s", 261: PROC_NAME_TEMPLATE2); 262: radMsgLogExit (); 263: 264: radSystemExit (TEMPLATE_SYSTEM_ID); 265: 266: exit (1); 267: } 268: 269: // save our process pid and create the lock file 270: templateWork.myPid = getpid (); 271: pidfile = fopen (pidName, "w"); 272: if (pidfile == NULL) 273: { 274: radMsgLog (PRI_CATASTROPHIC, "lock file create failed!\n"); 275: 276: radProcessExit (); 277: radSystemExit (TEMPLATE_SYSTEM_ID); 278: 279: exit (1); 280: } 281: fprintf (pidfile, "%d", templateWork.myPid); 282: fclose (pidfile); 283: 284: 285: // save the current alarm signal handler, set all signal handlers 286: // to the default handler, then set the alarm handler back to original 287: alarmHandler = radProcessSignalGetHandler (SIGALRM); 288: radProcessSignalCatchAll (defaultSigHandler); 289: radProcessSignalCatch (SIGALRM, alarmHandler); 290: 291: 292: // create our state machine - where all run-time work is done 293: templateWork.stateMachine = radStatesInit (&templateWork); 294: if (templateWork.stateMachine == NULL) 295: { 296: radMsgLog (PRI_HIGH, "radStatesInit failed"); 297: 298: radProcessExit (); 299: radSystemExit (TEMPLATE_SYSTEM_ID); 300: 301: exit (1); 302: } 303: 304: if (radStatesAddHandler (templateWork.stateMachine, TEMPLATE_STATE_IDLE, 305: template2IdleState) 306: == ERROR) 307: { 308: radMsgLog (PRI_HIGH, "radStatesAddHandler failed"); 309: radStatesExit (templateWork.stateMachine); 310: 311: radProcessExit (); 312: radSystemExit (TEMPLATE_SYSTEM_ID); 313: 314: exit (1); 315: } 316: if (radStatesAddHandler (templateWork.stateMachine, TEMPLATE_STATE_RUN, 317: template2RunState) 318: == ERROR) 319: { 320: radMsgLog (PRI_HIGH, "radStatesAddHandler failed"); 321: radStatesExit (templateWork.stateMachine); 322: 323: radProcessExit (); 324: radSystemExit (TEMPLATE_SYSTEM_ID); 325: 326: exit (1); 327: } 328: if (radStatesAddHandler (templateWork.stateMachine, TEMPLATE_STATE_ERROR, 329: template2ErrorState) 330: == ERROR) 331: { 332: radMsgLog (PRI_HIGH, "radStatesAddHandler failed"); 333: radStatesExit (templateWork.stateMachine); 334: 335: radProcessExit (); 336: radSystemExit (TEMPLATE_SYSTEM_ID); 337: 338: exit (1); 339: } 340: 341: radStatesSetState (templateWork.stateMachine, TEMPLATE_STATE_IDLE); 342: 343: 344: // initialize the radlib message router interface 345: if (radMsgRouterInit (".") == ERROR) 346: { 347: radMsgLog (PRI_HIGH, "radMsgRouterInit failed"); 348: radStatesExit (templateWork.stateMachine); 349: 350: radProcessExit (); 351: radSystemExit (TEMPLATE_SYSTEM_ID); 352: 353: exit (1); 354: } 355: 356: radMsgRouterMessageRegister (TEMPLATE_MSGID_USER_REQUEST); 357: 358: 359: radMsgLog (PRI_STATUS, "running ..."); 360: 361: 362: // dummy up a stimulus to get the state machine running 363: stim.type = STIM_DUMMY; 364: radStatesProcess (templateWork.stateMachine, &stim); 365: 366: 367: while (!templateWork.exiting) 368: { 369: // wait on timers, events, file descriptors, msgs, everything! 370: if (radProcessWait (0) == ERROR) 371: { 372: templateWork.exiting = TRUE; 373: } 374: } 375: 376: 377: radMsgLog (PRI_STATUS, "exiting normally..."); 378: 379: radStatesExit (templateWork.stateMachine); 380: templateSysExit (); 381: 382: radProcessExit (); 383: radSystemExit (TEMPLATE_SYSTEM_ID); 384: 385: exit (0); 386:} 387: