#endif /* HAVE_UNAME */
#include <stdio.h>
+#include <time.h>
#include <sys/stat.h>
+#include <sys/time.h>
#include <signal.h>
#include <string.h>
#include <ctype.h>
+
+/* from exec.c */
+extern void exec_command (const char *shell, const char *command, int nice);
+
#undef countof
#define countof(x) (sizeof((x))/sizeof((*x)))
int subproc_timer_id; /* timer to delay subproc launch */
int subproc_check_timer_id; /* timer to check whether it started up */
int subproc_check_countdown; /* how many more checks left */
- int preview_nice_level;
int *list_elt_to_hack_number; /* table for sorting the hack list */
int *hack_number_to_list_elt; /* the inverse table */
saver_preferences *p = &s->prefs;
char str[100];
+ /* The file supports timeouts of less than a minute, but the GUI does
+ not, so throttle the values to be at least one minute (since "0" is
+ a bad rounding choice...)
+ */
+# define THROTTLE(NAME) if (p->NAME != 0 && p->NAME < 60000) p->NAME = 60000
+ THROTTLE (timeout);
+ THROTTLE (cycle);
+ THROTTLE (passwd_timeout);
+# undef THROTTLE
+
# define FMT_MINUTES(NAME,N) \
- sprintf (str, "%d", ((N) + 59) / (60 * 1000)); \
+ sprintf (str, "%d", (((N / 1000) + 59) / 60)); \
gtk_entry_set_text (GTK_ENTRY (name_to_widget (s, (NAME))), str)
# define FMT_SECONDS(NAME,N) \
screenhack *hack = (hack_number >= 0 ? p->screenhacks[hack_number] : 0);
char *doc_string = 0;
+ /* #### not in Gtk 1.2
+ gtk_label_set_selectable (doc);
+ */
+
# ifdef HAVE_XML
if (s->cdata)
{
}
-static void
-exec_program (const char *cmd, int nice_level)
-{
- char *av[1024];
- int ac = 0;
- char *token = strtok (strdup(cmd), " \t");
- while (token)
- {
- av[ac++] = token;
- token = strtok(0, " \t");
- }
- av[ac] = 0;
-
- nice (nice_level - nice (0));
-
- usleep (250000); /* pause for 1/4th second before launching, to give the
- previous program time to die and flush its X buffer,
- so we don't get leftover turds on the window. */
-
- execvp (av[0], av); /* shouldn't return. */
-
- {
- char buf [512];
- sprintf (buf, "%s: could not execute \"%s\"", blurb(), av[0]);
- perror (buf);
- }
- fflush(stderr);
- fflush(stdout);
- exit (1); /* Note that this only exits a child fork. */
-}
-
-
/* Immediately and unconditionally launches the given process,
after appending the -window-id option; sets running_preview_pid.
*/
{
saver_preferences *p = &s->prefs;
Window id;
- Bool hairy_p;
- char *new_cmd;
+ char *new_cmd = 0;
pid_t forked;
- int nice_level = nice (0) - p->nice_inferior;
const char *cmd = s->desired_preview_cmd;
GtkWidget *pr = name_to_widget (s, "preview");
if (s->preview_suppressed_p)
{
kill_preview_subproc (s);
- return;
+ goto DONE;
}
new_cmd = malloc (strlen (cmd) + 40);
sprintf (new_cmd + strlen (new_cmd), " -window-id 0x%X", id);
}
- hairy_p = (new_cmd && !!strpbrk (new_cmd, "*?$&!<>[];`'\\\"="));
- if (hairy_p)
- {
- /* Command requires a full shell? Forget it. */
- free (new_cmd);
- new_cmd = 0;
- if (s->debug_p)
- fprintf (stderr, "%s: command is hairy: not previewing\n", blurb());
- }
-
kill_preview_subproc (s);
if (! new_cmd)
{
s->running_preview_error_p = True;
clear_preview_window (s);
- return;
+ goto DONE;
}
switch ((int) (forked = fork ()))
sprintf (buf, "%s: couldn't fork", blurb());
perror (buf);
s->running_preview_error_p = True;
- return;
+ goto DONE;
+ break;
}
case 0:
{
close (ConnectionNumber (GDK_DISPLAY()));
- exec_program (new_cmd, nice_level);
- abort();
+
+ usleep (250000); /* pause for 1/4th second before launching, to give
+ the previous program time to die and flush its X
+ buffer, so we don't get leftover turds on the
+ window. */
+
+ exec_command (p->shell, new_cmd, p->nice_inferior);
+ /* Don't bother printing an error message when we are unable to
+ exec subprocesses; we handle that by polling the pid later. */
+ exit (1); /* exits child fork */
break;
default:
}
schedule_preview_check (s);
+
+ DONE:
+ if (new_cmd) free (new_cmd);
+ new_cmd = 0;
}
if (s->debug_p)
fprintf (stderr, "%s: %s\n", blurb(), ndpy);
+ /* don't free(ndpy) -- some implementations of putenv (BSD 4.4, glibc
+ 2.0) copy the argument, but some (libc4,5, glibc 2.1.2) do not.
+ So we must leak it (and/or the previous setting). Yay.
+ */
+
if (def_path && *def_path)
{
const char *opath = getenv("PATH");
if (putenv (npath))
abort ();
+ /* do not free(npath) -- see above */
if (s->debug_p)
fprintf (stderr, "%s: added \"%s\" to $PATH\n", blurb(), def_path);
the_network_is_not_the_computer (state *s)
{
Display *dpy = GDK_DISPLAY();
- char *rversion, *ruser, *rhost;
+ char *rversion = 0, *ruser = 0, *rhost = 0;
char *luser, *lhost;
char *msg = 0;
struct passwd *p = getpwuid (getuid ());
if (*msg)
warning_dialog (s->toplevel_widget, msg, True, 1);
+ if (rversion) free (rversion);
+ if (ruser) free (ruser);
+ if (rhost) free (rhost);
free (msg);
}
}
#ifdef DEFAULT_ICONDIR /* from -D on compile line */
- add_pixmap_directory (DEFAULT_ICONDIR);
+ {
+ const char *dir = DEFAULT_ICONDIR;
+ if (*dir) add_pixmap_directory (dir);
+ }
#endif
/* This is gross, but Gtk understands --display and not -display...
capplet = capplet_widget_new ();
/* Make there be a "Close" button instead of "OK" and "Cancel" */
+# ifdef HAVE_CRAPPLET_IMMEDIATE
capplet_widget_changes_are_immediate (CAPPLET_WIDGET (capplet));
+# endif /* HAVE_CRAPPLET_IMMEDIATE */
-# if 1
- /* In crapplet-mode, take off the menubar. */
- gtk_widget_hide (name_to_widget (s, "menubar"));
-# endif
+ /* In crapplet-mode, take off the menubar. */
+ gtk_widget_hide (name_to_widget (s, "menubar"));
/* Reparent our top-level container to be a child of the capplet
window.