OpcUaCanOpen
CANopen OPC-UA server
shutdown.cpp
Go to the documentation of this file.
1 /******************************************************************************
2 ** shutdown.cpp
3 **
4 ** Copyright (c) 2006-2016 Unified Automation GmbH. All rights reserved.
5 **
6 ** Software License Agreement ("SLA") Version 2.5
7 **
8 ** Unless explicitly acquired and licensed from Licensor under another
9 ** license, the contents of this file are subject to the Software License
10 ** Agreement ("SLA") Version 2.5, or subsequent versions
11 ** as allowed by the SLA, and You may not copy or use this file in either
12 ** source code or executable form, except in compliance with the terms and
13 ** conditions of the SLA.
14 **
15 ** All software distributed under the SLA is provided strictly on an
16 ** "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
17 ** AND LICENSOR HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
18 ** LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
19 ** PURPOSE, QUIET ENJOYMENT, OR NON-INFRINGEMENT. See the SLA for specific
20 ** language governing rights and limitations under the SLA.
21 **
22 ** The complete license agreement can be found here:
23 ** http://unifiedautomation.com/License/SLA/2.5/
24 **
25 ** Project: C++ OPC Server SDK sample code
26 **
27 ** Description: Portable shutdown flag using CTRL-C (SIGINT)
28 ** Notes: Visual Studio catches CTRL-C when it's thrown by default,
29 ** which is not wanted normally. You can disable this by opening the
30 ** exceptions dialog via the menu Debug->Exceptions. Then deactivate
31 ** the "CTRL-C" exception in the "Win32 Exceptions" category.
32 **
33 ******************************************************************************/
34 #include "shutdown.h"
35 #include "uaplatformlayer.h"
36 
37 #include <stdio.h>
38 #include <string.h>
39 
40 # ifndef WIN32
41 # include <unistd.h>
42 # include <limits.h>
43 # endif
44 
45 /* shutdown flag */
46 static volatile unsigned int g_ShutDown = 0;
47 
48 #ifdef _WIN32_WCE
49 # include <windows.h>
50 #elif defined(_WIN32) && !defined(USE_CTRLC_ON_WINDOWS)
51 # include <conio.h> /* DOS header for _kbhit() and _getch() */
52 #endif
53 
54 /* Return shutdown flag. */
55 unsigned int ShutDownFlag()
56 {
57 #if defined(_WIN32) && !defined(USE_CTRLC_ON_WINDOWS)
58  #ifndef _WIN32_WCE
59  if (_kbhit() && _getch() == 'x') return 1;
60  else return 0;
61  #else
62  if (GetAsyncKeyState(VK_ESCAPE)) return 1;
63  else return 0;
64  #endif
65 #else
66  return g_ShutDown;
67 #endif
68 }
69 
70 /****************************************
71  * Linux SIGINT Handler implementation. *
72  ****************************************/
73 #ifdef __linux__
74 #include <signal.h>
75 
77 void signal_handler(int signo)
78 {
79  SHUTDOWN_TRACE("Received signal %i\n", signo);
80  g_ShutDown = 1;
81 }
82 
84 {
85  /* register signal handlers. */
86  struct sigaction new_action, old_action;
87 
88  /* Set up the structure to specify the new action. */
89  new_action.sa_handler = signal_handler;
90  sigemptyset(&new_action.sa_mask);
91  new_action.sa_flags = 0;
92 
93  /* install new signal handler for SIGINT */
94  sigaction(SIGINT, NULL, &old_action);
95  if (old_action.sa_handler != SIG_IGN)
96  {
97  sigaction(SIGINT, &new_action, NULL);
98  }
99  /* install new signal handler for SIGTERM */
100  sigaction(SIGTERM, NULL, &old_action);
101  if (old_action.sa_handler != SIG_IGN)
102  {
103  sigaction(SIGTERM, &new_action, NULL);
104  }
105 
106  /* Set up the structure to prevent program termination on interrupted connections. */
107  new_action.sa_handler = SIG_IGN;
108  sigemptyset(&new_action.sa_mask);
109  new_action.sa_flags = 0;
110 
111  /* install new signal handler for SIGPIPE*/
112  sigaction(SIGPIPE, NULL, &old_action);
113  if (old_action.sa_handler != SIG_IGN)
114  {
115  sigaction(SIGPIPE, &new_action, NULL);
116  }
117 }
118 #elif defined(_WIN32)
119 /******************************************
120  * Windows CTRL-C Handler implementation. *
121  ******************************************/
122 # ifdef USE_CTRLC_ON_WINDOWS
123 # include <windows.h>
124 # include <conio.h>
125 BOOL CtrlHandler(DWORD fdwCtrlType)
126 {
127  switch ( fdwCtrlType )
128  {
129  // Handle the CTRL-C signal.
130  case CTRL_C_EVENT:
131  SHUTDOWN_TRACE("Received CTRL-C signal.\n");
132  g_ShutDown = 1;
133  return( TRUE );
134  default:
135  break;
136  }
137  return FALSE;
138 }
140 {
141  SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, TRUE );
142 }
143 # else /* USE_CTRLC_ON_WINDOWS */
145 {
146 }
147 # endif /* USE_CTRLC_ON_WINDOWS */
148 #else /* __linux__ */
149 /********************************************************************
150  * Dummy implementation for embedded systems. They never shut down. *
151  ********************************************************************/
153 {
154 }
155 #endif
156 
157 char* getAppPath()
158 {
159  char* pszAppPath = NULL;
160  char* pszFind = NULL;
161  int maxPath = 0;
162 #ifdef _WIN32
163 #ifdef _WIN32_WCE
164  TCHAR result[MAX_PATH];
165  char szAppPath[MAX_PATH];
166  maxPath = MAX_PATH;
167  GetModuleFileName(NULL, result, MAX_PATH);
168  for ( int i=0; i<MAX_PATH; i++ ) szAppPath[i] = (char)result[i];
169  pszFind = strrchr(szAppPath, '\\');
170 #else // #ifdef _WIN32_WCE
171  char szAppPath[MAX_PATH];
172  maxPath = MAX_PATH;
173  GetModuleFileNameA(NULL, szAppPath, MAX_PATH);
174  szAppPath[MAX_PATH-1] = 0;
175  pszFind = strrchr(szAppPath, '\\');
176 #endif // #ifdef _WIN32_WCE
177 #elif defined(__QNX__)
178  char szAppPath[PATH_MAX] = {0};
179  getcwd(szAppPath, sizeof(szAppPath)-1);
180 #else // #ifdef _WIN32
181  char szAppPath[PATH_MAX];
182  maxPath = PATH_MAX;
183  memset(szAppPath, 0, sizeof(szAppPath)); /* initialize with zeros, readlink does not null terminate the string */
184 #if defined (VXWORKS)
185  strncpy(szAppPath, "ide0:/ESystem/opcua/dummy.exe", sizeof(szAppPath)-1);
186 #else //defined (VXWORKS)
187  if ( readlink("/proc/self/exe", szAppPath, sizeof(szAppPath)-1) < 0 )
188  {
189  return NULL;
190  }
191 #endif //defined (VXWORKS)
192  pszFind = strrchr(szAppPath, '/');
193 #endif // #ifdef _WIN32
194  if (pszFind)
195  {
196  *pszFind = 0; // cut off appname
197  }
198  pszAppPath = new char [maxPath+1];
199  pszAppPath[maxPath] = 0;
200  strncpy(pszAppPath, szAppPath, strlen(szAppPath)+1);
201 
202  return pszAppPath;
203 }