aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sysdeps/mach/hurd/Makefile26
-rw-r--r--sysdeps/mach/hurd/fcntl.c50
-rw-r--r--sysdeps/mach/hurd/ptsname.c65
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)