From 6d3b9b687df41d9e2d28609059cbed1e63ba7468 Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Tue, 12 Mar 2019 21:15:30 +0100 Subject: [PATCH] hurd: Add _read. * include/gnu/hurd.h (fd_read): Declare. * include/gnu/syscall.h (SYS__io_read): New value. * lib/gnu/_read.c: New file. * lib/gnu/fd-read.c: New file. * lib/gnu/io-read.c: New file. * build-aux/configure-lib.sh (libc_SOURCES): Add _read sources. --- build-aux/configure-lib.sh | 8 +++++ include/gnu/hurd.h | 1 + include/gnu/syscall.h | 9 ++++++ lib/gnu/_read.c | 34 +++++++++++++++++++++ lib/gnu/fd-read.c | 40 +++++++++++++++++++++++++ lib/gnu/io-read.c | 60 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 152 insertions(+) create mode 100644 lib/gnu/_read.c create mode 100644 lib/gnu/fd-read.c create mode 100644 lib/gnu/io-read.c diff --git a/build-aux/configure-lib.sh b/build-aux/configure-lib.sh index 1499e2dd..2a6946ea 100644 --- a/build-aux/configure-lib.sh +++ b/build-aux/configure-lib.sh @@ -149,6 +149,14 @@ lib/string/strcpy.c lib/string/strncmp.c " +if test $mes_kernel = gnu; then + libc_SOURCES="$libc_SOURCES +lib/gnu/_read.c +lib/gnu/fd-read.c +lib/gnu/io-read.c +" +fi + if test $mes_kernel = linux; then libc_SOURCES="$libc_SOURCES lib/linux/access.c diff --git a/include/gnu/hurd.h b/include/gnu/hurd.h index fb3c1a41..419cc606 100644 --- a/include/gnu/hurd.h +++ b/include/gnu/hurd.h @@ -61,5 +61,6 @@ extern struct hurd_startup_data _hurd_startup_data; mach_port_t fd_get (int filedes); error_t fd_write (mach_port_t port, void const *buffer, size_t *size, loff_t offset); +error_t fd_read (mach_port_t port, void *buffer, size_t *size, loff_t offset); #endif // __MES_GNU_HURD_H diff --git a/include/gnu/syscall.h b/include/gnu/syscall.h index 7420fac6..51b98ecd 100644 --- a/include/gnu/syscall.h +++ b/include/gnu/syscall.h @@ -42,6 +42,7 @@ enum enum { SYS__io_write = 21000, + SYS__io_read, }; // hurd/process.defs @@ -78,6 +79,13 @@ struct mach_msg_2 mach_msg_type_t type_two; int two; }; +struct mach_msg_loff_int +{ + mach_msg_header_t header; + mach_msg_type_t type_one; loff_t one; + mach_msg_type_t type_two; int two; +}; + struct mach_msg_startup_info { mach_msg_header_t header; @@ -123,5 +131,6 @@ kern_return_t __exec_startup_get_data (mach_port_t bootstrap, struct hurd_startu // io.c kern_return_t __io_write (io_t io_object, data_t data, mach_msg_type_number_t size, loff_t offset, vm_size_t *wrote); +kern_return_t __io_read (io_t io, data_t *data, mach_msg_type_number_t *read, loff_t offset, vm_size_t size); #endif // __MES_GNU_SYSCALL_H diff --git a/lib/gnu/_read.c b/lib/gnu/_read.c new file mode 100644 index 00000000..8035ed98 --- /dev/null +++ b/lib/gnu/_read.c @@ -0,0 +1,34 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2019 Jan (janneke) Nieuwenhuizen + * + * This file is part of GNU Mes. + * + * GNU Mes 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 3 of the License, or (at + * your option) any later version. + * + * GNU Mes 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 GNU Mes. If not, see . + */ + +#include +#include +#include +#include + +ssize_t +_read (int filedes, void *buffer, size_t size) +{ + mach_port_t p = fd_get (filedes); + error_t e = fd_read (p, buffer, &size, -1); + if (!e) + return size; + return -1; +} diff --git a/lib/gnu/fd-read.c b/lib/gnu/fd-read.c new file mode 100644 index 00000000..bf8da45d --- /dev/null +++ b/lib/gnu/fd-read.c @@ -0,0 +1,40 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2019 Jan (janneke) Nieuwenhuizen + * + * This file is part of GNU Mes. + * + * GNU Mes 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 3 of the License, or (at + * your option) any later version. + * + * GNU Mes 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 GNU Mes. If not, see . + */ + +/** Commentary: + Inspired by implementation in GNU C Library: + _hurd_fd_read + Copyright (C) 1993-2016 Free Software Foundation, Inc. + */ + +#include +#include +#include +#include + +error_t +fd_read (mach_port_t port, void *buffer, size_t *read, loff_t offset) +{ + char *data; + error_t e = __io_read (port, &data, read, offset, *read); + if (!e) + memcpy (buffer, data, *read); + return e; +} diff --git a/lib/gnu/io-read.c b/lib/gnu/io-read.c new file mode 100644 index 00000000..8b10ae8e --- /dev/null +++ b/lib/gnu/io-read.c @@ -0,0 +1,60 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2019 Jan (janneke) Nieuwenhuizen + * + * This file is part of GNU Mes. + * + * GNU Mes 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 3 of the License, or (at + * your option) any later version. + * + * GNU Mes 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 GNU Mes. If not, see . + */ + +#include + +struct mach_msg_int_pointer +{ + mach_msg_header_t header; + mach_msg_type_t type_one; int one; + mach_msg_type_long_t type_two; union {char *two; char pointer[2048];}; +}; + +kern_return_t +__io_read (io_t io, data_t *data, mach_msg_type_number_t *read, loff_t offset, vm_size_t size) +{ + union message + { + struct mach_msg_loff_int request; + struct mach_msg_int_pointer reply; + }; + union message message = {0}; + message.request.header.msgh_size = sizeof (message.request); + message.request.type_one = mach_msg_type_int64; + message.request.one = offset; + message.request.type_two = mach_msg_type_int32; + message.request.two = size; + + kern_return_t result = __syscall_put (io, SYS__io_read, + &message.request.header, + sizeof (message.reply)); + + if (result == KERN_SUCCESS) + { + *read = message.reply.type_two.msgtl_number; + *data = message.reply.pointer; + } + else + { + *read = 0; + *data = 0; + } + return result; +}