about summary refs log tree commit diff
path: root/sysdeps/mach
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/mach')
-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)