/* Gets the name of an image file to load by running xscreensaver-getimage-file at the end of a pipe. This can be very slow! */ static FILE * open_image_name_pipe (const char *dir) { char *s; /* /bin/sh on OS X 10.10 wipes out the PATH. */ const char *path = getenv("PATH"); char *cmd = s = malloc ((strlen(dir) + strlen(path)) * 2 + 100); strcpy (s, "/bin/sh -c 'export PATH="); s += strlen (s); while (*path) { char c = *path++; if (BACKSLASH(c)) *s++ = '\\'; *s++ = c; } strcpy (s, "; "); s += strlen (s); strcpy (s, "xscreensaver-getimage-file --name "); s += strlen (s); while (*dir) { char c = *dir++; if (BACKSLASH(c)) *s++ = '\\'; *s++ = c; } strcpy (s, "'"); s += strlen (s); *s = 0; FILE *pipe = popen (cmd, "r"); free (cmd); return pipe; }
static char * escape_str (char *s, const char *src) { while (*src) { char c = *src++; if (BACKSLASH(c)) *s++ = '\\'; *s++ = c; } return s; }
static void launch_text_generator (text_data *d) { XtAppContext app = XtDisplayToApplicationContext (d->dpy); char buf[255]; const char *oprogram = d->program; char *s; # ifdef HAVE_COCOA /* /bin/sh on OS X 10.10 wipes out the PATH. */ const char *path = getenv("PATH"); char *cmd = s = malloc ((strlen(oprogram) + strlen(path)) * 2 + 100); strcpy (s, "export PATH="); s += strlen (s); while (*path) { char c = *path++; if (BACKSLASH(c)) *s++ = '\\'; *s++ = c; } strcpy (s, "; "); s += strlen (s); # else char *cmd = s = malloc ((strlen(oprogram)) * 2 + 100); # endif strcpy (s, "( "); strcat (s, oprogram); s += strlen (s); /* Kludge! Special-case "xscreensaver-text" to tell it how wide the screen is. We used to do this by just always feeding `program' through sprintf() and setting the default value to "xscreensaver-text --cols %d", but that makes things blow up if someone ever uses a --program that includes a % anywhere. */ if (!strcmp (oprogram, "xscreensaver-text")) { if (d->char_w) sprintf (s, " --cols %d", d->char_w); if (d->max_lines) sprintf (s, " --lines %d", d->max_lines); s += strlen(s); } strcpy (s, " ) 2>&1"); # ifdef DEBUG fprintf (stderr, "%s: textclient: launch %s: %s\n", cmd, (d->pty_p ? "pty" : "pipe"), program); # endif #ifdef HAVE_FORKPTY if (d->pty_p) { int fd; struct winsize ws; ws.ws_col = d->char_w; ws.ws_row = d->char_h; ws.ws_xpixel = d->pix_w; ws.ws_ypixel = d->pix_h; d->pipe = 0; if ((d->pid = forkpty(&fd, NULL, NULL, &ws)) < 0) { /* Unable to fork */ sprintf (buf, "%.100s: forkpty", progname); perror (buf); } else if (!d->pid) { /* This is the child fork. */ char *av[10]; int i = 0; if (putenv ("TERM=vt100")) abort(); av[i++] = "/bin/sh"; av[i++] = "-c"; av[i++] = cmd; av[i] = 0; execvp (av[0], av); sprintf (buf, "%.100s: %.100s", progname, oprogram); perror (buf); exit (1); } else { /* This is the parent fork. */ if (d->pipe) abort(); d->pipe = fdopen (fd, "r+"); if (d->pipe_id) abort(); d->pipe_id = XtAppAddInput (app, fileno (d->pipe), (XtPointer) (XtInputReadMask | XtInputExceptMask), subproc_cb, (XtPointer) d); # ifdef DEBUG fprintf (stderr, "%s: textclient: pid = %d\n", progname, d->pid); # endif } } else #endif /* HAVE_FORKPTY */ { /* don't mess up controlling terminal on "-pipe -program tcsh". */ static int protected_stdin_p = 0; if (! protected_stdin_p) { fclose (stdin); open ("/dev/null", O_RDWR); /* re-allocate fd 0 */ protected_stdin_p = 1; } if (d->pipe) abort(); if ((d->pipe = popen (cmd, "r"))) { if (d->pipe_id) abort(); d->pipe_id = XtAppAddInput (app, fileno (d->pipe), (XtPointer) (XtInputReadMask | XtInputExceptMask), subproc_cb, (XtPointer) d); # ifdef DEBUG fprintf (stderr, "%s: textclient: popen\n", progname); # endif } else { sprintf (buf, "%.100s: %.100s", progname, cmd); perror (buf); } } free (cmd); }