From db4a202c6b28914c43adb19a32074372f7ea937e Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Mon, 11 Mar 2019 17:45:56 -0400 Subject: [PATCH] hurd: Add _write. * include/gnu/syscall.h (SYS__io_write): Add enum field. (_hurd_dtable, _hurd_dtable_size): Declare variable. (fd_get, fd_write, __io_write, __syscall_put): Declare. * lib/gnu/hurd-start.c (_hurd_dtable, _hurd_dtable_size): Define variable. * lib/gnu/_write.c: New file. * lib/gnu/fd-get.c (fd_get): New file. * lib/gnu/fd-write.c (fd_write): New file. * lib/gnu/io-write.c: New file. * lib/gnu/syscall.c (__syscall_put): New function. * build-aux/cofnigure-lib.sh (libc_mini_SOURCES): Add write sources. * lib/tests/mes/30-oputs.c (main): Update. * lib/tests/mes/30-oputs.stdout: New file. * lib/tests/mes/30-eputs.c: New test. * lib/tests/mes/30-eputs.stderr: New file. * build-aux/check-mescc.sh (TESTS): Add it. --- .gitignore | 2 -- build-aux/check-mescc.sh | 1 + build-aux/configure-lib.sh | 4 +++ include/gnu/hurd.h | 18 ++++++++++-- include/gnu/syscall.h | 12 ++++++++ lib/gnu/_write.c | 34 ++++++++++++++++++++++ lib/gnu/exec-startup-get-data.c | 1 + lib/gnu/fd-get.c | 37 ++++++++++++++++++++++++ lib/gnu/fd-write.c | 41 +++++++++++++++++++++++++++ lib/gnu/hurd-start.c | 5 ++++ lib/gnu/io-write.c | 50 +++++++++++++++++++++++++++++++++ lib/gnu/syscall.c | 44 +++++++++++++++++++++++++++++ lib/tests/mes/30-eputs.c | 29 +++++++++++++++++++ lib/tests/mes/30-eputs.stderr | 2 ++ lib/tests/mes/30-oputs.c | 2 +- lib/tests/mes/30-oputs.stdout | 2 ++ 16 files changed, 279 insertions(+), 5 deletions(-) create mode 100644 lib/gnu/_write.c create mode 100644 lib/gnu/fd-get.c create mode 100644 lib/gnu/fd-write.c create mode 100644 lib/gnu/io-write.c create mode 100644 lib/tests/mes/30-eputs.c create mode 100644 lib/tests/mes/30-eputs.stderr create mode 100644 lib/tests/mes/30-oputs.stdout diff --git a/.gitignore b/.gitignore index e7ae9341..7c534a14 100644 --- a/.gitignore +++ b/.gitignore @@ -34,8 +34,6 @@ *.a *.o *.seed-out -*.stderr -*.stdout /lib/tests/*/[0-9a][0-9a-z]-* !/lib/tests/*/*.c diff --git a/build-aux/check-mescc.sh b/build-aux/check-mescc.sh index 68865e8b..15204d35 100755 --- a/build-aux/check-mescc.sh +++ b/build-aux/check-mescc.sh @@ -75,6 +75,7 @@ lib/tests/scaffold/23-global-pointer-pointer-ref.c lib/tests/scaffold/23-pointer-sub.c lib/tests/scaffold/23-pointer.c lib/tests/mes/30-oputs.c +lib/tests/mes/30-eputs.c lib/tests/string/30-strlen.c lib/tests/scaffold/30-exit-0.c lib/tests/scaffold/30-exit-42.c diff --git a/build-aux/configure-lib.sh b/build-aux/configure-lib.sh index af1803ad..1499e2dd 100644 --- a/build-aux/configure-lib.sh +++ b/build-aux/configure-lib.sh @@ -46,6 +46,10 @@ lib/string/strlen.c libc_mini_shared_SOURCES="$libc_mini_shared_SOURCES lib/gnu/_exit.c lib/gnu/exec-startup-get-data.c +lib/gnu/fd-get.c +lib/gnu/fd-write.c +lib/gnu/io-write.c +lib/gnu/_write.c lib/gnu/hurd-start.c lib/gnu/proc-mark-exit.c lib/gnu/syscall.c diff --git a/include/gnu/hurd.h b/include/gnu/hurd.h index 1ed66790..fb3c1a41 100644 --- a/include/gnu/hurd.h +++ b/include/gnu/hurd.h @@ -24,6 +24,16 @@ #define _GNU_SOURCE 1 #define __USE_GNU 1 +#include +#include + +#ifndef _BITS_TYPES_H +#ifndef _LOFF_T +#define _LOFF_T +typedef off64_t loff_t; +#endif +#endif + #include #include #include @@ -44,8 +54,12 @@ struct hurd_startup_data vm_address_t user_entry; }; -extern mach_port_t *_hurd_init_dtable; -extern mach_msg_type_number_t _hurd_init_dtablesize; +#define _HURD_DTABLE_MAX 1024 +extern mach_port_t _hurd_dtable[_HURD_DTABLE_MAX]; +extern int _hurd_dtable_size; 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); + #endif // __MES_GNU_HURD_H diff --git a/include/gnu/syscall.h b/include/gnu/syscall.h index 7365ed0a..7420fac6 100644 --- a/include/gnu/syscall.h +++ b/include/gnu/syscall.h @@ -38,6 +38,12 @@ enum SYS__task_get_special_port = 2058, }; +// hurd/io.defs +enum + { + SYS__io_write = 21000, + }; + // hurd/process.defs enum { @@ -51,6 +57,8 @@ enum }; extern mach_msg_type_t mach_msg_type_int32; +extern mach_msg_type_t mach_msg_type_int64; +extern mach_msg_type_long_t mach_msg_type_pointer; struct mach_msg { @@ -102,6 +110,7 @@ struct mach_msg_startup_info kern_return_t __syscall (mach_port_t port, int sys_call); kern_return_t __syscall2 (mach_port_t port, int sys_call, int one, int two); kern_return_t __syscall_get (mach_port_t port, int sys_call, mach_msg_header_t *message, size_t size); +kern_return_t __syscall_put (mach_port_t port, int sys_call, mach_msg_header_t *message, size_t size); // mach.defs kern_return_t __task_terminate (mach_port_t task); @@ -112,4 +121,7 @@ kern_return_t __vm_statistics (mach_port_t task, vm_statistics_data_t *vm_stats) kern_return_t __proc_mark_exit (mach_port_t process, int one, int two); kern_return_t __exec_startup_get_data (mach_port_t bootstrap, struct hurd_startup_data *data); +// 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); + #endif // __MES_GNU_SYSCALL_H diff --git a/lib/gnu/_write.c b/lib/gnu/_write.c new file mode 100644 index 00000000..656b16d4 --- /dev/null +++ b/lib/gnu/_write.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 +_write (int filedes, void const *buffer, size_t size) +{ + mach_port_t p = fd_get (filedes); + error_t e = fd_write (p, buffer, &size, -1); + if (!e) + return size; + return -1; +} diff --git a/lib/gnu/exec-startup-get-data.c b/lib/gnu/exec-startup-get-data.c index 0a065601..142d712e 100644 --- a/lib/gnu/exec-startup-get-data.c +++ b/lib/gnu/exec-startup-get-data.c @@ -18,6 +18,7 @@ * along with GNU Mes. If not, see . */ +//#include #include static void diff --git a/lib/gnu/fd-get.c b/lib/gnu/fd-get.c new file mode 100644 index 00000000..23f42b2a --- /dev/null +++ b/lib/gnu/fd-get.c @@ -0,0 +1,37 @@ +/* -*-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_get + Copyright (C) 1993-2016 Free Software Foundation, Inc. + */ + +#include +#include +#include + +mach_port_t +fd_get (int filedes) +{ + if (filedes >=0 && filedes <= _hurd_dtable_size) + return _hurd_dtable[filedes]; + return 0; +} diff --git a/lib/gnu/fd-write.c b/lib/gnu/fd-write.c new file mode 100644 index 00000000..9e18bc5b --- /dev/null +++ b/lib/gnu/fd-write.c @@ -0,0 +1,41 @@ +/* -*-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_write -- write to a file descriptor; handles job control et al. + Copyright (C) 1993-2016 Free Software Foundation, Inc. + */ + +#include +#include +#include +#include + +error_t +fd_write (mach_port_t port, void const *buffer, size_t *size, loff_t offset) +{ + mach_msg_type_number_t wrote = 0; + error_t err = __io_write (port, buffer, *size, 0, &wrote); + if (! err) + *size = wrote; + + return err; +} diff --git a/lib/gnu/hurd-start.c b/lib/gnu/hurd-start.c index fea1eb6c..fcaaba61 100644 --- a/lib/gnu/hurd-start.c +++ b/lib/gnu/hurd-start.c @@ -33,6 +33,8 @@ #include struct hurd_startup_data _hurd_startup_data; +mach_port_t _hurd_dtable[_HURD_DTABLE_MAX]; +int _hurd_dtable_size; void __mach_init (void); @@ -44,4 +46,7 @@ _hurd_start () __task_get_special_port (__mach_task_self (), TASK_BOOTSTRAP_PORT, &bootstrap); __exec_startup_get_data (bootstrap, &_hurd_startup_data); + _hurd_dtable_size = _hurd_startup_data.dtablesize; + for (int i = 0; i < _hurd_dtable_size; i++) + _hurd_dtable[i] = _hurd_startup_data.dtable[i]; } diff --git a/lib/gnu/io-write.c b/lib/gnu/io-write.c new file mode 100644 index 00000000..bc768672 --- /dev/null +++ b/lib/gnu/io-write.c @@ -0,0 +1,50 @@ +/* -*-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_pointer_int +{ + mach_msg_header_t header; + mach_msg_type_long_t type_one; char *one; + mach_msg_type_t type_two; loff_t two; +}; + +kern_return_t +__io_write (io_t io, data_t data, mach_msg_type_number_t size, loff_t offset, vm_size_t *wrote) +{ + struct mach_msg_pointer_int message = {0}; + message.header.msgh_size = sizeof (struct mach_msg_pointer_int); + message.type_one = mach_msg_type_pointer; + message.one = data; + message.type_two = mach_msg_type_int64; + message.two = offset; + + message.type_one.msgtl_number = size; + message.type_one.msgtl_header.msgt_inline = 0; + message.header.msgh_bits = MACH_MSGH_BITS_COMPLEX; + + kern_return_t result = __syscall_put (io, SYS__io_write, + &message.header, + sizeof (struct mach_msg_2)); + if (result == KERN_SUCCESS) + *wrote = message.two; + return result; +} diff --git a/lib/gnu/syscall.c b/lib/gnu/syscall.c index 01052986..bd919a47 100644 --- a/lib/gnu/syscall.c +++ b/lib/gnu/syscall.c @@ -33,6 +33,33 @@ mach_msg_type_t mach_msg_type_int32 = .msgt_unused = 0 // msgt_unused }; +mach_msg_type_long_t mach_msg_type_pointer = + { + { + 0, // msgt_name + 0, // msgt_size + 0, // msgt_number + 1, // msgt_inline FIXME: we always outline... + 1, // msgt_longform + 0, // msgt_deallocate + 0, // msgt_unused + }, + MACH_MSG_TYPE_CHAR, // msgtl_name + 8, // msgtl_size + 2048, // msgtl_number + }; + +mach_msg_type_t mach_msg_type_int64 = + { + (unsigned char) MACH_MSG_TYPE_INTEGER_64, // msgt_name + 64, // msgt_size + 1, // msgt_number + 1, // msgt_inline + 0, // msgt_longform + 0, // msgt_deallocate + 0, // msgt_unused + }; + kern_return_t __syscall (mach_port_t port, int sys_call) { @@ -97,3 +124,20 @@ __syscall_get (mach_port_t port, int sys_call, mach_msg_header_t *message, size_ MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); } + +kern_return_t +__syscall_put (mach_port_t port, int sys_call, mach_msg_header_t *message, size_t size) +{ + message->msgh_bits |= MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE); + message->msgh_remote_port = port; + message->msgh_local_port = __mach_reply_port (); + message->msgh_seqno = 0; + message->msgh_id = sys_call; + return __mach_msg (message, + MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, + message->msgh_size, + size, + message->msgh_local_port, + MACH_MSG_TIMEOUT_NONE, + MACH_PORT_NULL); +} diff --git a/lib/tests/mes/30-eputs.c b/lib/tests/mes/30-eputs.c new file mode 100644 index 00000000..c5cd48b2 --- /dev/null +++ b/lib/tests/mes/30-eputs.c @@ -0,0 +1,29 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2017,2018,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 + +int +main () +{ + eputs ("\n"); + eputs ("Hello, GNU Mes\n"); + return 0; +} diff --git a/lib/tests/mes/30-eputs.stderr b/lib/tests/mes/30-eputs.stderr new file mode 100644 index 00000000..a09f869c --- /dev/null +++ b/lib/tests/mes/30-eputs.stderr @@ -0,0 +1,2 @@ + +Hello, GNU Mes diff --git a/lib/tests/mes/30-oputs.c b/lib/tests/mes/30-oputs.c index 55090857..81481828 100644 --- a/lib/tests/mes/30-oputs.c +++ b/lib/tests/mes/30-oputs.c @@ -24,6 +24,6 @@ int main () { oputs ("\n"); - oputs ("mes\n"); + oputs ("Hello, GNU Mes\n"); return 0; } diff --git a/lib/tests/mes/30-oputs.stdout b/lib/tests/mes/30-oputs.stdout new file mode 100644 index 00000000..a09f869c --- /dev/null +++ b/lib/tests/mes/30-oputs.stdout @@ -0,0 +1,2 @@ + +Hello, GNU Mes