📄 stafprocosutil.cpp
字号:
/*****************************************************************************//* Software Testing Automation Framework (STAF) *//* (C) Copyright IBM Corp. 2001 *//* *//* This software is licensed under the Common Public License (CPL) V1.0. *//*****************************************************************************/#include "STAF.h"#include "STAF_iostream.h"#include <pthread.h>#include <sys/stat.h>#include <sys/types.h>#include <sys/file.h>#include <unistd.h>#include <errno.h>#include <fcntl.h>#include <signal.h>#include "STAFProc.h"#include "STAFProcOSUtil.h"#include "STAFUtil.h"#include "STAFTrace.h"unsigned int makePerformanceAdjustments(STAFPerfInfo perfInfo, STAFString& errorBuffer, unsigned int& osRC){ osRC = 0; errorBuffer = ""; return 0;}void generic_signal_handler(int signum){ STAFString error = STAFString("Received signal ") + STAFString(signum); switch (signum) { case SIGQUIT: { STAFTrace::trace(kSTAFTraceError, error + " (SIGQUIT)"); (*gShutdownSemaphorePtr)->post(); break; } case SIGINT: { STAFTrace::trace(kSTAFTraceError, error + " (SIGINT)"); (*gShutdownSemaphorePtr)->post(); break; } case SIGTERM: { STAFTrace::trace(kSTAFTraceError, error + " (SIGTERM)"); (*gShutdownSemaphorePtr)->post(); break; } case SIGFPE: { STAFTrace::trace(kSTAFTraceError, error + " (SIGFPE)"); abort(); break; } case SIGABRT: { STAFTrace::trace(kSTAFTraceError, error + " (SIGABRT)"); break; } case SIGILL: { STAFTrace::trace(kSTAFTraceError, error + " (SIGILL)"); abort(); break; } case SIGSEGV: { STAFTrace::trace(kSTAFTraceError, error + " (SIGSEGV)"); abort(); break; } default: { STAFTrace::trace(kSTAFTraceError, error + " (Unknown)"); } }}static const char *staflck = "/tmp/";static const char *stafipc = "/tmp/STAFIPC_";static const char *datadirlck = "/tmp/DataDir_";static int staflckdes = -1;static int datadirlckdes = -1;unsigned int STAFProcOSInit(STAFString &errorBuffer, unsigned int &osRC){ // Set up our signal handling struct sigaction sa; sa.sa_handler = SIG_IGN; sigfillset(&sa.sa_mask); sa.sa_flags = 0; if (sigaction(SIGTTOU, &sa, 0) < 0) { errorBuffer = "Unable to set SIGTTOU to SIG_IGN"; osRC = errno; return 1; } if (sigaction(SIGPIPE, &sa, 0) < 0) { errorBuffer = "Unable to set SIGPIPE to SIG_IGN"; osRC = errno; return 1; } sa.sa_handler = generic_signal_handler; if (sigaction(SIGFPE, &sa, 0) < 0) { errorBuffer = "Unable to set signal handler for SIGFPE"; osRC = errno; return 1; } if (sigaction(SIGILL, &sa, 0) < 0) { errorBuffer = "Unable to set signal handler for SIGILL"; osRC = errno; return 1; } if (sigaction(SIGSEGV, &sa, 0) < 0) { errorBuffer = "Unable to set signal handler for SIGSEGV"; osRC = errno; return 1; } if (sigaction(SIGABRT, &sa, 0) < 0) { errorBuffer = "Unable to set signal handler for SIGABRT"; osRC = errno; return 1; } if (sigaction(SIGINT, &sa, 0) < 0) { errorBuffer = "Unable to set signal handler for SIGINT"; osRC = errno; return 1; } if (sigaction(SIGQUIT, &sa, 0) < 0) { errorBuffer = "Unable to set signal handler for SIGQUIT"; osRC = errno; return 1; } if (sigaction(SIGTERM, &sa, 0) < 0) { errorBuffer = "Unable to set signal handler for SIGTERM"; osRC = errno; return 1; } // create a temporary file to serve as indicator that STAFProc // is already running. if (umask(0) == -1) { errorBuffer = "Unable to set umask"; osRC = errno; return 1; } STAFString staflckInstance; staflckInstance = STAFString(staflck) + (*gSTAFInstanceNamePtr) + ".tmp" + STAFString(kUTF8_NULL); staflckdes = open(staflckInstance.toCurrentCodePage()->buffer(), O_CREAT | O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO); struct flock theLock = { 0 }; theLock.l_type = F_WRLCK; if (fcntl(staflckdes, F_SETLK, &theLock) == -1) { osRC = errno; errorBuffer = "STAFProc already running"; return 1; } return 0;}unsigned int STAFProcOSLockDataDir(STAFString &errorBuffer, unsigned int &osRC){ STAFString datadirlckInstance; datadirlckInstance = STAFString(datadirlck) + (*gSTAFWriteLocationPtr).replace(kUTF8_SLASH, kUTF8_HYPHEN) + ".tmp" + STAFString(kUTF8_NULL); datadirlckdes = open(datadirlckInstance.toCurrentCodePage()->buffer(), O_CREAT | O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO); struct flock theLock = { 0 }; theLock.l_type = F_WRLCK; if (fcntl(datadirlckdes, F_SETLK, &theLock) == -1) { osRC = errno; errorBuffer = "Data directory in use"; return 1; } return 0;}unsigned int STAFProcOSTerm(STAFString &errorBuffer, unsigned int &osRC){ // here we unlock the file and on success, flock returns 0 and unlocks // the file, otherwise, it fails with -1 (but this should not happen) struct flock theLock = { 0 }; theLock.l_type = F_UNLCK; STAFString staflckInstance; staflckInstance = STAFString(staflck) + *gSTAFInstanceNamePtr + ".tmp" + STAFString(kUTF8_NULL); if (fcntl(staflckdes, F_SETLK, &theLock) == -1) { osRC = errno; errorBuffer = "Unable to unlock " + staflckInstance; return 1; } if (unlink(staflckInstance.toCurrentCodePage()->buffer()) == -1) { osRC = errno; errorBuffer = "Could not remove " + staflckInstance; return 1; } // Data dir lock STAFString datadirlckInstance; datadirlckInstance = STAFString(datadirlck) + (*gSTAFWriteLocationPtr).replace(kUTF8_SLASH, kUTF8_HYPHEN) + ".tmp" + STAFString(kUTF8_NULL); if (fcntl(datadirlckdes, F_SETLK, &theLock) == -1) { osRC = errno; errorBuffer = "Unable to unlock " + datadirlckInstance; return 1; } if (unlink(datadirlckInstance.toCurrentCodePage()->buffer()) == -1) { osRC = errno; errorBuffer = "Could not remove " + datadirlckInstance; return 1; } STAFString stafipcInstance; stafipcInstance = STAFString(stafipc) + *gSTAFInstanceNamePtr + STAFString(kUTF8_NULL); if (unlink(stafipcInstance.toCurrentCodePage()->buffer()) == -1) { osRC = errno; errorBuffer = "Could not remove " + stafipcInstance; return 1; } return 0;}// The following is all code written by Dan Lepore to handle signals for// AIX. This code will probably be reincorporated once I figure out exactly// how/which signals should be handled. Note, there are definite platform// differences as to which signals exist.#if 0#include <signal.h>#include <sys/context.h>#include <sys/mstsave.h>#include <assert.h>void HandleSignal(unsigned long);void staf_errhandler(int, int, struct sigcontext *);STAFEventSem gSigThread;stafproc_main(){ gSigThread.reset(); // reset the signal thread wait semaphore gThreadManagerPtr->dispatch(new STAFThreadFunc(HandleSignal,0)); gSigThread.wait();}stafProcTerminate(){ int pid; int rc; if ((pid = fork ()) != 0) { // parent process // if fork failed, parent returns error, otherwise returns ok if (pid == -1) { system("./cleanstaf.ksh 2>/dev/null"); exit(1); } } else { rc = execlp("./cleanstaf",NULL); printf("rc = %d\n",rc); exit(1); } exit(1);}void _System HandleSignal(unsigned long nada){ struct sigaction action; sigset_t set; sigset_t setasynch; long rc; int sig; int pid; // set up signal handling for exception conditions. action.sa_handler = (void(*)(int))staf_errhandler; sigemptyset(&set); // empty set blocked in handler action.sa_mask = set; // update sigaction mask action.sa_flags = 0x0; // zero all flags rc = sigaction(SIGILL,&action,NULL); // illegal op assert (rc == 0); rc = sigaction(SIGSEGV,&action,NULL); // addressing assert(rc == 0); // Now, set up signal handling for asynch events. sigemptyset(&setasynch); /* null set blocked */ sigaddset(&setasynch, SIGINT); /* handle interrupt */ sigaddset(&setasynch, SIGTERM); /* handle termination */ sigthreadmask(SIG_BLOCK, &set, NULL); /* block for signal */ // Post Main thread. gSigThread.post(); // Issue sigwait to block waiting for termination. rc = sigwait(&setasynch, &sig); gShutdownSemaphore->post(); if ((pid = fork ()) != 0) { // parent process // if fork failed, parent returns error, otherwise returns ok if (pid == -1) { system("./cleanstaf.ksh 2>/dev/null"); exit(1); } } else { rc = execlp("./cleanstaf",NULL); printf("rc = %d\n",rc); exit(1); } exit(1);}void staf_errhandler(int signal, int code, struct sigcontext *scp){ int rc = 0; int pid = 0; STAFTrace::trace( kSTAFTraceError, "STAFProc: Signal Received - exception detected. Exception Type: " + STAFString(scp->sc_jmpbuf.jmp_context.excp_type)); gShutdownSemaphore->post(); if ((pid = fork ()) != 0) { // parent process // if fork failed, parent returns error, otherwise returns ok if (pid == -1) { system("./cleanstaf.ksh 2>/dev/null"); exit(1); } } else { rc = execlp("./cleanstaf",NULL); printf("rc = %d\n",rc); exit(1); } abort();}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -