Commit Diff


commit - d980494c3c457d28ec2abc3ec6f1d63322164e4d
commit + fea541a838dbab837f755ad784432fd65069c77c
blob - d83c272f4036d3971845202b54868eb60a2c17af
blob + 2e46ef7af0971f3ce4c31a75aca78e021be03d2b
--- amused.c
+++ amused.c
@@ -201,7 +201,7 @@ start_child(enum amused_process proc, int fd)
 	}
 
 	if (fd != 3) {
-		if (dup2(fd, 3) == -1)
+		if (fd != -1 && dup2(fd, 3) == -1)
 			fatal("cannot setup imsg fd");
 	} else if (fcntl(F_SETFD, 0) == -1)
 		fatal("cannot setup imsg fd");
@@ -209,7 +209,7 @@ start_child(enum amused_process proc, int fd)
 	argv[argc++] = argv0;
 	switch (proc) {
 	case PROC_MAIN:
-		fatal("can not start main process");
+		break;
 	case PROC_PLAYER:
 		argv[argc++] = "-Tp";
 		break;
@@ -338,6 +338,13 @@ main(int argc, char **argv)
 }
 
 void
+spawn_daemon(void)
+{
+	debug = 0;
+	start_child(PROC_MAIN, -1);
+}
+
+void
 imsg_event_add(struct imsgev *iev)
 {
 	iev->events = EV_READ;
blob - 216322d71c078e2bce9cd98b4170485a77a6fa9c
blob + 77b043abadef6bf57b4b8765d51fa16c362ce0bd
--- amused.h
+++ amused.h
@@ -82,6 +82,7 @@ struct ctl_command {
 };
 
 /* amused.c */
+void		spawn_daemon(void);
 void		imsg_event_add(struct imsgev *iev);
 int		imsg_compose_event(struct imsgev *, uint16_t, uint32_t,
 		    pid_t, int, const void *, uint16_t);
blob - fb2a7fafbdbde3b83797216021b5d2f91d15293d
blob + bdb846af95dc64cc70eab4e95805b402a7484edb
--- ctl.c
+++ ctl.c
@@ -290,25 +290,53 @@ ctl_add(struct parse_result *res, int argc, char **arg
 	return ctlaction(res);
 }
 
-__dead void
-ctl(int argc, char **argv)
+static int
+sockconn(void)
 {
-	struct sockaddr_un	 sun;
-	int			 ctl_sock;
+	struct sockaddr_un	sun;
+	int			sock, saved_errno;
 
-	log_init(1, LOG_DAEMON);
-	log_setverbose(verbose);
-
-	if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
+	if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
 		fatal("socket");
 
 	memset(&sun, 0, sizeof(sun));
 	sun.sun_family = AF_UNIX;
 	strlcpy(sun.sun_path, csock, sizeof(sun.sun_path));
+	if (connect(sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
+		saved_errno = errno;
+		close(sock);
+		errno = saved_errno;
+		return -1;
+	}
 
-	if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1)
-		fatal("connect %s", csock);
+	return sock;
+}
+
+__dead void
+ctl(int argc, char **argv)
+{
+	int ctl_sock, i = 0;
 
+	log_init(1, LOG_DAEMON);
+	log_setverbose(verbose);
+
+	do {
+		struct timespec	ts = { 0, 50000000 }; /* 0.05 seconds */
+
+		if ((ctl_sock = sockconn()) != -1)
+			break;
+		if (errno != ENOENT && errno != ECONNREFUSED)
+			fatal("connect %s", csock);
+
+		if (i == 0)
+			spawn_daemon();
+
+		nanosleep(&ts, NULL);
+	} while (++i < 20);
+
+	if (ctl_sock == -1)
+		fatalx("failed to connect to the daemon");
+
 	ibuf = xmalloc(sizeof(*ibuf));
 	imsg_init(ibuf, ctl_sock);