1 #include "ace/Service_Manager.h"
3 #include "ace/Get_Opt.h"
4 #include "ace/Log_Category.h"
5 #include "ace/Service_Repository.h"
6 #include "ace/Service_Config.h"
7 #include "ace/Service_Types.h"
8 #include "ace/Reactor.h"
9 #include "ace/WFMO_Reactor.h"
10 #include "ace/OS_NS_stdio.h"
11 #include "ace/OS_NS_string.h"
13 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
15 ACE_ALLOC_HOOK_DEFINE (ACE_Service_Manager
)
18 ACE_Service_Manager::dump () const
20 #if defined (ACE_HAS_DUMP)
21 ACE_TRACE ("ACE_Service_Manager::dump");
22 #endif /* ACE_HAS_DUMP */
27 u_short
ACE_Service_Manager::DEFAULT_PORT_
= 10000;
29 ACE_Service_Manager::ACE_Service_Manager ()
33 ACE_TRACE ("ACE_Service_Manager::ACE_Service_Manager");
36 ACE_Service_Manager::~ACE_Service_Manager ()
38 ACE_TRACE ("ACE_Service_Manager::~ACE_Service_Manager");
42 ACE_Service_Manager::suspend ()
44 ACE_TRACE ("ACE_Service_Manager::suspend");
45 return ACE_Reactor::instance ()->suspend_handler (this);
49 ACE_Service_Manager::resume ()
51 ACE_TRACE ("ACE_Service_Manager::resume");
52 return ACE_Reactor::instance ()->resume_handler (this);
56 ACE_Service_Manager::open (const ACE_INET_Addr
&sia
)
58 ACE_TRACE ("ACE_Service_Manager::open");
60 // Reuse the listening address, even if it's already in use!
61 if (this->acceptor_
.open (sia
, 1) == -1)
70 ACE_Service_Manager::info (ACE_TCHAR
**strp
, size_t length
) const
72 ACE_TRACE ("ACE_Service_Manager::info");
74 ACE_TCHAR buf
[BUFSIZ
];
76 if (this->acceptor_
.get_local_addr (sa
) == -1)
81 ACE_OS::snprintf (buf
, BUFSIZ
,
82 ACE_TEXT ("%d/%s %s"),
83 sa
.get_port_number (),
85 ACE_TEXT ("# lists all services in the daemon\n"));
87 if (*strp
== 0 && (*strp
= ACE_OS::strdup (buf
)) == 0)
93 ACE_OS::strsncpy (*strp
, buf
, length
);
96 return static_cast<int> (ACE_OS::strlen (buf
));
100 ACE_Service_Manager::init (int argc
, ACE_TCHAR
*argv
[])
102 ACE_TRACE ("ACE_Service_Manager::init");
103 ACE_INET_Addr
local_addr (ACE_Service_Manager::DEFAULT_PORT_
);
105 //FUZZ: disable check_for_lack_ACE_OS
106 ACE_Get_Opt
getopt (argc
, argv
, ACE_TEXT ("dp:s:"), 0); // Start at argv[0]
108 for (int c
; (c
= getopt ()) != -1; )
109 //FUZZ: enable check_for_lack_ACE_OS
116 local_addr
.set ((u_short
) ACE_OS::atoi (getopt
.opt_arg ()));
119 this->signum_
= ACE_OS::atoi (getopt
.opt_arg ());
125 if (this->get_handle () == ACE_INVALID_HANDLE
&&
126 this->open (local_addr
) == -1)
128 ACELIB_ERROR_RETURN ((LM_ERROR
,
130 ACE_TEXT ("open")), -1);
132 else if (ACE_Reactor::instance ()->register_handler
134 ACE_Event_Handler::ACCEPT_MASK
) == -1)
136 ACELIB_ERROR_RETURN ((LM_ERROR
,
137 ACE_TEXT ("registering service with ACE_Reactor\n")),
145 ACE_Service_Manager::handle_close (ACE_HANDLE
, ACE_Reactor_Mask
)
147 ACE_TRACE ("ACE_Service_Manager::handle_close");
148 return this->acceptor_
.close ();
152 ACE_Service_Manager::fini ()
154 ACE_TRACE ("ACE_Service_Manager::fini");
158 if (this->get_handle () != ACE_INVALID_HANDLE
)
161 ACE_Reactor::instance ()->remove_handler (
163 ACE_Event_Handler::ACCEPT_MASK
| ACE_Event_Handler::DONT_CALL
);
165 this->handle_close (ACE_INVALID_HANDLE
,
166 ACE_Event_Handler::NULL_MASK
);
173 ACE_Service_Manager::get_handle () const
175 ACE_TRACE ("ACE_Service_Manager::get_handle");
176 return this->acceptor_
.get_handle ();
180 ACE_Service_Manager::handle_signal (int, siginfo_t
*, ucontext_t
*)
185 // Determine all the services offered by this daemon and return the
186 // information back to the client.
189 ACE_Service_Manager::list_services ()
191 ACE_TRACE ("ACE_Service_Manager::list_services");
192 ACE_Service_Repository_Iterator
sri (*ACE_Service_Repository::instance (), 0);
194 for (const ACE_Service_Type
*sr
;
198 ssize_t len
= static_cast<ssize_t
> (ACE_OS::strlen (sr
->name ())) + 11;
199 ACE_TCHAR buf
[BUFSIZ
];
200 ACE_TCHAR
*p
= buf
+ len
;
202 ACE_OS::strcpy (buf
, sr
->name ());
203 ACE_OS::strcat (buf
, (sr
->active ()) ?
204 ACE_TEXT (" (active) ") :
205 ACE_TEXT (" (paused) "));
210 len
+= sr
->type ()->info (&p
, sizeof buf
- len
);
214 ACELIB_DEBUG ((LM_DEBUG
,
215 ACE_TEXT ("len = %d, info = %s%s"),
218 buf
[len
- 1] == '\n' ? ACE_TEXT ("") : ACE_TEXT ("\n")));
223 ssize_t n
= this->client_stream_
.send_n (buf
, len
);
225 if (n
<= 0 && errno
!= EPIPE
)
227 ACELIB_ERROR ((LM_ERROR
,
229 ACE_TEXT ("send_n")));
237 // Trigger a reconfiguration of the Service Configurator via its
241 ACE_Service_Manager::reconfigure_services ()
243 ACE_TRACE ("ACE_Service_Manager::reconfigure_services");
246 // Send ourselves a signal! ACE_OS::kill (ACE_OS::getpid (),
250 // Flag the main event loop that a reconfiguration should occur.
251 // The next trip through the <ACE_Reactor::run_event_loop> should
252 // pick this up and cause a reconfiguration. Note that we can't
253 // trigger the reconfiguration automatically since that might "pull
254 // the rug" out from underneath the existing services in a
256 ACE_Service_Config::reconfig_occurred ((sig_atomic_t) 1);
257 return static_cast<int> (this->client_stream_
.send_n ("done\n",
261 // isolate the request-processing code
263 ACE_Service_Manager::process_request (ACE_TCHAR
*request
)
265 ACE_TRACE("ACE_Service_Manager::process_request");
268 // Kill trailing newlines.
270 (*p
!= '\0') && (*p
!= '\r') && (*p
!= '\n');
278 if (ACE_OS::strcmp (request
, ACE_TEXT ("help")) == 0)
280 // Return a list of the configured services.
281 this->list_services ();
283 else if (ACE_OS::strcmp (request
, ACE_TEXT ("reconfigure") )== 0)
285 // Trigger a reconfiguration by re-reading the local <svc.conf> file.
286 this->reconfigure_services ();
290 // Just process a single request passed in via the socket
292 ACE_Service_Config_Guard
guard (ACE_Service_Config::global ());
293 ACE_Service_Config::process_directive (request
);
296 // Additional management services may be handled here...
299 // Accept new connection from client and carry out the service they
303 ACE_Service_Manager::handle_input (ACE_HANDLE
)
305 ACE_TRACE ("ACE_Service_Manager::handle_input");
307 // Try to find out if the implementation of the reactor that we are
308 // using requires us to reset the event association for the newly
309 // created handle. This is because the newly created handle will
310 // inherit the properties of the listen handle, including its event
312 bool reset_new_handle
=
313 ACE_Reactor::instance ()->uses_event_associations ();
315 if (this->acceptor_
.accept (this->client_stream_
, // stream
319 reset_new_handle
// reset new handler
327 ACELIB_DEBUG ((LM_DEBUG
,
328 ACE_TEXT ("client_stream fd = %d\n"),
329 this->client_stream_
.get_handle ()));
332 if (this->client_stream_
.get_remote_addr (sa
) == -1)
337 ACELIB_DEBUG ((LM_DEBUG
,
338 ACE_TEXT ("accepted from host %C at port %d\n"),
340 sa
.get_port_number ()));
343 ACE_TCHAR request
[BUFSIZ
];
344 ACE_TCHAR
* offset
= request
;
345 ssize_t remaining
= sizeof (request
);
347 // Read service request from client.
351 // Keep looping until we actually get the request. Note that Win32
352 // sets the socket into non-blocking mode, so we may need to loop if
353 // the system is heavily loaded. Read bytes into the buffer until a
354 // '\n' or '\r' is found in the buffer, otherwise the buffer
355 // contains an incomplete string.
361 result
= client_stream_
.recv (offset
, remaining
);
364 if (result
== 0 && error
!= EWOULDBLOCK
)
371 if ((remaining
-= result
) <= 0)
373 ACELIB_DEBUG ((LM_ERROR
,
374 ACE_TEXT ("Request buffer overflow.\n")));
382 if (ACE_OS::strchr (request
, '\r') != 0
383 || ACE_OS::strchr (request
, '\n') != 0)
389 while ((result
== -1 && error
== EWOULDBLOCK
) || remaining
> 0);
396 ACELIB_DEBUG ((LM_ERROR
,
407 ACE_Event_Handler
*old_signal_handler
= 0;
408 ACE_Reactor::instance ()->register_handler (SIGPIPE
,
411 &old_signal_handler
);
413 this->process_request (request
);
415 // Restore existing SIGPIPE handler
416 ACE_Reactor::instance ()->register_handler (SIGPIPE
,
421 if (this->client_stream_
.close () == -1 && this->debug_
)
423 ACELIB_DEBUG ((LM_ERROR
,
425 ACE_TEXT ("close")));
431 ACE_END_VERSIONED_NAMESPACE_DECL