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