aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@member.fsf.org>2015-12-28 17:01:42 +0100
committerMattias Andrée <maandree@member.fsf.org>2015-12-28 17:01:42 +0100
commit4cf537d9cbf122572d98867d7239881ee63fd336 (patch)
treeeb56a9a5f5b520d69765046e587e4f1f17f5c8e0
parentclose state file + unlink before closing to avoid race condition (diff)
downloadsat-4cf537d9cbf122572d98867d7239881ee63fd336.tar.gz
sat-4cf537d9cbf122572d98867d7239881ee63fd336.tar.bz2
sat-4cf537d9cbf122572d98867d7239881ee63fd336.tar.xz
accept connections and for-exec to appropriate image
Signed-off-by: Mattias Andrée <maandree@member.fsf.org>
-rw-r--r--src/README6
-rw-r--r--src/satd-diminished.c68
2 files changed, 68 insertions, 6 deletions
diff --git a/src/README b/src/README
index 541907e..e36126f 100644
--- a/src/README
+++ b/src/README
@@ -4,7 +4,11 @@ satr.c The satr program, ask satd to run jobs early.
satrm.c The satrm program, ask satd to remove jobs from the queue.
satd.c The initialisation part of satd.
-satd-diminished.c The rest of satd, std.c exec:s to this.
+satd-diminished.c The rest of satd, satd.c exec:s to this.
+satd-add.c The part of satd responding to sat, satd-diminished.c fork–exec:s to this.
+satd-rm.c The part of satd responding to satrm, satd-diminished.c fork–exec:s to this.
+satd-list.c The part of satd responding to satlist, satd-diminished.c fork–exec:s to this.
+satd-run.c The part of satd responding to satr, satd-diminished.c fork–exec:s to this.
parse_time.[ch] Use by sat.c to parse the time argument.
Only rudimentary parsing is done.
diff --git a/src/satd-diminished.c b/src/satd-diminished.c
index 48ada56..d887e27 100644
--- a/src/satd-diminished.c
+++ b/src/satd-diminished.c
@@ -20,6 +20,9 @@
* DEALINGS IN THE SOFTWARE.
*/
#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <sys/socket.h>
@@ -70,17 +73,72 @@
int
main(int argc, char *argv[])
{
- int fd;
+ int fd = -1, rc = 0;
+ pid_t pid;
+ char type;
+ const char *image;
- fd = accept(SOCK_FILENO. NULL, NULL);
- shutdown(fd, SHUT_RDWR);
- close(fd);
+accept_again:
+ fd = accept(SOCK_FILENO, NULL, NULL);
+ if (fd == -1) {
+ switch (errno) {
+ case ECONNABORTED:
+ case EINTR:
+ goto accept_again;
+ default:
+ /* Including EMFILE, ENFILE, and ENOMEM
+ * because of potential resource leak. */
+ goto fail;
+ }
+ }
+fork_again:
+ if (recv(fd, &type, (size_t)1, 0) <= 0) {
+ perror(argv[0]);
+ goto connection_done;
+ }
+ switch ((pid = fork())) {
+ case -1:
+ if (errno != EAGAIN)
+ goto fail;
+ (void) sleep(1); /* Possibly shorter because of SIGCHLD. */
+ goto fork_again;
+ case 0:
+ switch (type) {
+ case SAT_QUEUE: image = LIBEXEC "/" PACKAGE "/satd-add"; break;
+ case SAT_REMOVE: image = LIBEXEC "/" PACKAGE "/satd-rm"; break;
+ case SAT_PRINT: image = LIBEXEC "/" PACKAGE "/satd-list"; break;
+ case SAT_RUN: image = LIBEXEC "/" PACKAGE "/satd-run"; break;
+ default:
+ fprintf(stderr, "%s: invalid command received.\n", argv[0]);
+ exit(1);
+ }
+ if (dup2(fd, SOCK_FILENO) != -1)
+ close(fd), fd = SOCK_FILENO, execv(image, argv);
+ perror(argv[0]);
+ close(fd);
+ exit(1);
+ default:
+ break;
+ }
+connection_done:
+ close(fd), fd = -1;
+ goto accept_again;
+done:
unlink(argv[1]);
- unlink(argv[2]); /* Only on success! */
+ if (!rc)
+ unlink(argv[2]);
close(SOCK_FILENO);
close(STATE_FILENO);
return 0;
+
+fail:
+ perror(argv[0]);
+ if (fd >= 0)
+ close(fd);
+ rc = 1;
+ goto done;
+
(void) argc;
}