#include <syslog.h>
#include <pwd.h>
#include <grp.h>
-#include <ctype.h>
#include <limits.h>
+#include <fcntl.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
-#include <sys/fcntl.h>
+#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
_exit(exitstatus);
}
-static void NONRETURNING sighandler_chld(int ignored) {
+static void reporttermination(int status) {
struct progress_msg progress_mbuf;
+
+ memset(&progress_mbuf,0,sizeof(progress_mbuf));
+ progress_mbuf.magic= PROGRESS_MAGIC;
+ progress_mbuf.type= pt_terminated;
+ progress_mbuf.data.terminated.status= status;
+ xfwrite(&progress_mbuf,sizeof(progress_mbuf),swfile);
+ xfflush(swfile);
+}
+
+static void NONRETURNING sighandler_chld(int ignored) {
int status;
pid_t returned;
if (returned!=child) syscallerror("spurious child process");
child= childtokill= -1;
- memset(&progress_mbuf,0,sizeof(progress_mbuf));
- progress_mbuf.magic= PROGRESS_MAGIC;
- progress_mbuf.type= pt_terminated;
- progress_mbuf.data.terminated.status= status;
- xfwrite(&progress_mbuf,sizeof(progress_mbuf),swfile);
- xfflush(swfile);
-
+ reporttermination(status);
syslog(LOG_INFO,"service completed (status %d %d)",(status>>8)&0x0ff,status&0x0ff);
_exit(0);
}
getevent(&event_mbuf);
assert(event_mbuf.type == et_confirm);
+ if (execbuiltin == bisexec_shutdown && !serviceuser_uid) {
+ /* The check for the uid is just so we can give a nice
+ * error message (in the actual code for bisexec_shutdown).
+ * If this is spoofed somehow then the unlink() will simply fail.
+ */
+ r= unlink(RENDEZVOUSPATH);
+ if (r) syscallfailure("remove rendezvous socket %s",RENDEZVOUSPATH);
+ syslog(LOG_NOTICE,"arranging for termination, due to client request");
+ reporttermination(0);
+ _exit(10);
+ }
+
fork_service_synch();
getevent(&event_mbuf);