#include #include #include #include #include #include #include "util.h" #include "postprocess.h" static char socket_path[100]; struct Job { pid_t pid; char burstdir[255]; char target[255]; int savedng; }; pid_t start_processing(struct Job job) { pid_t child_pid = fork(); if (child_pid < 0) { err("fork failed"); } else if (child_pid > 0) { // parent process return child_pid; } else { // child process postprocess_internal(job.burstdir, job.target); exit(0); } return -1; } int listen_on_socket() { int sock; struct sockaddr_un addr; // Clean existing socket if (remove(socket_path) == -1 && errno != ENOENT) { err("could not clean up old socket"); } // Make new unix domain socket to listen on sock = socket(AF_UNIX, SOCK_SEQPACKET, 0); if (sock < 0) { err("could not make socket fd"); return 0; } memset(&addr, 0, sizeof(struct sockaddr_un)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1); if (bind(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)) < 0) { err("failed to bind socket"); return 0; } if (listen(sock, 20) < 0) { err("failed to listen"); return 0; } return sock; } int queue_job(struct Job job) { int sock; struct sockaddr_un addr; sock = socket(AF_UNIX, SOCK_SEQPACKET, 0); if (sock < 0) { err("could not make socket fd"); return 0; } memset(&addr, 0, sizeof(struct sockaddr_un)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1); if (connect(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)) < 0) { err("failed to open socket"); return 0; } if (write(sock, &job, sizeof(job)) < 0) { err("failed to write"); return 0; } close(sock); return 1; } int listen_and_convert(int do_fork) { int sock, fd; struct sockaddr_un cli_addr; unsigned int clilen; struct Job job; if (do_fork == 1) { pid_t child_pid = fork(); if (child_pid < 0) { err("fork failed"); } else if (child_pid > 0) { usleep(1000000); // parent process return 1; } } clilen = sizeof(cli_addr); postprocess_setup(); sock = listen_on_socket(); while(1) { fd = accept(sock, (struct sockaddr *)&cli_addr, &clilen); if (fd < 0) { err("failed to accept"); return 0; } if(read(fd, &job, sizeof(job)) < 0) { err("failed to read"); return 0; } close(fd); start_processing(job); wait(NULL); } } void make_socket_path() { char fname[80]; char *xdg_runtime_dir = getenv("XDG_RUNTIME_DIR"); char *user = getenv("USER"); snprintf(fname, sizeof(fname), "postprocessd-%s.sock", user); if (xdg_runtime_dir) { snprintf(socket_path, sizeof(socket_path), "%s/%s", xdg_runtime_dir, fname); } else { snprintf(socket_path, sizeof(socket_path), "/tmp/%s", fname); } } int main(int argc, char *argv[]) { struct Job job; make_socket_path(); if (argc == 4) { // Parse command line arguments into the job struct job.pid = 0; strncpy(job.burstdir, argv[1], sizeof(job.burstdir)); strncpy(job.target, argv[2], sizeof(job.target)); if (strcmp(argv[3], "0") == 0) { job.savedng = 0; } else { job.savedng = 1; } if(queue_job(job)) return 0; if(listen_and_convert(1)) queue_job(job); } else if (argc == 2) { if (strcmp(argv[1], "--daemon") == 0) { listen_and_convert(0); } } else { printf("usage: %s burst-dir target-name save-dng\n", argv[0]); exit(1); } if(listen_and_convert(1)) queue_job(job); return 0; }