+
+ if (!opt_port)
+ fatal("-p|--port is a required argument for -1|--start");
+ if (opt_idle_server_timeout!=DEFAULT_IDLE_SERVER_TIMEOUT)
+ fatal("-i|--idle-server-timeout is a forbidden argument for -1|--start");
+
+ lock_create(LOCK_SH);
+ lock_touch();
+ session_try();
+ lock_close();
+
+ lock_create(LOCK_EX);
+ system_checked(opt_command);
+ lock_create(LOCK_SH);
+
+ for (retry=0;retry*CONNECT_RETRY_MSEC/1000<opt_start_command_timeout;retry++) {
+ lock_touch();
+ session_try();
+ if (poll(NULL,0,CONNECT_RETRY_MSEC))
+ fatal("poll(timeout %dmsec): %m",CONNECT_RETRY_MSEC);
+ }
+ fatal("Timed out after %ld seconds connecting to port %d after spawned: %s",
+ opt_start_command_timeout,opt_port,opt_command);
+}
+
+/* Returns: Is fresh or does not exist? */
+static int lock_open_and_time_check(int lock_mode)
+{
+struct stat statbuf;
+
+ if (!opt_lock)
+ return 0;
+
+ if (access(opt_lock,R_OK|W_OK)) {
+ if (errno==ENOENT)
+ return 1;
+ fatal("Error checking existance of the lock file \"%s\": %m",opt_lock);
+ }
+ if (!lock_create(lock_mode|LOCK_NB))
+ return 0;
+ if (lock_fd==-1 || fstat(lock_fd,&statbuf))
+ fatal("Error fstat(2)ting lock file \"%s\": %m",opt_lock);
+ return statbuf.st_mtime>=time(NULL)-opt_idle_server_timeout;
+}
+
+static void lock_delete_and_close(void)
+{
+ if (opt_lock && lock_fd!=-1)
+ if (unlink(opt_lock))
+ fatal("Error deleting no longer used lock file \"%s\": %m",opt_lock);
+ lock_close();
+}
+
+static void stop(void) G_GNUC_NORETURN;
+static void stop(void)
+{
+int is_fresh;
+
+ /* Lock still being held! */
+ if (opt_port)
+ fatal("-p|--port is a forbidden argument for -0|--stop");
+ if (opt_start_command_timeout!=DEFAULT_START_COMMAND_TIMEOUT)
+ fatal("-T|--start-command-timeout is a forbidden argument for -0|--stop");
+ if (opt_idle_server_timeout!=DEFAULT_IDLE_SERVER_TIMEOUT && !opt_lock)
+ fatal("-l|--lock is a required argument for -i|--idle-server-timeout of -1|--start");
+
+ is_fresh=lock_open_and_time_check(LOCK_SH);
+ lock_close();
+ if (is_fresh)
+ exit(EXIT_SUCCESS);
+
+ lock_open_and_time_check(LOCK_EX);
+ system_checked(opt_command);
+ lock_delete_and_close();
+
+ exit(EXIT_SUCCESS);
+}
+
+int main(int argc,char **argv) G_GNUC_NORETURN;
+int main(int argc,char **argv)
+{