summaryrefslogtreecommitdiffstats
path: root/utils/textclient.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/textclient.c')
-rw-r--r--utils/textclient.c129
1 files changed, 112 insertions, 17 deletions
diff --git a/utils/textclient.c b/utils/textclient.c
index fe40928..4a4c895 100644
--- a/utils/textclient.c
+++ b/utils/textclient.c
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 2012-2016 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright © 2012-2021 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
@@ -22,7 +22,7 @@
#include "utils.h"
-#if !defined(USE_IPHONE) && !defined(HAVE_ANDROID) /* whole file */
+#if !defined(HAVE_IPHONE) && !defined(HAVE_ANDROID) /* whole file */
#include "textclient.h"
#include "resources.h"
@@ -117,6 +117,72 @@ escape_str (char *s, const char *src)
}
#endif
+
+/* Let's see if we're able to fork and exec at all. Thanks, macOS.
+ */
+static Bool
+selftest (void)
+{
+ static Bool done = False;
+ pid_t pid;
+ char buf [255];
+ if (done) return True;
+
+ pid = fork ();
+ switch ((int) pid)
+ {
+ case -1:
+ sprintf (buf, "%s: textclient: selftest: couldn't fork", progname);
+ perror (buf);
+ return False;
+
+ case 0: /* child */
+ {
+ char * const av[] = { "/bin/sh", "-c", "true", 0 };
+ execvp (av[0], av);
+ exit (1); /* exits child fork */
+ break;
+ }
+
+ default: /* parent */
+ {
+ int status = -1;
+ int i;
+ /* Busy-loops are bad mmmmkayyyy */
+ struct timeval tv;
+ tv.tv_sec = 0;
+ tv.tv_usec = 100000L; /* 0.1 sec */
+ for (i = 0; i < 50; i++) { /* 5 sec max */
+ pid_t pid2 = waitpid (pid, &status, 0);
+ if (pid == pid2) break;
+ (void) select (0, 0, 0, 0, &tv);
+ }
+
+ if (status != 0)
+ {
+# ifdef DEBUG
+ fprintf (stderr, "%s: selftest: textclient: status %d\n",
+ progname, status);
+# endif
+ return False;
+ }
+ else
+ {
+# ifdef DEBUG
+ fprintf (stderr, "%s: textclient: selftest ok\n", progname);
+# endif
+ done = True;
+ }
+ break;
+ }
+ }
+
+ return True;
+}
+
+
+static void start_timer (text_data *d);
+
static void
launch_text_generator (text_data *d)
{
@@ -142,6 +208,15 @@ launch_text_generator (text_data *d)
char *cmd = s = malloc ((strlen(oprogram)) * 2 + 100);
# endif
+ if (!selftest())
+ {
+ if (!d->out_buffer || !*d->out_buffer)
+ d->out_buffer = "Can't exec; Gatekeeper problem?\r\n\r\n";
+ start_timer (d);
+ free (cmd);
+ return;
+ }
+
strcpy (s, "( ");
strcat (s, oprogram);
s += strlen (s);
@@ -204,26 +279,39 @@ launch_text_generator (text_data *d)
free (text_mode);
}
- strcpy (s, text_mode_flag);
- s += strlen (s);
-
- if (value_res)
+ /* If the 'program' resource already has a text-mode option in it,
+ don't override that! 'gltext' does this. */
+ if (! (strstr (cmd, " --date") ||
+ strstr (cmd, " --text") ||
+ strstr (cmd, " --file") ||
+ strstr (cmd, " --url") ||
+ strstr (cmd, " --program")))
{
- size_t old_s = s - cmd;
- char *value = get_string_resource (d->dpy, value_res, "");
- if (!value)
- value = strdup("");
- cmd = realloc(cmd, cmd_capacity + strlen(value) * 2);
- s = cmd + old_s;
- *s = ' ';
- ++s;
- s = escape_str(s, value);
- free(value);
+ strcpy (s, text_mode_flag);
+ s += strlen (s);
+
+ if (value_res)
+ {
+ size_t old_s = s - cmd;
+ char *value = get_string_resource (d->dpy, value_res, "");
+ if (!value)
+ value = strdup("");
+ cmd = realloc(cmd, cmd_capacity + strlen(value) * 2);
+ s = cmd + old_s;
+ *s = ' ';
+ ++s;
+ s = escape_str(s, value);
+ free(value);
+ }
}
# endif /* HAVE_COCOA */
}
+# if 1
strcpy (s, " ) 2>&1");
+# else
+ strcpy (s, " )");
+# endif
# ifdef DEBUG
fprintf (stderr, "%s: textclient: launch %s: %s\n", progname,
@@ -477,6 +565,13 @@ textclient_open (Display *dpy)
d->program = get_string_resource (dpy, "program", "Program");
+ /* Just in case the resource is blank, e.g. gltext. */
+ if (!d->program || !*d->program || !strcmp(d->program, "(default)"))
+ {
+ if (d->program) free (d->program);
+ d->program = strdup ("xscreensaver-text");
+ }
+
# ifdef HAVE_FORKPTY
/* Kludge for MacOS standalone mode: see OSX/SaverRunner.m. */
@@ -670,4 +765,4 @@ textclient_putc (text_data *d, XKeyEvent *k)
return False;
}
-#endif /* !USE_IPHONE -- whole file */
+#endif /* !HAVE_IPHONE -- whole file */