static int opt_stderr;
static const char *opt_lock;
static int opt_ignore_spawned_command_output;
-static const char *opt_command;
+static char *opt_command;
static void fatal(const char *fmt,...) G_GNUC_PRINTF(1,2) G_GNUC_NORETURN;
+/* for atexit(3) function */
+static int verror_quiet;
+
static void verror(const char *fmt,va_list ap) G_GNUC_PRINTF(1,0);
static void verror(const char *fmt,va_list ap)
{
char *string;
const char *const double_error="Error printing error message";
+ if (verror_quiet)
+ return;
if (!use_syslog && !use_stderr)
use_stderr=1;
if (-1==vasprintf(&string,fmt,ap)) {
return string;
}
+static void *xmalloc(size_t size)
+{
+void *r;
+
+ if ((r=malloc(size)))
+ return r;
+ fatal("Error allocing %lu bytes",(unsigned long)size);
+}
+
static void usage(void)
{
fprintf(stderr,"\
static void lock_close(void)
{
- if (lock_fd==-1)
+ if (lock_fd==-1 || !opt_lock)
return;
+ /* It should not be needed but some stale locks were seen on:
+ * White Box Linux kernel-smp-2.6.9-5.0.5.EL
+ */
+ if (flock(lock_fd,LOCK_UN|LOCK_NB))
+ fatal("Error unlocking lock file \"%s\": %m",opt_lock);
if (close(lock_fd))
fatal("Error closing lock file \"%s\": %m",opt_lock);
lock_fd=-1;
}
+static void lock_close_atexit(void)
+{
+ /* Prevent some crashes of malloc(3) etc. */
+ verror_quiet=1;
+ lock_close();
+}
+
static int connect_try(void)
{
int fdtcp;
pollfdi_name[0]=conn0_name;
pollfdi_name[1]=conn1_name;
for (;;) {
- for (fdi=0;fdi<G_N_ELEMENTS(pollfdi);fdi++)
- if (pollfdi[fdi].events)
- break;
- if (fdi>=G_N_ELEMENTS(pollfdi)) {
- lock_close();
- exit(EXIT_SUCCESS);
- }
if (0>=poll(pollfdi,G_N_ELEMENTS(pollfdi),-1))
fatal("poll(%s socket,%s socket): %m",pollfdi_name[0],pollfdi_name[1]);
for (fdi=0;fdi<G_N_ELEMENTS(pollfdi);fdi++)
fatal("read(%s socket): %m",pollfdi_name[fdi]);
}
if (got==0) {
- pollfdi[fdi].events&=~POLLIN;
- break;
+ lock_close();
+ exit(EXIT_SUCCESS);
}
for (fdo=0;fdo<G_N_ELEMENTS(pollfdi);fdo++) {
if (fdi==fdo)
int main(int argc,char **argv)
{
char optc;
+size_t opt_command_len;
+int i;
+char *s;
if ((program_name=strrchr(argv[0],'/')))
program_name++;
else
program_name=argv[0];
+ atexit(lock_close_atexit);
+
optarg=NULL; optind=0; /* FIXME: Possible portability problem. */
while ((optc=getopt_long(argc,argv,"01T:i:Sel:p:Ih",longopts,NULL))!=EOF) switch (optc) {
long l;
if (optind>=argc)
fatal("<start-server-command/stop-server-command> is a required argument");
- if (optind+1<argc)
- fatal("Too many arguments, <start-server-command/stop-server-command> may need quoting");
- opt_command=argv[optind];
+ opt_command_len=0;
+ for (i=optind;i<argc;i++)
+ opt_command_len+=strlen(argv[i])+1;
+ opt_command=xmalloc(opt_command_len);
+ s=opt_command;
+ for (i=optind;i<argc;i++) {
+size_t argv_i_len=strlen(argv[i]);
+
+ if (s>opt_command)
+ *s++=' ';
+ memcpy(s,argv[i],argv_i_len);
+ s+=argv_i_len;
+ }
+ *s++=0;
+ assert(s==opt_command+opt_command_len);
if (!opt_syslog && !opt_stderr)
opt_stderr=1;