Make kdump(1) print more useful information

Matthias Schmidt schmidtm at mathematik.uni-marburg.de
Thu Dec 13 03:07:09 PST 2007


Hi,

I ported a patch from FreeBSD over making kdump(1) output more
informative.  For an example see [1].  The patch applies clean to HEAD
and works.  The code looks not very nice, but rewriting the whole
thing would take too much time for less gain.  The patch differs
slightly from FreeBSD due to the fact that kse*, the* is FreeBSD only.

I attached a second one-line patch for sys/fcntl.h, replacing a _KERNEL
ifdef with _KERNEL_STRUCTURES.  Without this patch kdump won't compile.

The kdump patch was reviewed by corecore.

Regards,

	Matthias

[1] http://lists.freebsd.org/pipermail/cvs-src/2006-May/063955.html

-- 
Dipl.-Inf. Matthias Schmidt <schmidtm at mathematik.uni-marburg.de>
Dept. of Mathematics and Computer Science, Distributed Systems Group
University of Marburg, Hans-Meerwein-Strasse, 35032 Marburg, Germany
Tel: +49.6421.28 21 591, Fax: +49.6421.28 21 573, Office C4347
diff -urN kdump.orig/Makefile kdump/Makefile
--- kdump.orig/Makefile	2007-08-27 18:50:54.000000000 +0200
+++ kdump/Makefile	2007-12-13 12:34:56.000000000 +0100
@@ -1,17 +1,20 @@
 #	@(#)Makefile	8.1 (Berkeley) 6/6/93
-# $FreeBSD: src/usr.bin/kdump/Makefile,v 1.4.2.2 2002/07/23 09:16:07 ru Exp $
+# $FreeBSD: src/usr.bin/kdump/Makefile,v 1.12 2006/05/20 14:27:22 netchild Exp $
 # $DragonFly: src/usr.bin/kdump/Makefile,v 1.6 2007/08/27 16:50:54 pavalos Exp $
 
 .PATH: ${.CURDIR}/../ktrace
 
 PROG=		kdump
-SRCS=		kdump.c ioctl.c subr.c
-CFLAGS+=	-I${.CURDIR}/../ktrace -I${.CURDIR}/../.. -I${.CURDIR}/../../sys
+SRCS=		kdump.c ioctl.c kdump_subr.c subr.c
+CFLAGS+=	-I${.CURDIR}/../ktrace -I${.CURDIR} -I${.CURDIR}/../.. 
 WARNS?=	0
 
-CLEANFILES=	ioctl.c
+CLEANFILES=	ioctl.c kdump_subr.c
 
 ioctl.c: mkioctls
 	sh ${.CURDIR}/mkioctls ${DESTDIR}/usr/include > ${.TARGET}
 
+kdump_subr.c: mksubr
+	sh ${.CURDIR}/mksubr ${DESTDIR}/usr/include > ${.TARGET}
+
 .include <bsd.prog.mk>
