summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hurd/Makefile49
-rw-r--r--hurd/gensym.awk78
-rw-r--r--hurd/ioctl-decode.h15
-rw-r--r--hurd/ioctl-tmpl.sym13
-rw-r--r--hurd/ioctl.awk127
5 files changed, 280 insertions, 2 deletions
diff --git a/hurd/Makefile b/hurd/Makefile
index 53436d87..1b133aaa 100644
--- a/hurd/Makefile
+++ b/hurd/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation
+# Copyright (C) 1993, 94, 95, 96, 99 Free Software Foundation
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
@@ -19,7 +19,7 @@ dir := hurd
makemode := misc
hdrs = $(wildcard $(srcdir)/*.defs $(srcdir)/*.h)
-DIST_FILES = subsystems $(notdir $(hdrs))
+DIST_FILES = subsystems $(notdir $(hdrs)) ioctl-tmpl.sym ioctl.awk gensym.awk
INSTHDRS = hurd_types.h ioctl_types.h paths.h shared.h \
$(notdir $(wildcard $(srcdir)/*.defs))
@@ -32,3 +32,48 @@ install-headers install: $(includedir)/hurd \
$(includedir)/hurd/%: $(srcdir)/%; $(INSTALL_DATA) $< $@
$(includedir)/hurd:;mkdir -p $@
+
+
+
+#
+# The following rules assist in creating an `Xioctl.defs' file
+# to define RPCs that are sent primarily by ioctl commands.
+# To use them, write a file `Xioctl-headers.h', e.g. for `mioctl-headers.h':
+# #include <sys/mtio.h>
+# with an #include for each header that defines ioctl request macros
+# using _IO('X') et al. Then `make Xioctl-proto.defs' will create
+# a prototype file for you to hand-edit into `Xioctl.defs'.
+
+# Building foo.h from foo.sym:
+%.symc: %.sym
+ $(AWK) -f $(srcdir)/gensym.awk $< >$*.symc
+%.symc.o: %.symc
+ $(CC) -S $(CPPFLAGS) $(CFLAGS) $(CPPFLAGS-$@) -x c -o $@ $<
+%.h: %.symc.o
+ sed <$< -e 's/^[^*].*$$//' | \
+ sed -e 's/^[*]/#define/' -e 's/mAgIc[^-0-9]*//' -e '/^ *$$/d' >$@
+
+%-ioctls.sym: tmpl-ioctls.sym
+ sed 's|HEADER|<$(subst +,/,$*)>|' $< > $@
+
+cpp = $(CC) $(CPPFLAGS) $(CFLAGS) $(CPPFLAGS-$@) -E -x c
+
+%ioctl-requests.list: %ioctl-headers.h
+ $(cpp) $< | sed -n 's/^#.*"\([^"]*\)".*$$/\1/p' | sort | uniq | \
+ while read f; do \
+ sed -n 's/^[ ]*#[ ]*define[ ]*\([A-Z0-9_]*\)[^A-Z0-9_][^A-Z0-9_]*_IO.*'\'$*\'.*$$'/\1/p' $$f; \
+ done | sort | uniq > $@
+
+%ioctl.defs: %ioctl.sym
+
+%ioctl-values.sym: %ioctl-headers.h %ioctl-requests.list ioctl-tmpl.sym
+ (sed 's%@HEADER_LIST@%$<%;s/@GROUP@/$*/g' < $(filter %.sym,$^); \
+ while read r; do \
+ for x in CMD SUBID INOUT TYPE \
+ TYPE0 TYPE1 TYPE2 COUNT0 COUNT1 COUNT2; do \
+ echo "expr $${x}($${r}) $${r}_$${x}"; \
+ done; \
+ done < $(filter %.list,$^)) > $@
+
+%ioctl-proto.defs: %ioctl-values.h ioctl.awk
+ sed 's/^#define//;s/_/ /g' $< | $(AWK) -f $(filter %.awk,$^) > $@
diff --git a/hurd/gensym.awk b/hurd/gensym.awk
new file mode 100644
index 00000000..21283214
--- /dev/null
+++ b/hurd/gensym.awk
@@ -0,0 +1,78 @@
+#
+# Copyright (c) 1994 The University of Utah and
+# the Computer Systems Laboratory (CSL). All rights reserved.
+#
+# Permission to use, copy, modify and distribute this software and its
+# documentation is hereby granted, provided that both the copyright
+# notice and this permission notice appear in all copies of the
+# software, derivative works or modified versions, and any portions
+# thereof, and that both notices appear in supporting documentation.
+#
+# THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
+# IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
+# ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+#
+# CSL requests users of this software to return to csl-dist@cs.utah.edu any
+# improvements that they make and grant CSL redistribution rights.
+#
+# Author: Bryan Ford, University of Utah CSL
+#
+
+BEGIN {
+ bogus_printed = "no"
+}
+
+# Start the bogus function just before the first sym directive,
+# so that any #includes higher in the file don't get stuffed inside it.
+/^[a-z]/ {
+ if (bogus_printed == "no")
+ {
+ print "void bogus() {";
+ bogus_printed = "yes";
+ }
+}
+
+# Take an arbitrarily complex C symbol or expression and constantize it.
+/^expr/ {
+ print "__asm (\"";
+ if ($3 == "")
+ printf "* %s mAgIc%%0\" : : \"i\" (%s));\n", $2, $2;
+ else
+ printf "* %s mAgIc%%0\" : : \"i\" (%s));\n", $3, $2;
+}
+
+# Output a symbol defining the size of a C structure.
+/^size/ {
+ print "__asm (\"";
+ if ($4 == "")
+ printf "* %s_SIZE mAgIc%%0\" : : \"i\" (sizeof(struct %s)));\n",
+ toupper($3), $2;
+ else
+ printf "* %s mAgIc%%0\" : : \"i\" (sizeof(struct %s)));\n",
+ $4, $2;
+}
+
+# Output a symbol defining the byte offset of an element of a C structure.
+/^offset/ {
+ print "__asm (\"";
+ if ($5 == "")
+ {
+ printf "* %s_%s mAgIc%%0\" : : \"i\" (&((struct %s*)0)->%s));\n",
+ toupper($3), toupper($4), $2, $4;
+ }
+ else
+ {
+ printf "* %s mAgIc%%0\" : : \"i\" (&((struct %s*)0)->%s));\n",
+ toupper($5), $2, $4;
+ }
+}
+
+# Copy through all preprocessor directives.
+/^#/ {
+ print
+}
+
+END {
+ print "}"
+}
+
diff --git a/hurd/ioctl-decode.h b/hurd/ioctl-decode.h
new file mode 100644
index 00000000..f65880cf
--- /dev/null
+++ b/hurd/ioctl-decode.h
@@ -0,0 +1,15 @@
+/* This file is used by the Makefile rules for generating
+ Xioctl-proto.defs, see Makefile for details. */
+
+#define CMD(request) _IOC_COMMAND (request)
+#define TYPE(request) _IOC_TYPE (request)
+#define INOUT(request) _IOC_INOUT (request)
+
+#define SUBID(request) IOC_COMMAND_SUBID (_IOC_COMMAND (request))
+
+#define TYPE0(request) _IOT_TYPE0 (_IOC_TYPE (request))
+#define TYPE1(request) _IOT_TYPE1 (_IOC_TYPE (request))
+#define TYPE2(request) _IOT_TYPE2 (_IOC_TYPE (request))
+#define COUNT0(request) _IOT_COUNT0 (_IOC_TYPE (request))
+#define COUNT1(request) _IOT_COUNT1 (_IOC_TYPE (request))
+#define COUNT2(request) _IOT_COUNT2 (_IOC_TYPE (request))
diff --git a/hurd/ioctl-tmpl.sym b/hurd/ioctl-tmpl.sym
new file mode 100644
index 00000000..8029ec00
--- /dev/null
+++ b/hurd/ioctl-tmpl.sym
@@ -0,0 +1,13 @@
+/* This file is used by the Makefile rules for generating
+ Xioctl-proto.defs, see Makefile for details. */
+
+#include <sys/ioctl.h>
+#include <hurd/ioctls.defs>
+
+#include "ioctl-decode.h"
+
+#include "@HEADER_LIST@"
+#define GROUPCHAR '@GROUP@'
+
+expr GROUPCHAR GROUP
+expr IOC_GROUP_SUBSYSTEM(GROUPCHAR) SUBSYSTEM
diff --git a/hurd/ioctl.awk b/hurd/ioctl.awk
new file mode 100644
index 00000000..289a9ab9
--- /dev/null
+++ b/hurd/ioctl.awk
@@ -0,0 +1,127 @@
+#
+# This awk script is used by the Makefile rules for generating
+# Xioctl-proto.defs, see Makefile for details.
+#
+
+$1 == "SUBSYSTEM" { subsystem = $2 + 0; next }
+$1 == "GROUP" { groupchar = $2; next }
+
+$2 == "CMD" { cmd[tolower($1)] = $3;
+ c = $3 + 0;
+ if (c > highcmd) highcmd = c;
+ icmd[c] = tolower($1);
+ next }
+$2 == "SUBID" { subid[tolower($1)] = $3;
+ c = $3 + 0;
+ if (c > highid) highid = c;
+ id2cmdname[c] = tolower($1);
+ next }
+$2 == "TYPE" { type[tolower($1)] = $3; next }
+$2 == "INOUT" { inout[tolower($1)] = $3; next }
+$2 == "TYPE0" { type0[tolower($1)] = $3; next }
+$2 == "TYPE1" { type1[tolower($1)] = $3; next }
+$2 == "TYPE2" { type2[tolower($1)] = $3; next }
+$2 == "COUNT0" { count0[tolower($1)] = $3; next }
+$2 == "COUNT1" { count1[tolower($1)] = $3; next }
+$2 == "COUNT2" { count2[tolower($1)] = $3; next }
+
+END {
+ group = sprintf("%cioctl", groupchar);
+
+ printf "subsystem %s %d; /* see ioctls.defs for calculation */\n\n", \
+ group, subsystem;
+
+ typemap[0] = "char";
+ typemap[1] = "char";
+ typemap[2] = "short";
+ typemap[3] = "int";
+ typemap[4] = "???64 bits???";
+ inoutmap[1] = "out";
+ inoutmap[2] = "in";
+ inoutmap[3] = "inout";
+
+ print "";
+ for (cmdname in type0) {
+ if (count0[cmdname] > 1) {
+ typecount = type0[cmdname] "," count0[cmdname];
+ if (!tc[typecount]) {
+ tc[typecount] = typemap[type0[cmdname]] "array_" count0[cmdname] "_t";
+ print "type", tc[typecount], "=", ("array[" count0[cmdname] "]"), \
+ "of", (typemap[type0[cmdname]] ";"), "/* XXX rename this! */";
+ }
+ argtype["0," cmdname] = tc[typecount];
+ }
+ else if (count0[cmdname] == 1) {
+ argtype["0," cmdname] = typemap[type0[cmdname]]
+ }
+ }
+
+ for (cmdname in type1) {
+ if (count1[cmdname] > 1) {
+ typecount = type1[cmdname] "," count1[cmdname];
+ if (!tc[typecount]) {
+ tc[typecount] = typemap[type1[cmdname]] "array_" count1[cmdname] "_t";
+ print "type", tc[typecount], "=", ("array[" count1[cmdname] "]"), \
+ "of", (typemap[type1[cmdname]] ";"), "/* XXX rename this! */";
+ }
+ argtype["1," cmdname] = tc[typecount];
+ }
+ else if (count1[cmdname] == 1) {
+ argtype["1," cmdname] = typemap[type1[cmdname]]
+ }
+ }
+
+ for (cmdname in type2) {
+ if (count2[cmdname] > 1) {
+ typecount = type2[cmdname] "," count2[cmdname];
+ if (!tc[typecount]) {
+ tc[typecount] = typemap[type2[cmdname]] "array_" count2[cmdname] "_t";
+ print "type", tc[typecount], "=", ("array[" count2[cmdname] "]"), \
+ "of", (typemap[type2[cmdname]] ";"), "/* XXX rename this! */";
+ }
+ argtype["2," cmdname] = tc[typecount];
+ }
+ else if (count2[cmdname] == 1) {
+ argtype["2," cmdname] = typemap[type2[cmdname]]
+ }
+ }
+ print "";
+
+ lastid = -1;
+ for (i = 0; i <= highid; ++i)
+ if (id2cmdname[i]) {
+ cmdname = id2cmdname[i];
+
+ if (lastid < 100 && i > 100) {
+ if (lastid == 98)
+ print "\nskip; /* 99 unused */"
+ else
+ printf "\nskip %d; /* %d-99 unused */\n", 100 - lastid, lastid + 1;
+ print "\n\
+/* Because MiG defines reply ports as 100 more than request ports, we\n\
+ have to leave one hundred empty RPC's here. */\n\
+skip 100;";
+ lastid = 199;
+ }
+
+ if (i == lastid + 2)
+ print "\nskip; /*", lastid + 1, "unused */";
+ else if (i != lastid + 1)
+ printf "\nskip %d; /* %d-%d unused */\n", \
+ i - lastid - 1, lastid + 1, i - 1;
+ lastid = i;
+ print "\n/*", i, toupper(cmdname), "*/";
+ printf "routine %s_%s (\n\treqport: io_t", group, cmdname;
+ if (inout[cmdname]) {
+ io = inoutmap[inout[cmdname]];
+ for (argidx = 0; argidx <= 2; ++argidx)
+ if (argtype[argidx "," cmdname])
+ printf ";\n\t%s\targ%d: %s", \
+ io, argidx, argtype[argidx "," cmdname];
+ }
+ else {
+ printf ";\n\tin\trequest: int";
+ }
+ print ");"
+ }
+}