From 0702b5f4fb6041e8f753b871de8a7152d4103d66 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 19 Mar 1999 15:32:17 +0000 Subject: 1999-03-19 Roland McGrath * sysdeps/mach/hurd/fcntl.c (__fcntl: case F_GETLK,F_SETLK,F_SETLKW): Support whole-file locking (only) by using the file_lock RPC. This has very wrong semantics, but is better than nothing for the time being. (Correct POSIX.1 locking will require new RPCs in the Hurd protocols that will be somewhat hairy to specify.) --- sysdeps/mach/hurd/Makefile | 26 ++++++++++++++++-- sysdeps/mach/hurd/fcntl.c | 50 +++++++++++++++++++++++++++++++--- sysdeps/mach/hurd/ptsname.c | 65 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+), 6 deletions(-) create mode 100644 sysdeps/mach/hurd/ptsname.c 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 #include #include +#include /* 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 +#include +#include +#include +#include + + +/* 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) -- cgit 1.4.1