diff -urN kdump.orig/kdump.c kdump/kdump.c
--- kdump.orig/kdump.c	2007-05-07 17:43:31.000000000 +0200
+++ kdump/kdump.c	2007-12-13 12:34:14.000000000 +0100
@@ -32,7 +32,7 @@
  *
  * @(#) Copyright (c) 1988, 1993 The Regents of the University of California.  All rights reserved.
  * @(#)kdump.c	8.1 (Berkeley) 6/6/93
- * $FreeBSD: src/usr.bin/kdump/kdump.c,v 1.17 1999/12/29 05:05:33 peter Exp $
+ * $FreeBSD: src/usr.bin/kdump/kdump.c,v 1.29 2006/05/20 14:27:22 netchild Exp $
  * $DragonFly: src/usr.bin/kdump/kdump.c,v 1.8 2007/05/07 15:43:31 dillon Exp $
  */
 
@@ -54,6 +54,7 @@
 #include <unistd.h>
 #include <vis.h>
 #include "ktrace.h"
+#include "kdump_subr.h"
 
 int timestamp, decimal, fancy = 1, tail, maxdata = 64;
 int fixedformat;
@@ -257,14 +258,20 @@
 	if (narg) {
 		char c = '(';
 		if (fancy) {
+
+#define print_number(i,n,c) do {                      \
+	if (decimal)                                  \
+		(void)printf("%c%ld", c, (long)*i);   \
+	else                                          \
+		(void)printf("%c%#lx", c, (long)*i);  \
+	i++;                                          \
+	n--;                                          \
+	c = ',';                                      \
+	} while (0);
+
 			if (ktr->ktr_code == SYS_ioctl) {
 				char *cp;
-				if (decimal)
-					(void)printf("(%ld", (long)*ip);
-				else
-					(void)printf("(%#lx", (long)*ip);
-				ip++;
-				narg--;
+				print_number(ip,narg,c);
 				if ((cp = ioctlname(*ip)) != NULL)
 					(void)printf(",%s", cp);
 				else {
@@ -276,6 +283,336 @@
 				c = ',';
 				ip++;
 				narg--;
+			} else if (ktr->ktr_code == SYS_access) {
+				print_number(ip,narg,c);
+				(void)putchar(',');
+				accessmodename ((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_open) {
+				int	flags;
+				int	mode;
+				print_number(ip,narg,c);
+				flags = *ip;
+				mode = *++ip;
+				(void)putchar(',');
+				flagsandmodename (flags, mode, decimal);
+				ip++;
+				narg-=2;
+			} else if (ktr->ktr_code == SYS_wait4) {
+				print_number(ip,narg,c);
+				print_number(ip,narg,c);
+				(void)putchar(',');
+				wait4optname ((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_chmod ||
+				   ktr->ktr_code == SYS_fchmod ||
+				   ktr->ktr_code == SYS_lchmod) {
+				print_number(ip,narg,c);
+				(void)putchar(',');
+				modename ((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_mknod) {
+				print_number(ip,narg,c);
+				(void)putchar(',');
+				modename ((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_getfsstat) {
+				print_number(ip,narg,c);
+				print_number(ip,narg,c);
+				(void)putchar(',');
+				getfsstatflagsname ((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_mount) {
+				print_number(ip,narg,c);
+				print_number(ip,narg,c);
+				(void)putchar(',');
+				mountflagsname ((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_unmount) {
+				print_number(ip,narg,c);
+				(void)putchar(',');
+				mountflagsname ((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_recvmsg ||
+				   ktr->ktr_code == SYS_sendmsg) {
+				print_number(ip,narg,c);
+				print_number(ip,narg,c);
+				(void)putchar(',');
+				sendrecvflagsname ((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_recvfrom ||
+				   ktr->ktr_code == SYS_sendto) {
+				print_number(ip,narg,c);
+				print_number(ip,narg,c);
+				print_number(ip,narg,c);
+				(void)putchar(',');
+				sendrecvflagsname ((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_chflags ||
+				   ktr->ktr_code == SYS_fchflags) {
+				print_number(ip,narg,c);
+				(void)putchar(',');
+				modename((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_kill) {
+				print_number(ip,narg,c);
+				(void)putchar(',');
+				signame((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_reboot) {
+				(void)putchar('(');
+				rebootoptname((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_umask) {
+				(void)putchar('(');
+				modename((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_msync) {
+				print_number(ip,narg,c);
+				print_number(ip,narg,c);
+				(void)putchar(',');
+				msyncflagsname((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_mmap) {
+				print_number(ip,narg,c);
+				print_number(ip,narg,c);
+				(void)putchar(',');
+				mmapprotname ((int)*ip);
+				(void)putchar(',');
+				ip++;
+				narg--;
+				mmapflagsname ((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_mprotect) {
+				print_number(ip,narg,c);
+				print_number(ip,narg,c);
+				(void)putchar(',');
+				mmapprotname ((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_madvise) {
+				print_number(ip,narg,c);
+				print_number(ip,narg,c);
+				(void)putchar(',');
+				madvisebehavname((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_setpriority) {
+				print_number(ip,narg,c);
+				print_number(ip,narg,c);
+				(void)putchar(',');
+				prioname((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_fcntl) {
+				int cmd;
+				int arg;
+				print_number(ip,narg,c);
+				cmd = *ip;
+				arg = *++ip;
+				(void)putchar(',');
+				fcntlcmdname(cmd, arg, decimal);
+				ip++;
+				narg-=2;
+			} else if (ktr->ktr_code == SYS_socket) {
+				(void)putchar('(');
+				sockdomainname((int)*ip);
+				ip++;
+				narg--;
+				(void)putchar(',');
+				socktypename((int)*ip);
+				ip++;
+				narg--;
+				c = ',';
+			} else if (ktr->ktr_code == SYS_setsockopt ||
+				   ktr->ktr_code == SYS_getsockopt) {
+				print_number(ip,narg,c);
+				(void)putchar(',');
+				sockoptlevelname((int)*ip, decimal);
+				ip++;
+				narg--;
+				(void)putchar(',');
+				sockoptname((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_lseek) {
+				print_number(ip,narg,c);
+				/* Hidden 'pad' argument, not in lseek(2) */
+				print_number(ip,narg,c);
+				print_number(ip,narg,c);
+				(void)putchar(',');
+				whencename ((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_flock) {
+				print_number(ip,narg,c);
+				(void)putchar(',');
+				flockname((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_mkfifo ||
+				   ktr->ktr_code == SYS_mkdir) {
+				print_number(ip,narg,c);
+				(void)putchar(',');
+				modename((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_shutdown) {
+				print_number(ip,narg,c);
+				(void)putchar(',');
+				shutdownhowname((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_socketpair) {
+				(void)putchar('(');
+				sockdomainname((int)*ip);
+				ip++;
+				narg--;
+				(void)putchar(',');
+				socktypename((int)*ip);
+				ip++;
+				narg--;
+				c = ',';
+			} else if (ktr->ktr_code == SYS_getrlimit ||
+				   ktr->ktr_code == SYS_setrlimit) {
+				(void)putchar('(');
+				rlimitname((int)*ip);
+				ip++;
+				narg--;
+				c = ',';
+			} else if (ktr->ktr_code == SYS_quotactl) {
+				print_number(ip,narg,c);
+				quotactlname((int)*ip);
+				ip++;
+				narg--;
+				c = ',';
+			} else if (ktr->ktr_code == SYS_rtprio) {
+				(void)putchar('(');
+				rtprioname((int)*ip);
+				ip++;
+				narg--;
+				c = ',';
+			} else if (ktr->ktr_code == SYS___semctl) {
+				print_number(ip,narg,c);
+				print_number(ip,narg,c);
+				semctlname((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_semget) {
+				print_number(ip,narg,c);
+				print_number(ip,narg,c);
+				semgetname((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_msgctl) {
+				print_number(ip,narg,c);
+				shmctlname((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_shmat) {
+				print_number(ip,narg,c);
+				print_number(ip,narg,c);
+				shmatname((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_shmctl) {
+				print_number(ip,narg,c);
+				shmctlname((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_minherit) {
+				print_number(ip,narg,c);
+				print_number(ip,narg,c);
+				minheritname((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_rfork) {
+				(void)putchar('(');
+				rforkname((int)*ip);
+				ip++;
+				narg--;
+				c = ',';
+			} else if (ktr->ktr_code == SYS_lio_listio) {
+				(void)putchar('(');
+				lio_listioname((int)*ip);
+				ip++;
+				narg--;
+				c = ',';
+			} else if (ktr->ktr_code == SYS_mlockall) {
+				(void)putchar('(');
+				mlockallname((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_sched_setscheduler) {
+				print_number(ip,narg,c);
+				schedpolicyname((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_sched_get_priority_max ||
+				   ktr->ktr_code == SYS_sched_get_priority_min) {
+				(void)putchar('(');
+				schedpolicyname((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_sendfile) {
+				print_number(ip,narg,c);
+				print_number(ip,narg,c);
+				print_number(ip,narg,c);
+				print_number(ip,narg,c);
+				print_number(ip,narg,c);
+				print_number(ip,narg,c);
+				sendfileflagsname((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_kldsym) {
+				print_number(ip,narg,c);
+				kldsymcmdname((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_sigprocmask) {
+				(void)putchar('(');
+				sigprocmaskhowname((int)*ip);
+				ip++;
+				narg--;
+				c = ',';
+			} else if (ktr->ktr_code == SYS___acl_get_file ||
+				   ktr->ktr_code == SYS___acl_set_file ||
+				   ktr->ktr_code == SYS___acl_get_fd ||
+				   ktr->ktr_code == SYS___acl_set_fd ||
+				   ktr->ktr_code == SYS___acl_delete_file ||
+				   ktr->ktr_code == SYS___acl_delete_fd ||
+				   ktr->ktr_code == SYS___acl_aclcheck_file ||
+				   ktr->ktr_code == SYS___acl_aclcheck_fd) {
+				print_number(ip,narg,c);
+				acltypename((int)*ip);
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_sigaction) {
+				(void)putchar('(');
+				signame((int)*ip);
+				ip++;
+				narg--;
+				c = ',';
+			} else if (ktr->ktr_code == SYS_extattrctl) {
+				print_number(ip,narg,c);
+				extattrctlname((int)*ip);
+				ip++;
+				narg--;
 			} else if (ktr->ktr_code == SYS_ptrace) {
 				if (*ip < sizeof(ptrace_ops) /
 				    sizeof(ptrace_ops[0]) && *ip >= 0)
@@ -312,13 +649,7 @@
 			}
 		}
 		while (narg) {
-			if (decimal)
-				(void)printf("%c%ld", c, (long)*ip);
-			else
-				(void)printf("%c%#lx", c, (long)*ip);
-			c = ',';
-			ip++;
-			narg--;
+			print_number(ip,narg,c);
 		}
 		(void)putchar(')');
 	}
diff -urN kdump.orig/kdump_subr.h kdump/kdump_subr.h
--- kdump.orig/kdump_subr.h	1970-01-01 01:00:00.000000000 +0100
+++ kdump/kdump_subr.h	2007-12-12 20:25:17.000000000 +0100
@@ -0,0 +1,48 @@
+/* $FreeBSD: src/usr.bin/kdump/kdump_subr.h,v 1.3 2007/04/09 22:04:27 emaste Exp $ */
+
+void signame (int);
+void semctlname (int);
+void shmctlname (int);
+void semgetname (int);
+void fcntlcmdname (int, int, int);
+void rtprioname (int);
+void modename (int);
+void flagsname (int);
+void flagsandmodename (int, int, int);
+void accessmodename (int);
+void mmapprotname (int);
+void mmapflagsname (int);
+void wait4optname (int);
+void sendrecvflagsname (int);
+void getfsstatflagsname (int);
+void mountflagsname (int);
+void rebootoptname (int);
+void flockname (int);
+void sockoptname (int);
+void sockoptlevelname (int, int);
+void sockdomainname (int);
+void sockipprotoname (int);
+void socktypename (int);
+void thrcreateflagsname (int);
+void mlockallname (int);
+void shmatname (int);
+void rforkname (int);
+void nfssvcname (int);
+void whencename (int);
+void rlimitname (int);
+void shutdownhowname (int);
+void prioname (int);
+void madvisebehavname (int);
+void msyncflagsname (int);
+void schedpolicyname (int);
+void kldunloadfflagsname (int);
+void ksethrcmdname (int);
+void extattrctlname (int);
+void kldsymcmdname (int);
+void sendfileflagsname (int);
+void acltypename (int);
+void sigprocmaskhowname (int);
+void lio_listioname (int);
+void minheritname (int);
+void quotactlname (int);
+void ptraceopname (int);
diff -urN kdump.orig/mksubr kdump/mksubr
--- kdump.orig/mksubr	1970-01-01 01:00:00.000000000 +0100
+++ kdump/mksubr	2007-12-13 12:26:05.000000000 +0100
@@ -0,0 +1,436 @@
+set -e
+
+# Generates kdump_subr.c
+# mkioctls is a special-purpose script, and works fine as it is
+# now, so it remains independent. The idea behind how it generates
+# its list was heavily borrowed here.
+#
+# Some functions here are automatically generated. This can mean
+# the user will see unusual kdump output or errors while building
+# if the underlying .h files are changed significantly.
+#
+# Key:
+# AUTO: Completely auto-generated with either the "or" or the "switch"
+# method.
+# AUTO - Special: Generated automatically, but with some extra commands
+# that the auto_*_type() functions are inappropriate for.
+# MANUAL: Manually entered and must therefore be manually updated.
+
+# $FreeBSD: src/usr.bin/kdump/mksubr,v 1.9 2007/04/09 19:16:24 emaste Exp $
+
+LC_ALL=C; export LC_ALL
+
+if [ -z "$1" ]
+then
+	echo "usage: sh $0 include-dir"
+	exit 1
+fi
+include_dir=$1
+
+#
+# Automatically generates a C function that will print out the
+# numeric input as a pipe-delimited string of the appropriate
+# #define keys. ex:
+# S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH
+# The XOR is necessary to prevent including the "0"-value in every
+# line.
+#
+auto_or_type () {
+	local name grep file
+	name=$1
+	grep=$2
+	file=$3
+
+	cat <<_EOF_
+/* AUTO */
+void
+$name (int arg)
+{
+	int	or = 0;
+_EOF_
+	egrep "^#[[:space:]]*define[[:space:]]+"${grep}"[[:space:]]*" \
+		$include_dir/$file | \
+	awk '{ for (i = 1; i <= NF; i++) \
+		if ($i ~ /define/) \
+			break; \
+		++i; \
+		printf "\tif(!((arg>0)^((%s)>0)))\n\t\tif_print_or(arg, %s, or);\n", $i, $i }'
+cat <<_EOF_
+	if (or == 0)
+		(void)printf("<invalid>%ld", (long)arg);
+}
+
+_EOF_
+}
+
+#
+# Automatically generates a C function used when the argument
+# maps to a single, specific #definition
+#
+auto_switch_type () {
+	local name grep file
+	name=$1
+	grep=$2
+	file=$3
+
+	cat <<_EOF_
+/* AUTO */
+void
+$name (int arg)
+{
+	switch (arg) {
+_EOF_
+	egrep "^#[[:space:]]*define[[:space:]]+"${grep}"[[:space:]]*" \
+		$include_dir/$file | \
+	awk '{ for (i = 1; i <= NF; i++) \
+		if ($i ~ /define/) \
+			break; \
+		++i; \
+		printf "\tcase %s:\n\t\t(void)printf(\"%s\");\n\t\tbreak;\n", $i, $i }'
+cat <<_EOF_
+	default: /* Should not reach */
+		(void)printf("<invalid=%ld>", (long)arg);
+	}
+}
+
+_EOF_
+}
+
+#
+# Automatically generates a C function used when the argument
+# maps to a #definition
+#
+auto_if_type () {
+	local name grep file
+	name=$1
+	grep=$2
+	file=$3
+
+	cat <<_EOF_
+/* AUTO */
+void
+$name (int arg)
+{
+_EOF_
+	egrep "^#[[:space:]]*define[[:space:]]+"${grep}"[[:space:]]*" \
+		$include_dir/$file | \
+	awk '{ printf "\t"; \
+		if (NR > 1) \
+			printf "else " ; \
+		printf "if (arg == %s) \n\t\tprintf(\"%s\");\n", $2, $2 }'
+cat <<_EOF_
+	else /* Should not reach */
+		(void)printf("<invalid=%ld>", (long)arg);
+}
+
+_EOF_
+}
+
+# C start
+
+cat <<_EOF_
+#define _KERNEL_STRUCTURES
+
+#include <stdio.h>
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+#include <sys/unistd.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/ptrace.h>
+#include <sys/resource.h>
+#include <sys/reboot.h>
+#include <sched.h>
+#include <sys/linker.h>
+#include <sys/extattr.h>
+#include <sys/acl.h>
+#include <aio.h>
+#include <sys/sem.h>
+#include <sys/ipc.h>
+#include <sys/rtprio.h>
+#include <sys/shm.h>
+#include <vfs/ufs/quota.h>
+
+#include "kdump_subr.h"
+
+/*
+ * These are simple support macros. print_or utilizes a variable
+ * defined in the calling function to track whether or not it should
+ * print a logical-OR character ('|') before a string. if_print_or
+ * simply handles the necessary "if" statement used in many lines
+ * of this file.
+ */
+#define print_or(str,orflag) do {                  \\
+	if (orflag) putchar('|'); else orflag = 1; \\
+	printf (str); }                            \\
+	while (0)
+#define if_print_or(i,flag,orflag) do {            \\
+	if ((i & flag) == flag)                    \\
+	print_or(#flag,orflag); }                  \\
+	while (0)
+
+/* MANUAL */
+extern char *signames[]; /* from kdump.c */
+void
+signame (int sig)
+{
+	if (sig > 0 && sig < NSIG)
+		(void)printf("SIG%s",signames[sig]);
+	else
+		(void)printf("SIG %d", sig);
+}
+
+/* MANUAL */
+void
+semctlname (int cmd)
+{
+	switch (cmd) {
+	case GETNCNT:
+		(void)printf("GETNCNT");
+		break;
+	case GETPID:
+		(void)printf("GETPID");
+		break;
+	case GETVAL:
+		(void)printf("GETVAL");
+		break;
+	case GETALL:
+		(void)printf("GETALL");
+		break;
+	case GETZCNT:
+		(void)printf("GETZCNT");
+		break;
+	case SETVAL:
+		(void)printf("SETVAL");
+		break;
+	case SETALL:
+		(void)printf("SETALL");
+		break;
+	case IPC_RMID:
+		(void)printf("IPC_RMID");
+		break;
+	case IPC_SET:
+		(void)printf("IPC_SET");
+		break;
+	case IPC_STAT:
+		(void)printf("IPC_STAT");
+		break;
+	default: /* Should not reach */
+		(void)printf("<invalid=%ld>", (long)cmd);
+	}
+}
+
+/* MANUAL */
+void
+shmctlname (int cmd) {
+	switch (cmd) {
+	case IPC_RMID:
+		(void)printf("IPC_RMID");
+		break;
+	case IPC_SET:
+		(void)printf("IPC_SET");
+		break;
+	case IPC_STAT:
+		(void)printf("IPC_STAT");
+		break;
+	default: /* Should not reach */
+		(void)printf("<invalid=%ld>", (long)cmd);
+	}
+}
+
+/* MANUAL */
+void
+semgetname (int flag) {
+	int	or = 0;
+	if_print_or(flag, SEM_R, or);
+	if_print_or(flag, SEM_A, or);
+	if_print_or(flag, (SEM_R>>3), or);
+	if_print_or(flag, (SEM_A>>3), or);
+	if_print_or(flag, (SEM_R>>6), or);
+	if_print_or(flag, (SEM_A>>6), or);
+}
+
+/*
+ * MANUAL
+ *
+ * Only used by SYS_open. Unless O_CREAT is set in flags, the
+ * mode argument is unused (and often bogus and misleading).
+ */
+void
+flagsandmodename (int flags, int mode, int decimal) {
+	flagsname (flags);
+	(void)putchar(',');
+	if ((flags & O_CREAT) == O_CREAT) {
+		modename (mode);
+	} else {
+		if (decimal) {
+			(void)printf("<unused>%ld", (long)mode);
+		} else {
+			(void)printf("<unused>%#lx", (long)mode);
+		}
+	}
+}
+
+/*
+ * MANUAL
+ *
+ * [g|s]etsockopt's level argument can either be SOL_SOCKET or a value
+ * referring to a line in /etc/protocols . It might be appropriate
+ * to use getprotoent(3) here.
+ */
+void
+sockoptlevelname (int level, int decimal)
+{
+	if (level == SOL_SOCKET) {
+		(void)printf("SOL_SOCKET");
+	} else {
+		if (decimal) {
+			(void)printf("%ld", (long)level);
+		} else {
+			(void)printf("%#lx", (long)level);
+		}
+	}
+}
+
+_EOF_
+
+auto_or_type "modename" "S_[A-Z]+[[:space:]]+[0-6]{7}" "sys/stat.h"
+auto_or_type "flagsname" "O_[A-Z]+[[:space:]]+0x[0-9A-Fa-f]+" "sys/fcntl.h"
+auto_or_type "accessmodename" "[A-Z]_OK[[:space:]]+0?x?[0-9A-Fa-f]+" "sys/unistd.h"
+auto_or_type "mmapprotname" "PROT_[A-Z]+[[:space:]]+0x[0-9A-Fa-f]+" "sys/mman.h"
+auto_or_type "mmapflagsname" "MAP_[A-Z]+[[:space:]]+0x[0-9A-Fa-f]+" "sys/mman.h"
+auto_or_type "wait4optname" "W[A-Z]+[[:space:]]+[0-9]+" "sys/wait.h"
+auto_or_type "getfsstatflagsname" "MNT_[A-Z]+[[:space:]]+[1-9][0-9]*" "sys/mount.h"
+auto_or_type "mountflagsname" "MNT_[A-Z]+[[:space:]]+0x[0-9]+" "sys/mount.h"
+auto_or_type "rebootoptname" "RB_[A-Z]+[[:space:]]+0x[0-9]+" "sys/reboot.h"
+auto_or_type "flockname" "LOCK_[A-Z]+[[:space:]]+0x[0-9]+" "sys/fcntl.h"
+auto_or_type "mlockallname" "MCL_[A-Z]+[[:space:]]+0x[0-9]+" "sys/mman.h"
+auto_or_type "shmatname" "SHM_[A-Z]+[[:space:]]+[0-9]{6}+" "sys/shm.h"
+auto_or_type "rforkname" "RF[A-Z]+[[:space:]]+\([0-9]+<<[0-9]+\)" "sys/unistd.h"
+
+auto_switch_type "whencename" "SEEK_[A-Z]+[[:space:]]+[0-9]+" "sys/unistd.h"
+auto_switch_type "rlimitname" "RLIMIT_[A-Z]+[[:space:]]+[0-9]+" "sys/resource.h"
+auto_switch_type "shutdownhowname" "SHUT_[A-Z]+[[:space:]]+0x[0-9]+" "sys/socket.h"
+auto_switch_type "prioname" "PRIO_[A-Z]+[[:space:]]+[0-9]" "sys/resource.h"
+auto_switch_type "madvisebehavname" "_?MADV_[A-Z]+[[:space:]]+[0-9]+" "sys/mman.h"
+auto_switch_type "msyncflagsname" "MS_[A-Z]+[[:space:]]+0x[0-9]+" "sys/mman.h"
+auto_switch_type "schedpolicyname" "SCHED_[A-Z]+[[:space:]]+[0-9]+" "sched.h"
+auto_switch_type "kldunloadfflagsname" "LINKER_UNLOAD_[A-Z]+[[:space:]]+[0-9]+" "sys/linker.h"
+auto_switch_type "extattrctlname" "EXTATTR_NAMESPACE_[A-Z]+[[:space:]]+0x[0-9]+" "sys/extattr.h"
+auto_switch_type "kldsymcmdname" "KLDSYM_[A-Z]+[[:space:]]+[0-9]+" "sys/linker.h"
+auto_switch_type "sendfileflagsname" "SF_[A-Z]+[[:space:]]+[0-9]+" "sys/socket.h"
+auto_switch_type "acltypename" "ACL_TYPE_[A-Z]+[[:space:]]+0x[0-9]+" "sys/acl.h"
+auto_switch_type "sigprocmaskhowname" "SIG_[A-Z]+[[:space:]]+[0-9]+" "sys/signal.h"
+auto_switch_type "lio_listioname" "LIO_(NO)?WAIT[[:space:]]+[0-9]+" "aio.h"
+auto_switch_type "minheritname" "INHERIT_[A-Z]+[[:space:]]+[0-9]+" "sys/mman.h"
+auto_switch_type "quotactlname" "Q_[A-Z]+[[:space:]]+0x[0-9]+" "ufs/ufs/quota.h"
+auto_if_type "sockdomainname" "PF_[[:alnum:]]+[[:space:]]+" "sys/socket.h"
+auto_if_type "sockipprotoname" "IPPROTO_[[:alnum:]]+[[:space:]]+" "netinet/in.h"
+auto_switch_type "sockoptname" "SO_[A-Z]+[[:space:]]+0x[0-9]+" "sys/socket.h"
+auto_switch_type "socktypename" "SOCK_[A-Z]+[[:space:]]+[1-9]+[0-9]*" "sys/socket.h"
+auto_switch_type "ptraceopname" "PT_[[:alnum:]]+[[:space:]]+[0-9]+" "sys/ptrace.h"
+
+cat <<_EOF_
+/*
+ * AUTO - Special
+ * F_ is used to specify fcntl commands as well as arguments. Both sets are
+ * grouped in fcntl.h, and this awk script grabs the first group.
+ */
+void
+fcntlcmdname (int cmd, int arg, int decimal)
+{
+	switch (cmd) {
+_EOF_
+egrep "^#[[:space:]]*define[[:space:]]+F_[A-Z]+[[:space:]]+[0-9]+[[:space:]]*" \
+	$include_dir/sys/fcntl.h | \
+	awk 'BEGIN { o=0 } { for (i = 1; i <= NF; i++) \
+		if ($i ~ /define/) \
+			break; \
+		++i; \
+		if (o <= $(i+1)) \
+			printf "\tcase %s:\n\t\t(void)printf(\"%s\");\n\t\tbreak;\n", $i, $i; \
+		else \
+			exit; \
+		o = $(i+1) }'
+cat <<_EOF_
+	default: /* Should not reach */
+		(void)printf("<invalid=%ld>", (long)cmd);
+	}
+	(void)putchar(',');
+	if (cmd == F_GETFD || cmd == F_SETFD) {
+		if (arg == FD_CLOEXEC)
+			(void)printf("FD_CLOEXEC");
+		else if (arg == 0)
+			(void)printf("0");
+		else {
+			if (decimal)
+				(void)printf("<invalid>%ld", (long)arg);
+			else
+				(void)printf("<invalid>%#lx", (long)arg);
+		}
+	} else if (cmd == F_SETFL) {
+		flagsname(arg);
+	} else {
+		if (decimal)
+			(void)printf("%ld", (long)arg);
+		else
+			(void)printf("%#lx", (long)arg);
+	}
+}
+
+/*
+ * AUTO - Special
+ *
+ * The only reason this is not fully automated is due to the
+ * grep -v RTP_PRIO statement. A better egrep line should
+ * make this capable of being a auto_switch_type() function.
+ */
+void
+rtprioname (int func)
+{
+	switch (func) {
+_EOF_
+egrep "^#[[:space:]]*define[[:space:]]+RTP_[A-Z]+[[:space:]]+0x[0-9]+[[:space:]]*" \
+	$include_dir/sys/rtprio.h | grep -v RTP_PRIO | \
+	awk '{ for (i = 1; i <= NF; i++) \
+		if ($i ~ /define/) \
+			break; \
+		++i; \
+		printf "\tcase %s:\n\t\t(void)printf(\"%s\");\n\t\tbreak;\n", $i, $i }'
+cat <<_EOF_
+	default: /* Should not reach */
+		(void)printf("<invalid=%ld>", (long)func);
+	}
+}
+
+/*
+ * AUTO - Special
+ *
+ * The send and recv functions have a flags argument which can be
+ * set to 0. There is no corresponding #define. The auto_ functions
+ * detect this as "invalid", which is incorrect here.
+ */
+void
+sendrecvflagsname (int flags)
+{
+	int	or = 0;
+	
+	if (flags == 0) {
+		(void)printf("0");
+		return;
+	}
+_EOF_
+egrep "^#[[:space:]]*define[[:space:]]+MSG_[A-Z]+[[:space:]]+0x[0-9]+[[:space:]]*" $include_dir/sys/socket.h | \
+	awk '{ for (i = 1; i <= NF; i++) \
+		if ($i ~ /define/) \
+			break; \
+		++i; \
+		printf "\tif(!((flags>0)^((%s)>0)))\n\t\tif_print_or(flags, %s, or);\n", $i, $i }'
+cat <<_EOF_
+}
+
+_EOF_
Index: fcntl.h
===================================================================
RCS file: /usr/dcvs/src/sys/sys/fcntl.h,v
retrieving revision 1.12
diff -u -r1.12 fcntl.h
--- fcntl.h	29 Jun 2007 05:12:40 -0000	1.12
+++ fcntl.h	13 Dec 2007 11:52:53 -0000
@@ -96,7 +96,7 @@
 #define O_DIRECT	0x00010000
 
-#ifdef _KERNEL
+#ifdef _KERNEL_STRUCTURES
 #define O_ROOTCRED	0x00020000	/* fp_open */
 #endif
 




More information about the Submit mailing list