diff options
-rw-r--r-- | sysdeps/mach/hurd/Makefile | 26 | ||||
-rw-r--r-- | sysdeps/mach/hurd/fcntl.c | 50 | ||||
-rw-r--r-- | sysdeps/mach/hurd/ptsname.c | 65 |
3 files changed, 135 insertions, 6 deletions
diff --git a/sysdeps/mach/hurd/Makefile b/sysdeps/mach/hurd/Makefile index d635e9bb0a..92048d92d2 100644 --- a/sysdeps/mach/hurd/Makefile +++ b/sysdeps/mach/hurd/Makefile @@ -111,12 +111,34 @@ $(inst_libdir)/libc.a: $(hurd)/libc-ldscript $(+force); $(do-install) $(inst_libdir)/libc_p.a: $(hurd)/libc_p-ldscript $(+force); $(do-install) endif -# Make sure these are used to build the libc.so shared object too. +# Make sure these are used to build the libc.so shared object too. There +# is a circular dependency between each of these shared objects and libc +# (many high-level libc functions call stubs, stubs call low-level libc +# functions like memcpy and mach_msg). This works out fine at run time +# (all the objects are loaded before resolving their symbols, so these +# interdependencies are fine). But to create the shared objects we must +# link them one at a time; since each needs one or both of the others to +# produce its DT_NEEDED entries and to assign its undefined symbols the +# right symbol versions, we can't do any of them before the others! To +# get around this, we link each lib*user.so shared object twice. First, +# we link an object without reference to libc.so (since we haven't linked +# libc.so yet), so it lacks a DT_NEEDED record for the libc soname it +# depends on, and its undefined symbol references lack the symbol version +# assignments they should have. We will use this shared object solely to +# link libc.so against it; that gives libc.so the proper DT_NEEDED record, +# and symbol versions assignments (if the lib*user.so object is using them). +# Finally we link a second version of the same lib*user.so shared object, +# this time linked normally against libc so it gets a proper DT_NEEDED +# record and symbol version set; this one can be installed for run-time use. rpcuserlibs := $(common-objpfx)mach/libmachuser.so \ $(common-objpfx)hurd/libhurduser.so -$(common-objpfx)libc.so: $(rpcuserlibs) +link-rpcuserlibs := $(rpcuserlibs:%user.so=%user-link.so) +$(common-objpfx)libc.so: $(link-rpcuserlibs) rpath-dirs += mach hurd +$(link-rpcuserlibs): %-link.so: %_pic.a + $(build-module) -nostdlib -Wl,-soname=$(*F).so$($(*F).so-version) + # And get them into the libc.so ldscript. $(inst_libdir)/libc.so: $(rpcuserlibs) diff --git a/sysdeps/mach/hurd/fcntl.c b/sysdeps/mach/hurd/fcntl.c index b0349832a7..21ce766970 100644 --- a/sysdeps/mach/hurd/fcntl.c +++ b/sysdeps/mach/hurd/fcntl.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1992, 93, 94, 95, 96, 97 Free Software Foundation, Inc. +/* Copyright (C) 1992,93,94,95,96,97,99 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -21,6 +21,7 @@ #include <hurd.h> #include <hurd/fd.h> #include <stdarg.h> +#include <sys/file.h> /* XXX for LOCK_* */ /* Perform file control operations on FD. */ @@ -123,10 +124,51 @@ __fcntl (int fd, int cmd, ...) case F_SETLK: case F_SETLKW: { + /* XXX + We need new RPCs to support POSIX.1 fcntl file locking!! + For the time being we support the whole-file case only, + with all kinds of WRONG WRONG WRONG semantics, + by using flock. This is definitely the Wrong Thing, + but it might be better than nothing (?). */ struct flock *fl = va_arg (ap, struct flock *); - errno = fl?ENOSYS:EINVAL; /* XXX mib needs to implement io rpcs. */ - result = -1; - break; + va_end (ap); + switch (cmd) + { + case F_GETLK: + errno = ENOSYS; + return -1; + case F_SETLK: + cmd = LOCK_NB; + break; + default: + cmd = 0; + break; + } + switch (fl->l_type) + { + case F_RDLCK: cmd |= LOCK_SH; break; + case F_WRLCK: cmd |= LOCK_EX; break; + case F_UNLCK: cmd |= LOCK_UN; break; + default: + errno = EINVAL; + return -1; + } + switch (fl->l_whence) + { + case SEEK_SET: + if (fl->l_start == 0 && fl->l_len == 0) + break; + /* FALLTHROUGH */ + case SEEK_CUR: + case SEEK_END: + errno = ENOTSUP; + return -1; + default: + errno = EINVAL; + return -1; + } + + return __flock (fd, cmd); } case F_GETFL: /* Get per-open flags. */ diff --git a/sysdeps/mach/hurd/ptsname.c b/sysdeps/mach/hurd/ptsname.c new file mode 100644 index 0000000000..95b91cf07e --- /dev/null +++ b/sysdeps/mach/hurd/ptsname.c @@ -0,0 +1,65 @@ +/* ptsname -- return the name of a pty slave given an FD to the pty master + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <errno.h> +#include <string.h> +#include <hurd.h> +#include <hurd/fd.h> +#include <hurd/term.h> + + +/* Return the pathname of the pseudo terminal slave associated with + the master FD is open on, or NULL on errors. + The returned storage is good until the next call to this function. */ +char * +ptsname (int fd) +{ + static char peername[1024]; /* XXX */ + error_t err; + + err = __ptsname_r (fd, peername, sizeof (peername)); + if (err) + __set_errno (err); + + return err ? NULL : peername; +} + + +/* Store at most BUFLEN characters of the pathname of the slave pseudo + terminal associated with the master FD is open on in BUF. + Return 0 on success, otherwise an error number. */ +int +__ptsname_r (int fd, char *buf, size_t buflen) +{ + char peername[1024]; /* XXX */ + size_t len; + error_t err; + + peername[0] = '\0'; + if (err = HURD_DPORT_USE (fd, __term_get_peername (port, peername))) + return _hurd_fd_error (fd, err); + + len = strlen (peername) + 1; + if (len > buflen) + return ERANGE; + + memcpy (buf, peername, len); + return 0; +} +weak_alias (__ptsname_r, ptsname_r) |