implemented server_probe(int *pid) that used monitor interface

to probe server status.  Also returns PID if running (Linux only).
This commit is contained in:
gardners 2012-05-21 20:45:07 +09:30
parent 6f09128d9c
commit e44294ea66
3 changed files with 90 additions and 4 deletions

View File

@ -799,14 +799,23 @@ int app_server_status(int argc, const char *const *argv, struct command_line_opt
{
if (cli_arg(argc, argv, o, "instance path", &thisinstancepath, cli_absolute_path, NULL) == -1)
return -1;
int pid = server_pid();
if (pid < 0)
return -1;
int pid=-1;
int status=server_probe(&pid);
cli_puts("instancepath");
cli_delim(":");
cli_puts(serval_instancepath());
cli_delim("\n");
if (pid) {
cli_puts("status");
cli_delim(":");
switch(status) {
case SERVER_NOTRESPONDING: cli_puts("not responding"); break;
case SERVER_NOTRUNNING: cli_puts("stopped"); break;
case SERVER_RUNNING: cli_puts("running"); break;
case SERVER_UNKNOWN: default: cli_puts("unknown"); break;
}
cli_delim("\n");
if (pid>-1) {
cli_puts("pid");
cli_delim(":");
cli_printf("%d", pid);

View File

@ -693,3 +693,74 @@ int monitor_tell_clients(unsigned char *msg,int msglen,int mask)
}
return 0;
}
/* Check if there is a running server, and whether it is responding or not.
*/
int server_probe(int *pid)
{
int fd=-1;
struct sockaddr_un addr;
if ( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
return SERVER_UNKNOWN;
}
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
addr.sun_path[0]=0;
snprintf(&addr.sun_path[1],100,"org.servalproject.servald.monitor.socket");
int len = 1+strlen(&addr.sun_path[1]) + sizeof(addr.sun_family);
char *p=(char *)&addr;
printf("last char='%c' %02x\n",p[len-1],p[len-1]);
if (connect(fd, (struct sockaddr*)&addr, len) == -1) {
close(fd);
return SERVER_NOTRUNNING;
}
/* Give the server 2 seconds to send us something */
struct pollfd fds[1];
fds[0].fd=fd;
fds[0].events=POLLIN;
poll(fds,1,2000);
fcntl(fd,F_SETFL,fcntl(fd, F_GETFL, NULL)|O_NONBLOCK);
*pid=-1;
if (pid!=NULL) {
#if defined(HAVE_LINUX_STRUCT_UCRED)
struct ucred ucred;
#elif defined(HAVE_BSD_STRUCT_UCRED)
struct xucred ucred;
#else
#error "Unknown ucred struct"
#endif
socklen_t len=sizeof(ucred);
int res=getsockopt(fd,SOL_SOCKET,SO_PEERCRED,&ucred,&len);
if (len>sizeof(ucred)) {
WHYF("This is likely to be bad (memory overrun by getsockopt())");
}
if (res) {
WHY("Failed to read credentials of monitor.socket client");
} else {
#if defined(HAVE_LINUX_STRUCT_UCRED)
*pid = ucred.pid;
#elif defined(HAVE_BSD_STRUCT_UCRED)
#warning cannot get PID from ucred on BSD
*pid = -1;
#endif
}
}
char buff[1024];
int bytes=read(fd,buff,1024);
close(fd);
if (bytes<0) {
return SERVER_NOTRESPONDING;
} else if (bytes==0) {
// Could just be really busy.
return SERVER_NOTRESPONDING;
} else {
return SERVER_RUNNING;
}
}

View File

@ -1497,3 +1497,9 @@ int bufferAudioForPlayback(int codec,long long start_time,long long end_time,
unsigned char *data,int dataLen);
int startAudio();
int stopAudio();
#define SERVER_UNKNOWN 1
#define SERVER_NOTRESPONDING 2
#define SERVER_NOTRUNNING 3
#define SERVER_RUNNING 4
int server_probe(int *pid);