summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsabetts <sabetts>2002-11-24 21:52:20 +0000
committersabetts <sabetts>2002-11-24 21:52:20 +0000
commitbc15e751d3b8538720e89848db8bfb9f6f636c20 (patch)
treed192ee4116d97cdac29c2e5ee9095ab063930e23
parent1445719b28b87a3be8f13f5a931adc6fc3da9da3 (diff)
downloadratpoison-bc15e751d3b8538720e89848db8bfb9f6f636c20.zip
* src/main.c: include sys/wait.h
(chld_handler): new function * src/events.c: include sys/wait.h (handle_signals): Print an error message in the case of a child signal. * src/data.h (struct rp_child_info): New struct. (child_info): New global. (chld_signalled): likewise * src/actions.c (spawn): Let the SIGCHLD handler handle process completion instead of doing an ugly dance.
-rw-r--r--ChangeLog16
-rw-r--r--NEWS10
-rw-r--r--src/actions.c30
-rw-r--r--src/data.h12
-rw-r--r--src/events.c7
-rw-r--r--src/main.c31
6 files changed, 90 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index 1c1767a..4166099 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2002-11-24 Shawn Betts <sabetts@sfu.ca>
+
+ * src/main.c: include sys/wait.h
+ (chld_handler): new function
+
+ * src/events.c: include sys/wait.h
+ (handle_signals): Print an error message in the case of a child
+ signal.
+
+ * src/data.h (struct rp_child_info): New struct.
+ (child_info): New global.
+ (chld_signalled): likewise
+
+ * src/actions.c (spawn): Let the SIGCHLD handler handle process
+ completion instead of doing an ugly dance.
+
2002-11-20 Shawn Betts <sabetts@sfu.ca>
* src/ratpoison.h[!HAVE_VARARG_MACROS]: PRINT_ERROR and
diff --git a/NEWS b/NEWS
index c4476b4..dba4661 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,16 @@
ratpoison NEWS --- history of user-visible changes. -*- outline -*-
* Changes since 1.1.1
+** Shell command exit status
+When a shell command fails to execute then a message is reported in
+ratpoison: "Command not found."
+
+** New command 'warp'
+Toggles rat warping. By default ratpoison saves the position of the
+rat when leaving a window and when the user returns to the window the
+rat's position is restored. This can be counter-intuitive, so now you
+can toggle it.
+
** split, vsplit, hsplit
These commands now take a single argument. The argument can be a ratio
which divides the frame into two frames sized based on this ratio, or
diff --git a/src/actions.c b/src/actions.c
index 2779101..d02a983 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -973,29 +973,27 @@ void
spawn(void *data)
{
char *cmd = data;
- /* Ugly dance to avoid leaving zombies. Could use SIGCHLD, but it's
- not very portable. */
- if (fork() == 0)
+ int pid;
+
+ pid = fork();
+ if (pid == 0)
{
- if (fork() == 0)
- {
- /* Some process setup to make sure the spawned process runs
- in its own session. */
- putenv(current_screen()->display_string);
+ /* Some process setup to make sure the spawned process runs
+ in its own session. */
+ putenv(current_screen()->display_string);
#ifdef HAVE_SETSID
- setsid();
+ setsid();
#endif
#if defined (HAVE_SETPGID)
- setpgid (0, 0);
+ setpgid (0, 0);
#elif defined (HAVE_SETPGRP)
- setpgrp (0, 0);
+ setpgrp (0, 0);
#endif
- execl("/bin/sh", "sh", "-c", cmd, 0);
- _exit(EXIT_FAILURE);
- }
- _exit(EXIT_SUCCESS);
+ execl("/bin/sh", "sh", "-c", cmd, 0);
+ _exit(EXIT_FAILURE);
}
- wait((int *) 0);
+
+/* wait((int *) 0); */
PRINT_DEBUG ("spawned %s\n", cmd);
}
diff --git a/src/data.h b/src/data.h
index eae7df7..d81918d 100644
--- a/src/data.h
+++ b/src/data.h
@@ -165,6 +165,17 @@ struct rp_defaults
int warp;
};
+/* Information about a child process. */
+struct rp_child_info
+{
+ int pid;
+ int status;
+};
+
+/* When a child process exits this structure holds the information
+ about it to be used to report back to the user. */
+extern struct rp_child_info child_info;
+
extern struct rp_defaults defaults;
/* The prefix key also known as the command character under screen. */
@@ -250,6 +261,7 @@ extern struct modifier_info rp_modifier_info;
extern int alarm_signalled;
extern int kill_signalled;
extern int hup_signalled;
+extern int chld_signalled;
/* rudeness levels */
extern int rp_honour_transient_raise;
diff --git a/src/events.c b/src/events.c
index 4004c61..54270c3 100644
--- a/src/events.c
+++ b/src/events.c
@@ -33,6 +33,7 @@
#include <errno.h>
#include <unistd.h>
#include <sys/time.h>
+#include <sys/wait.h>
#include "ratpoison.h"
@@ -782,6 +783,12 @@ handle_signals ()
alarm_signalled = 0;
}
+ if (chld_signalled > 0)
+ {
+ marked_message_printf (0,0, " Command not found ");
+ chld_signalled = 0;
+ }
+
if (hup_signalled > 0)
{
clean_up ();
diff --git a/src/main.c b/src/main.c
index d5d5417..4f4e9af 100644
--- a/src/main.c
+++ b/src/main.c
@@ -33,6 +33,7 @@
#include <unistd.h>
#include <getopt.h>
#include <string.h>
+#include <sys/wait.h>
#include "ratpoison.h"
@@ -41,6 +42,7 @@ static void init_screen (screen_info *s, int screen_num);
int alarm_signalled = 0;
int kill_signalled = 0;
int hup_signalled = 0;
+int chld_signalled = 0;
int rat_x;
int rat_y;
int rat_visible = 1; /* rat is visible by default */
@@ -61,6 +63,7 @@ screen_info *screens;
int num_screens;
Display *dpy;
+struct rp_child_info child_info;
struct rp_defaults defaults;
int ignore_badwindow = 0;
@@ -201,6 +204,33 @@ alrm_handler (int signum)
alarm_signalled++;
}
+void
+chld_handler (int signum)
+{
+ int pid, status, serrno;
+ serrno = errno;
+
+ while (1)
+ {
+ pid = waitpid (WAIT_ANY, &status, WNOHANG);
+ if (pid <= 0)
+ break;
+
+ PRINT_DEBUG("Child status: %d\n", WEXITSTATUS (status));
+
+ /* Tell ratpoison about the CHLD signal. We are only interested
+ in reporting commands that failed to execute. These processes
+ have a return value of 127 (according to the sh manual). */
+ if (WEXITSTATUS (status) == 127)
+ {
+ chld_signalled = 1;
+ child_info.pid = pid;
+ child_info.status = status;
+ }
+ }
+ errno = serrno;
+}
+
int
handler (Display *d, XErrorEvent *e)
{
@@ -537,6 +567,7 @@ main (int argc, char *argv[])
set_sig_handler (SIGTERM, sighandler);
set_sig_handler (SIGINT, sighandler);
set_sig_handler (SIGHUP, hup_handler);
+ set_sig_handler (SIGCHLD, chld_handler);
/* Setup ratpoison's internal structures */
init_defaults();