Merge pull request #2216 from jwillemsen/jwi-cxxversionchecks
[ACE_TAO.git] / ACE / examples / NT_Service / main.cpp
blobfd3a982bc6834723cb23d731cd4d0b8cf78db9a3
2 //=============================================================================
3 /**
4 * @file main.cpp
6 * This is the main program - it just hands control off to the
7 * process instance to figure out what to do. This program only
8 * runs on Win32.
10 * @author Gonzalo Diethelm <gonzo@cs.wustl.edu> and Steve Huston <shuston@riverace.com>
12 //=============================================================================
15 #include "ace/Get_Opt.h"
16 #include "ace/Init_ACE.h"
17 #include "ntsvc.h"
19 #if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_SERVICES)
20 // FUZZ: disable check_for_streams_include
21 #include "ace/streams.h"
22 #include "ace/OS_NS_errno.h"
24 // Default for the -i (install) option
25 #define DEFAULT_SERVICE_INIT_STARTUP SERVICE_AUTO_START
27 class Process
29 public:
30 Process ();
31 ~Process ();
33 int run(int argc, ACE_TCHAR* argv[]);
35 private:
36 void parse_args (int argc,
37 ACE_TCHAR* argv[]);
38 void print_usage_and_die ();
40 private:
41 char progname[128];
43 int opt_install;
44 int opt_remove;
45 int opt_start;
46 int opt_kill;
47 int opt_type;
48 int opt_debug;
50 int opt_startup;
53 typedef ACE_Singleton<Process, ACE_Mutex> PROCESS;
55 Process::Process ()
56 : opt_install (0),
57 opt_remove (0),
58 opt_start (0),
59 opt_kill (0),
60 opt_type (0),
61 opt_debug (0),
62 opt_startup (0)
64 ACE_OS::strcpy (progname,
65 "service");
66 ACE::init ();
69 Process::~Process ()
71 ACE::fini ();
74 void
75 Process::print_usage_and_die ()
77 ACE_DEBUG ((LM_INFO,
78 "Usage: %s"
79 " -in -r -s -k -tn -d\n"
80 " -i: Install this program as an NT service, with specified startup\n"
81 " -r: Remove this program from the Service Manager\n"
82 " -s: Start the service\n"
83 " -k: Kill the service\n"
84 " -t: Set startup for an existing service\n"
85 " -d: Debug; run as a regular application\n",
86 progname,
87 0));
88 ACE_OS::exit(1);
91 void
92 Process::parse_args (int argc, ACE_TCHAR* argv[])
94 ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("i:rskt:d"));
95 int c;
97 while ((c = get_opt ()) != -1)
98 switch (c)
100 case 'i':
101 opt_install = 1;
102 opt_startup = ACE_OS::atoi (get_opt.opt_arg ());
103 if (opt_startup <= 0)
104 print_usage_and_die ();
105 break;
106 case 'r':
107 opt_remove = 1;
108 break;
109 case 's':
110 opt_start = 1;
111 break;
112 case 'k':
113 opt_kill = 1;
114 break;
115 case 't':
116 opt_type = 1;
117 opt_startup = ACE_OS::atoi (get_opt.opt_arg ());
118 if (opt_startup <= 0)
119 print_usage_and_die ();
120 break;
121 case 'd':
122 opt_debug = 1;
123 break;
124 default:
125 // -i can also be given without a value - if so, it defaults
126 // to defined value.
127 if (ACE_OS::strcmp (get_opt.argv ()[get_opt.opt_ind () - 1], ACE_TEXT ("-i")) == 0)
129 opt_install = 1;
130 opt_startup = DEFAULT_SERVICE_INIT_STARTUP;
132 else
134 print_usage_and_die ();
136 break;
140 // Define a function to handle Ctrl+C to cleanly shut this down.
142 static BOOL WINAPI
143 ConsoleHandler (DWORD /*ctrlType*/)
145 SERVICE::instance ()->handle_control (SERVICE_CONTROL_STOP);
146 return TRUE;
149 ACE_NT_SERVICE_DEFINE (Beeper,
150 Service,
151 ACE_TEXT ("Annoying Beeper Service"));
154 Process::run (int argc, ACE_TCHAR* argv[])
156 SERVICE::instance ()->name (ACE_TEXT ("Beeper"),
157 ACE_TEXT ("Annoying Beeper Service"));
159 parse_args (argc, argv);
161 if (opt_install && !opt_remove)
163 if (-1 == SERVICE::instance ()->insert (opt_startup))
165 ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("insert")));
166 return -1;
168 return 0;
171 if (opt_remove && !opt_install)
173 if (-1 == SERVICE::instance ()->remove ())
175 ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("remove")));
176 return -1;
178 return 0;
181 if (opt_start && opt_kill)
182 print_usage_and_die ();
184 if (opt_start)
186 if (-1 == SERVICE::instance ()->start_svc ())
188 ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("start")));
189 return -1;
191 return 0;
194 if (opt_kill)
196 if (-1 == SERVICE::instance ()->stop_svc ())
198 ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("stop")));
199 return -1;
201 return 0;
204 if (opt_type)
206 if (-1 == SERVICE::instance ()->startup (opt_startup))
208 ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("set startup")));
209 return -1;
211 return 0;
214 // If we get here, we either run the app in debug mode (-d) or are
215 // being called from the service manager to start the service.
217 if (opt_debug)
219 SetConsoleCtrlHandler (&ConsoleHandler, 1);
220 SERVICE::instance ()->svc ();
222 else
224 ofstream *output_file = new ofstream("ntsvc.log", ios::out);
225 if (output_file && output_file->rdstate() == ios::goodbit)
226 ACE_LOG_MSG->msg_ostream(output_file, 1);
227 ACE_LOG_MSG->open(argv[0],
228 ACE_Log_Msg::STDERR | ACE_Log_Msg::OSTREAM,
230 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%T (%t): Starting service.\n")));
232 ACE_NT_SERVICE_RUN (Beeper,
233 SERVICE::instance (),
234 ret);
235 if (ret == 0)
236 ACE_ERROR ((LM_ERROR,
237 ACE_TEXT ("%p\n"),
238 ACE_TEXT ("Couldn't start service")));
239 else
240 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%T (%t): Service stopped.\n")));
243 return 0;
247 ACE_TMAIN (int argc, ACE_TCHAR* argv[])
249 return PROCESS::instance ()->run (argc, argv);
252 #else
254 #include "ace/OS_main.h"
257 ACE_TMAIN (int, ACE_TCHAR*[])
259 // This program needs Windows services.
260 return 0;
263 #endif /* ACE_WIN32 && !ACE_LACKS_WIN32_SERVICES */