PERFORCE change 51082 for review
Marcel Moolenaar
marcel at FreeBSD.org
Wed Apr 14 22:53:00 PDT 2004
http://perforce.freebsd.org/chv.cgi?CH=51082
Change 51082 by marcel at marcel_nfs on 2004/04/14 22:52:33
Functional shell, though limited. We basicly fork/exec a gdb(1)
process with stdin, stdout and stderr redirected to us (where
stdout and stderr are multiplexed) and pass our stdin to the
child and forward the childs stdout to ours. To have a different
prompt (and a vehicle for setting other operation settings at
startup), we create a command file and use the --command=FILE
argument to gdb(1). By default we put a "set prompt (kgdb) " in
there. We can also copy the contents of .kgdbinit into it if we
want to support .kgdbinit at some time in the future.
Compile with WARNS=4.
Affected files ...
.. //depot/projects/gdb/usr.bin/kgdb/Makefile#2 edit
.. //depot/projects/gdb/usr.bin/kgdb/main.c#2 edit
Differences ...
==== //depot/projects/gdb/usr.bin/kgdb/Makefile#2 (text+ko) ====
@@ -2,5 +2,5 @@
PROG= kgdb
SRCS= main.c
-
+WARNS?= 4
.include <bsd.prog.mk>
==== //depot/projects/gdb/usr.bin/kgdb/main.c#2 (text+ko) ====
@@ -27,7 +27,121 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <err.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+int gdb_in, gdb_out;
+pid_t gdb_pid;
+
+char *cmdfile_name;
+int cmdfile_fd;
+
+static void
+mkpipe(int *rd, int *wr)
+{
+ int f[2];
+
+ if (pipe(f) == -1)
+ err(1, "pipe(2)");
+ *rd = f[0];
+ *wr = f[1];
+}
+
+static void
+launch_gdb(void)
+{
+ char *command;
+ int in, out;
+ int f, fmax;
+
+ mkpipe(&in, &gdb_in);
+ mkpipe(&gdb_out, &out);
+
+ gdb_pid = fork();
+ if (gdb_pid == -1)
+ err(1, "fork(2)");
+ if (gdb_pid == 0) {
+ if (asprintf(&command, "--command=%s", cmdfile_name) < 0)
+ err(1, "asprintf(3)");
+ /* Dup stderr last so that err(3) work as long as possible. */
+ if (dup2(in, 0) == -1 || dup2(out, 1) == -1 ||
+ dup2(out, 2) == -1)
+ err(1, "dup2(2)");
+ fmax = getdtablesize();
+ for (f = 3; f < fmax; f++)
+ close(f);
+ execlp("gdb", "gdb", command, NULL);
+ _exit(1);
+ }
+
+ close(in);
+ close(out);
+}
+
+static void
+mkcmdfile(void)
+{
+ static const char set_prompt[] = "set prompt (kgdb) ";
+
+ cmdfile_name = strdup("/tmp/kgdb.XXXXXXXX");
+ if (cmdfile_name == NULL)
+ err(1, "strdup(3)");
+ cmdfile_fd = mkstemp(cmdfile_name);
+ if (cmdfile_fd == -1)
+ err(1, "mkstemp(3)");
+ if (write(cmdfile_fd, set_prompt, sizeof(set_prompt) - 1) < 0)
+ err(1, "write(2)");
+}
+
int
-main(int argc, char *argv[])
+main(int argc __unused, char *argv[] __unused)
{
+ char buf[128];
+ fd_set rfds, wfds, xfds;
+ ssize_t sz;
+ int status;
+
+ mkcmdfile();
+ launch_gdb();
+
+ while (1) {
+ FD_ZERO(&rfds);
+ FD_ZERO(&wfds);
+ FD_ZERO(&xfds);
+ FD_SET(0, &rfds);
+ FD_SET(gdb_out, &rfds);
+ FD_SET(gdb_in, &xfds);
+ FD_SET(gdb_out, &xfds);
+ if (select(gdb_out + 1, &rfds, &wfds, &xfds, NULL) == -1) {
+ if (errno != EINTR)
+ err(1, "select(2)");
+ continue;
+ }
+ if (FD_ISSET(gdb_in, &xfds) || FD_ISSET(gdb_out, &xfds))
+ break;
+ if (FD_ISSET(0, &rfds)) {
+ sz = read(0, buf, sizeof(buf));
+ if (sz > 0)
+ sz = write(gdb_in, buf, sz);
+ }
+ if (FD_ISSET(gdb_out, &rfds)) {
+ sz = read(gdb_out, buf, sizeof(buf));
+ if (sz > 0)
+ sz = write(1, buf, sz);
+ }
+ }
+
+ close(gdb_in);
+ close(gdb_out);
+
+ wait4(gdb_pid, &status, 0, NULL);
+ return (WEXITSTATUS(status));
}
More information about the p4-projects
mailing list