* (ioctl-tests): New subdirectory. * (ioctl-tests/Makefile) (ioctl-tests/qio.h) (ioctl-tests/qioctl.c) (ioctl-tests/qioctl.defs) (ioctl-tests/qioctl-handler.c) (ioctl-tests/test.c): New files. --- Makefile | 2 +- ioctl-tests/Makefile | 45 +++++++++++++ ioctl-tests/qio.h | 30 ++++++++ ioctl-tests/qioctl-handler.c | 15 ++++ ioctl-tests/qioctl.c | 150 ++++++++++++++++++++++++++++++++++++++++++ ioctl-tests/qioctl.defs | 36 ++++++++++ ioctl-tests/test.c | 92 ++++++++++++++++++++++++++ 7 files changed, 369 insertions(+), 1 deletions(-) create mode 100644 ioctl-tests/Makefile create mode 100644 ioctl-tests/qio.h create mode 100644 ioctl-tests/qioctl-handler.c create mode 100644 ioctl-tests/qioctl.c create mode 100644 ioctl-tests/qioctl.defs create mode 100644 ioctl-tests/test.c
diff --git a/Makefile b/Makefile index 6d7e688..9a9b265 100644 --- a/Makefile +++ b/Makefile @@ -41,7 +41,7 @@ prog-subdirs = auth proc exec init term \ login daemons nfsd boot console \ hostmux usermux ftpfs trans \ console-client utils sutils ufs-fsck ufs-utils \ - benchmarks fstests + benchmarks fstests ioctl-tests # Other directories other-subdirs = hurd doc config release include diff --git a/ioctl-tests/Makefile b/ioctl-tests/Makefile new file mode 100644 index 0000000..a8333a7 --- /dev/null +++ b/ioctl-tests/Makefile @@ -0,0 +1,45 @@ +# Makefile for ioctl tests. +# +# Copyright (C) 2009 Free Software Foundation, Inc. +# +# Written by Carl Fredrik Hammar <hammy.l...@gmail.com>. +# +# This file is part of the GNU Hurd. +# +# The GNU Hurd is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# The GNU Hurd is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with the GNU Hurd; see the file COPYING. If not, write to the Free +# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA. + +dir := ioctl-tests +makemode := server + +SRCS = qioctl.c qioctl-handler.c #test.c +OBJS = qioctl.o qioctl-handler.o qioctlServer.o ioctl_handlerServer.o #test.o +target = qioctl #test +HURDLIBS = trivfs fshelp + +include ../Makeconf + +%.so.$(hurd-version): %_pic.o + $(CC) -shared -Wl,-soname=$@ -o $@ \ + $(rpath) $(CFLAGS) $(LDFLAGS) $($*.so-LDFLAGS) $^ + +cleantarg += qioctl.server qioctl-handler.so.$(hurd-version) + +qioctl.server: qioctl qioctl-handler.so.$(hurd-version) + settrans -acg $@ $^ + +check: test qioctl.server +# Prefix with `./' if not absolute path. + $(if $(filter /%,$^),$^,./$^) diff --git a/ioctl-tests/qio.h b/ioctl-tests/qio.h new file mode 100644 index 0000000..2deb213 --- /dev/null +++ b/ioctl-tests/qio.h @@ -0,0 +1,30 @@ +/* Dummy ioctls. + + Copyright (C) 2009 Free Software Foundation, Inc. + + Written by Carl Fredrik Hammar <hammy.l...@gmail.com>. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with the GNU Hurd; see the file COPYING. If not, write to the Free + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301 USA. */ + +#include <sys/ioctl.h> + +/* An ioctl to be handled by an RPC. */ +#define QNORMAL _IO('q', 0) + +/* An ioctl to be handled by a server provided ioctl-handler. */ +#define QOVERRIDE _IO('q', 1) diff --git a/ioctl-tests/qioctl-handler.c b/ioctl-tests/qioctl-handler.c new file mode 100644 index 0000000..a5b2503 --- /dev/null +++ b/ioctl-tests/qioctl-handler.c @@ -0,0 +1,15 @@ +#include <errno.h> +#include "qio.h" + +/* Handle the QOVERRIDE ioctl. */ +int +hurd_ioctl_handler (int fd, int request) +{ + if (request == QOVERRIDE) + return 0; + else + { + errno = ENOTTY; + return -1; + } +} diff --git a/ioctl-tests/qioctl.c b/ioctl-tests/qioctl.c new file mode 100644 index 0000000..cd6389c --- /dev/null +++ b/ioctl-tests/qioctl.c @@ -0,0 +1,150 @@ +/* Dummy ioctl server. + + Copyright (C) 2009 Free Software Foundation, Inc. + + Written by Carl Fredrik Hammar <hammy.l...@gmail.com>. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with the GNU Hurd; see the file COPYING. If not, write to the Free + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301 USA. */ + +#include <argp.h> +#include <error.h> +#include <fcntl.h> +#include <hurd/trivfs.h> +#include <version.h> + +#include "qioctl_S.h" +#include "ioctl_handler_S.h" + + +const char *argp_program_version = STANDARD_HURD_VERSION (qioctl); + +char *handler_file_name; + +error_t +parse_opt (int key, char *arg, struct argp_state *state) +{ + if (key == ARGP_KEY_ARG && state->arg_num == 0) + handler_file_name = arg; + else if (key == ARGP_KEY_ARG || key == ARGP_KEY_NO_ARGS) + argp_usage (state); + else + return ARGP_ERR_UNKNOWN; + return 0; +} + +static struct argp argp = { + .parser = parse_opt, + .args_doc = "FILE", + .doc = "qioctl dummy server" +}; + + +/* Trivfs stuff. */ + +int trivfs_fstype = FSTYPE_MISC; +int trivfs_fsid = 0; +int trivfs_allow_open = 0; +int trivfs_support_read = 0; +int trivfs_support_write = 0; +int trivfs_support_exec = 0; + +void +trivfs_modify_stat (struct trivfs_protid *cred, io_statbuf_t *stat) +{ +} + +error_t +trivfs_goaway (struct trivfs_control *cntl, int flags) +{ + struct port_class *class = cntl->protid_class; + + ports_inhibit_class_rpcs (class); + if (flags & FSYS_GOAWAY_FORCE || ports_count_class (class) == 0) + exit (0); + + ports_enable_class (class); + ports_resume_class_rpcs (class); + + return EBUSY; +} + +/* QNORMAL ioctl RPC. */ +error_t +S_qnormal (io_t io) +{ + return 0; +} + +/* Open and return HANDLER_FILE_NAME as described in + <hurd/ioctl_handler.defs>. */ +error_t +S_ioctl_handler_get (io_t io, io_t *handler) +{ + file_t handler_authed; + error_t err; + + err = 0; + handler_authed = file_name_lookup (handler_file_name, 0, 0); + if (handler_authed == MACH_PORT_NULL) + err = errno; + + if (!err) + { + err = io_restrict_auth (handler_authed, handler, 0, 0, 0, 0); + mach_port_deallocate (mach_task_self (), handler_authed); + } + + return err; +} + +static int +qioctl_demuxer (mach_msg_header_t *in, mach_msg_header_t *out) +{ + extern int qioctl_server (mach_msg_header_t *in, mach_msg_header_t *out); + extern int ioctl_handler_server (mach_msg_header_t *in, + mach_msg_header_t *out); + return qioctl_server (in, out) + || ioctl_handler_server (in, out) + || trivfs_demuxer (in, out); +} + +int +main (int argc, char *argv[]) +{ + mach_port_t bootstrap; + struct trivfs_control *fsys; + error_t err; + + err = argp_parse (&argp, argc, argv, 0, 0, 0); + if (err) + error (1, err, "Parsing arguments"); + + task_get_bootstrap_port (mach_task_self (), &bootstrap); + if (bootstrap == MACH_PORT_NULL) + error (1, 0, "Must be started as a translator"); + + err = trivfs_startup (bootstrap, 0, 0, 0, 0, 0, &fsys); + mach_port_deallocate (mach_task_self (), bootstrap); + if (err) + error (3, err, "Contacting parent"); + + ports_manage_port_operations_multithread (fsys->pi.bucket, qioctl_demuxer, + 30 * 1000, 0, 0); + + return 0; +} diff --git a/ioctl-tests/qioctl.defs b/ioctl-tests/qioctl.defs new file mode 100644 index 0000000..64c8b72 --- /dev/null +++ b/ioctl-tests/qioctl.defs @@ -0,0 +1,36 @@ +/* Definitions for dummy ioctls. + + Copyright (C) 2009 Free Software Foundation, Inc. + + Written by Carl Fredrik Hammar <hammy.l...@gmail.com>. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with the GNU Hurd; see the file COPYING. If not, write to the Free + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301 USA. */ + +#include <hurd/hurd_types.defs> + +INTR_INTERFACE + +/* ioctl class `q'; the subsystem is derived from calculations in + <hurd/ioctls.defs>. */ +subsystem qioctl 144000; /* XXX */ + +/* 0 QNORMAL */ +routine qnormal (io: io_t); + +/* 1 QOVERRIDE */ +skip; diff --git a/ioctl-tests/test.c b/ioctl-tests/test.c new file mode 100644 index 0000000..be9b1e5 --- /dev/null +++ b/ioctl-tests/test.c @@ -0,0 +1,92 @@ +/* Dummy ioctl test. + + Copyright (C) 2009 Free Software Foundation, Inc. + + Written by Carl Fredrik Hammar <hammy.l...@gmail.com>. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with the GNU Hurd; see the file COPYING. If not, write to the Free + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301 USA. */ + +#include <argp.h> +#include <errno.h> +#include <error.h> +#include <fcntl.h> + +#include "qio.h" + +char *file_name; + +error_t +parse_opt (int key, char *arg, struct argp_state *state) +{ + if (key == ARGP_KEY_ARG && state->arg_num == 0) + file_name = arg; + else if (key == ARGP_KEY_ARG || key == ARGP_KEY_NO_ARGS) + argp_usage (state); + else + return ARGP_ERR_UNKNOWN; + return 0; +} + +static struct argp argp = { + .parser = parse_opt, + .args_doc = "FILE", + .doc = "Call q ioctls on FILE" +}; + +int +main (int argc, char *argv[]) +{ + int file; + int i; + error_t err; + + err = argp_parse (&argp, argc, argv, 0, NULL, NULL); + if (err) + error (1, err, "Parsing arguments"); + + file = open (file_name, 0); + if (file == -1) + error (1, errno, "Opening `%s'", file_name); + + /* We call each ioctl twice to expose locking issues. */ + + for (i = 1; i <= 2; i++) + { + err = ioctl (file, QNORMAL); + if (err) + error (1, errno, "%d call of QNORMAL ioctl on `%s'", i, file_name); + } + + for (i = 1; i <= 2; i++) + { + err = ioctl (file, QOVERRIDE); + if (err) + error (1, errno, "%d call of QOVERRIDE ioctl on `%s'", i, file_name); + } + + for (i = 1; i <= 2; i++) + { + int n; + + err = ioctl (file, FIOCLEX, &n); + if (err) + error (1, errno, "%d call of FIOCLEX ioctl on `%s'", i, file_name); + } + + return 0; +} -- 1.6.3.3