FILE * cairo_boilerplate_open_any2ppm (const char *filename, int page, unsigned int flags, int (**close_cb) (FILE *)) { char command[4096]; #if HAS_DAEMON int sk; struct sockaddr_un addr; int len; if (flags & CAIRO_BOILERPLATE_OPEN_NO_DAEMON) goto POPEN; if (! any2ppm_daemon_exists ()) { if (system ("./any2ppm") != 0) goto POPEN; } sk = socket (PF_UNIX, SOCK_STREAM, 0); if (sk == -1) goto POPEN; memset (&addr, 0, sizeof (addr)); addr.sun_family = AF_UNIX; strcpy (addr.sun_path, SOCKET_PATH); if (connect (sk, (struct sockaddr *) &addr, sizeof (addr)) == -1) { close (sk); goto POPEN; } len = sprintf (command, "%s %d\n", filename, page); if (write (sk, command, len) != len) { close (sk); goto POPEN; } *close_cb = fclose; return fdopen (sk, "r"); POPEN: #endif *close_cb = pclose; sprintf (command, "./any2ppm %s %d", filename, page); return popen (command, "r"); }
static const char * any2ppm_daemon (void) { int timeout = TIMEOUT; struct pollfd pfd; int sk, fd; long flags; struct sockaddr_un addr; char *line = NULL; size_t len = 0; #ifdef SIGPIPE signal (SIGPIPE, SIG_IGN); #endif /* XXX racy! */ if (getenv ("ANY2PPM_FORCE") == NULL && any2ppm_daemon_exists ()) return "any2ppm daemon already running"; unlink (SOCKET_PATH); sk = socket (PF_UNIX, SOCK_STREAM, 0); if (sk == -1) return "unable to create socket"; memset (&addr, 0, sizeof (addr)); addr.sun_family = AF_UNIX; strcpy (addr.sun_path, SOCKET_PATH); if (bind (sk, (struct sockaddr *) &addr, sizeof (addr)) == -1) { close (sk); return "unable to bind socket"; } flags = fcntl (sk, F_GETFL); if (flags == -1 || fcntl (sk, F_SETFL, flags | O_NONBLOCK) == -1) { close (sk); return "unable to set socket to non-blocking"; } if (listen (sk, 5) == -1) { close (sk); return "unable to listen on socket"; } /* ready for client connection - detach from parent/terminal */ if (getenv ("ANY2PPM_NODAEMON") == NULL && daemonize () == -1) { close (sk); return "unable to detach from parent"; } if (! write_pid_file ()) { close (sk); return "unable to write pid file"; } if (getenv ("ANY2PPM_TIMEOUT") != NULL) { timeout = atoi (getenv ("ANY2PPM_TIMEOUT")); if (timeout == 0) timeout = -1; if (timeout > 0) timeout *= 1000; /* convert env (in seconds) to milliseconds */ } pfd.fd = sk; pfd.events = POLLIN; pfd.revents = 0; /* valgrind */ while (poll (&pfd, 1, timeout) > 0) { while ((fd = accept (sk, NULL, NULL)) != -1) { if (_getline (fd, &line, &len) != -1) { char *argv[10]; if (split_line (line, argv, ARRAY_LENGTH (argv)) > 0) { const char *err; err = convert (argv, fd); if (err != NULL) { FILE *file = fopen (".any2ppm.errors", "a"); if (file != NULL) { fprintf (file, "Failed to convert '%s': %s\n", argv[0], err); fclose (file); } } } } close (fd); } } close (sk); unlink (SOCKET_PATH); unlink (SOCKET_PATH ".pid"); free (line); return NULL; }