diff --git a/build-aux/configure-lib.sh b/build-aux/configure-lib.sh index 58af71d0..7baef702 100644 --- a/build-aux/configure-lib.sh +++ b/build-aux/configure-lib.sh @@ -157,7 +157,9 @@ lib/string/strncmp.c if test $mes_kernel = gnu; then libc_SOURCES="$libc_SOURCES +lib/gnu/_open3.c lib/gnu/_read.c +lib/gnu/dir-lookup.c lib/gnu/fd-read.c lib/gnu/io-read.c lib/stub/access.c @@ -171,7 +173,6 @@ lib/stub/fork.c lib/stub/_getcwd.c lib/stub/gettimeofday.c lib/stub/ioctl.c -lib/stub/_open3.c lib/stub/time.c lib/stub/unlink.c lib/stub/waitpid.c diff --git a/include/fcntl.h b/include/fcntl.h index f29d56ac..bfb870df 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -30,6 +30,7 @@ #else // ! SYSTEM_LIBC // *INDENT-OFF* +#if __linux__ #define O_RDONLY 0 #define O_WRONLY 1 #define O_RDWR 2 @@ -38,6 +39,16 @@ #define O_TRUNC 0x200 #define O_APPEND 0x400 #define O_DIRECTORY 0x10000 +#elif __GNU__ +#define O_RDONLY 1 +#define O_WRONLY 2 +#define O_RDWR 3 +#define O_CREAT 0x10 +#define O_APPEND 0x100 +#define O_TRUNC 0x10000 +#else +#error platform not supported +#endif // *INDENT-ON* #define FD_CLOEXEC 1 diff --git a/include/gnu/syscall.h b/include/gnu/syscall.h index 51b98ecd..26bd52dc 100644 --- a/include/gnu/syscall.h +++ b/include/gnu/syscall.h @@ -38,6 +38,12 @@ enum SYS__task_get_special_port = 2058, }; +// hurd/fsys.defs +enum + { + SYS__dir_lookup = 20018, + }; + // hurd/io.defs enum { diff --git a/lib/gnu/_open3.c b/lib/gnu/_open3.c new file mode 100644 index 00000000..932111d9 --- /dev/null +++ b/lib/gnu/_open3.c @@ -0,0 +1,48 @@ +/* -*-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_file_name_lookup, __hurd_file_name_lookup_retry + Copyright (C) 1992-2016 Free Software Foundation, Inc. + */ + +#include +#include +#include +#include + +int +_open3 (char const *file_name, int flags, int mode) +{ + mach_port_t port; + int do_retry; + char retry_name[1024]; + int start_dir = (file_name[0] == '/') ? INIT_PORT_CRDIR : INIT_PORT_CWDIR; + mach_port_t start_port = _hurd_startup_data.portarray[start_dir]; + while (file_name[0] == '/') + file_name++; + error_t e = __dir_lookup (start_port, file_name, flags, mode, &do_retry, retry_name, &port); + if (e) + return -1; + int fd = _hurd_dtable_count++; + _hurd_dtable[fd] = port; + return fd; +} diff --git a/lib/gnu/dir-lookup.c b/lib/gnu/dir-lookup.c new file mode 100644 index 00000000..d3a8426a --- /dev/null +++ b/lib/gnu/dir-lookup.c @@ -0,0 +1,76 @@ +/* -*-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 + +struct mach_msg_string_int_int +{ + mach_msg_header_t header; + mach_msg_type_t type_one; string_t one; + mach_msg_type_t type_two; int two; + mach_msg_type_t type_three; int three; +}; + +struct mach_msg_int_int_string_int +{ + mach_msg_header_t header; + mach_msg_type_t type_one; int one; + mach_msg_type_t type_two; int two; + mach_msg_type_t type_three; string_t three; + mach_msg_type_t type_four; int four; +}; + +mach_msg_type_t mach_msg_type_file_name = + { + /* msgt_name = */ (unsigned char) MACH_MSG_TYPE_STRING_C, + /* msgt_size = */ 8, + /* msgt_number = */ 1024, + /* msgt_inline = */ 1, + /* msgt_longform = */ 0, + /* msgt_deallocate = */ 0, + /* msgt_unused = */ 0 + }; + +kern_return_t __dir_lookup (file_t start_dir, string_t file_name, int flags, mode_t mode, retry_type *do_retry, string_t retry_name, mach_port_t *port) +{ + union message + { + struct mach_msg_string_int_int request; + struct mach_msg_int_int_string_int reply; + }; + union message message = {0}; + message.request.header.msgh_size = sizeof (message.request); + message.request.type_one = mach_msg_type_file_name; + strcpy (message.request.one, file_name); + message.request.type_two = mach_msg_type_int32; + message.request.two = flags; + message.request.type_three = mach_msg_type_int32; + message.request.three = mode; + + kern_return_t result = __syscall_get (start_dir, SYS__dir_lookup, + &message.request.header, + sizeof (message.reply)); + if (message.reply.one != KERN_SUCCESS) + return message.reply.one; + *port = message.reply.four; + return result; +} diff --git a/lib/gnu/io-write.c b/lib/gnu/io-write.c index bc768672..d7e31b0a 100644 --- a/lib/gnu/io-write.c +++ b/lib/gnu/io-write.c @@ -20,7 +20,7 @@ #include -struct mach_msg_pointer_int +struct mach_msg_pointer_loff { mach_msg_header_t header; mach_msg_type_long_t type_one; char *one; @@ -30,8 +30,8 @@ struct mach_msg_pointer_int 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); + struct mach_msg_pointer_loff message = {0}; + message.header.msgh_size = sizeof (struct mach_msg_pointer_loff); message.type_one = mach_msg_type_pointer; message.one = data; message.type_two = mach_msg_type_int64; diff --git a/lib/stdio/fopen.c b/lib/stdio/fopen.c index be4c3f62..6342e0a2 100644 --- a/lib/stdio/fopen.c +++ b/lib/stdio/fopen.c @@ -54,7 +54,7 @@ fopen (char const *file_name, char const *opentype) fd = _open3 (file_name, flags, mode); } else - fd = _open3 (file_name, 0, 0); + fd = _open3 (file_name, O_RDONLY, 0); if (__mes_debug ()) { diff --git a/lib/tests/posix/50-open-read.c b/lib/tests/posix/50-open-read.c index 7e7ff0b8..3b901d2b 100644 --- a/lib/tests/posix/50-open-read.c +++ b/lib/tests/posix/50-open-read.c @@ -41,7 +41,7 @@ main (int argc, char const *argv[]) eputs ("test open:"); eputs (file_name); eputs ("\n"); - int filedes = open (file_name, 0, 0); + int filedes = open (file_name, O_RDONLY, 0); if (filedes <= 2) return 1; char buf[20]; diff --git a/lib/tests/stdio/90-fseek.c b/lib/tests/stdio/90-fseek.c index 8d204f05..3d5121fc 100644 --- a/lib/tests/stdio/90-fseek.c +++ b/lib/tests/stdio/90-fseek.c @@ -27,7 +27,7 @@ int main () { - int fd = open ("../COPYING", 0); + int fd = open ("../COPYING", O_RDONLY); if (fd <= 0) return 1; FILE *f = fdopen (fd, "r");