about summary refs log tree commit diff
path: root/REORG.TODO/hurd/hurd/fd.h
diff options
context:
space:
mode:
Diffstat (limited to 'REORG.TODO/hurd/hurd/fd.h')
-rw-r--r--REORG.TODO/hurd/hurd/fd.h275
1 files changed, 275 insertions, 0 deletions
diff --git a/REORG.TODO/hurd/hurd/fd.h b/REORG.TODO/hurd/hurd/fd.h
new file mode 100644
index 0000000000..8954be0d50
--- /dev/null
+++ b/REORG.TODO/hurd/hurd/fd.h
@@ -0,0 +1,275 @@
+/* File descriptors.
+   Copyright (C) 1993-2017 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef	_HURD_FD_H
+
+#define	_HURD_FD_H	1
+#include <features.h>
+
+#include <cthreads.h>
+
+#include <hurd/hurd_types.h>
+#include <hurd/port.h>
+#include <sys/socket.h>
+
+
+/* Structure representing a file descriptor.  */
+
+struct hurd_fd
+  {
+    struct hurd_port port;	/* io server port.  */
+    int flags;			/* fcntl flags; locked by port.lock.  */
+
+    /* Normal port to the ctty.  When `port' is our ctty, this is a port to
+       the same io object but which never returns EBACKGROUND; when not,
+       this is nil.  */
+    struct hurd_port ctty;
+  };
+
+
+/* Current file descriptor table.  */
+
+extern int _hurd_dtablesize;
+extern struct hurd_fd **_hurd_dtable;
+extern struct mutex _hurd_dtable_lock; /* Locks those two variables.  */
+
+#include <hurd/signal.h>
+
+#ifndef _HURD_FD_H_EXTERN_INLINE
+#define _HURD_FD_H_EXTERN_INLINE __extern_inline
+#endif
+
+/* Returns the descriptor cell for FD.  If FD is invalid or unused, return
+   NULL.  The cell is unlocked; when ready to use it, lock it and check for
+   it being unused.  */
+
+_HURD_FD_H_EXTERN_INLINE struct hurd_fd *
+_hurd_fd_get (int fd)
+{
+  struct hurd_fd *descriptor;
+
+  HURD_CRITICAL_BEGIN;
+  __mutex_lock (&_hurd_dtable_lock);
+  if (fd < 0 || fd >= _hurd_dtablesize)
+    descriptor = NULL;
+  else
+    {
+      struct hurd_fd *cell = _hurd_dtable[fd];
+      if (cell == NULL)
+	/* No descriptor allocated at this index.  */
+	descriptor = NULL;
+      else
+	{
+	  __spin_lock (&cell->port.lock);
+	  if (cell->port.port == MACH_PORT_NULL)
+	    /* The descriptor at this index has no port in it.
+	       This happens if it existed before but was closed.  */
+	    descriptor = NULL;
+	  else
+	    descriptor = cell;
+	  __spin_unlock (&cell->port.lock);
+	}
+    }
+  __mutex_unlock (&_hurd_dtable_lock);
+  HURD_CRITICAL_END;
+
+  return descriptor;
+}
+
+
+/* Evaluate EXPR with the variable `descriptor' bound to a pointer to the
+   file descriptor structure for FD.   */
+
+#define	HURD_FD_USE(fd, expr)						      \
+  ({ struct hurd_fd *descriptor = _hurd_fd_get (fd);			      \
+     descriptor == NULL ? EBADF : (expr); })
+
+/* Evaluate EXPR with the variable `port' bound to the port to FD, and
+   `ctty' bound to the ctty port.  */
+
+#define HURD_DPORT_USE(fd, expr) \
+  HURD_FD_USE ((fd), HURD_FD_PORT_USE (descriptor, (expr)))
+
+/* Likewise, but FD is a pointer to the file descriptor structure.  */
+
+#define	HURD_FD_PORT_USE(fd, expr)					      \
+  ({ error_t __result;							      \
+     struct hurd_fd *const __d = (fd);					      \
+     struct hurd_userlink __ulink, __ctty_ulink;			      \
+     io_t port, ctty;							      \
+     void *crit = _hurd_critical_section_lock ();			      \
+     __spin_lock (&__d->port.lock);					      \
+     if (__d->port.port == MACH_PORT_NULL)				      \
+       {								      \
+	 __spin_unlock (&__d->port.lock);				      \
+	 _hurd_critical_section_unlock (crit);				      \
+	 __result = EBADF;						      \
+       }								      \
+     else								      \
+       {								      \
+	 ctty = _hurd_port_get (&__d->ctty, &__ctty_ulink);		      \
+	 port = _hurd_port_locked_get (&__d->port, &__ulink);		      \
+	 _hurd_critical_section_unlock (crit);				      \
+	 __result = (expr);						      \
+	 _hurd_port_free (&__d->port, &__ulink, port);			      \
+	 if (ctty != MACH_PORT_NULL)					      \
+	   _hurd_port_free (&__d->ctty, &__ctty_ulink, ctty);		      \
+       }								      \
+     __result; })
+
+#include <errno.h>
+
+/* Check if ERR should generate a signal.
+   Returns the signal to take, or zero if none.  */
+
+_HURD_FD_H_EXTERN_INLINE int
+_hurd_fd_error_signal (error_t err)
+{
+  switch (err)
+    {
+    case EMACH_SEND_INVALID_DEST:
+    case EMIG_SERVER_DIED:
+      /* The server has disappeared!  */
+      return SIGLOST;
+    case EPIPE:
+      return SIGPIPE;
+    default:
+      /* Having a default case avoids -Wenum-switch warnings.  */
+      return 0;
+    }
+}
+
+/* Handle an error from an RPC on a file descriptor's port.  You should
+   always use this function to handle errors from RPCs made on file
+   descriptor ports.  Some errors are translated into signals.  */
+
+_HURD_FD_H_EXTERN_INLINE error_t
+_hurd_fd_error (int fd, error_t err)
+{
+  int signo = _hurd_fd_error_signal (err);
+  if (signo)
+    {
+      const struct hurd_signal_detail detail
+	= { code: fd, error: err, exc: 0 };
+      _hurd_raise_signal (NULL, signo, &detail);
+    }
+  return err;
+}
+
+/* Handle error code ERR from an RPC on file descriptor FD's port.
+   Set `errno' to the appropriate error code, and always return -1.  */
+
+_HURD_FD_H_EXTERN_INLINE int
+__hurd_dfail (int fd, error_t err)
+{
+  errno = _hurd_fd_error (fd, err);
+  return -1;
+}
+
+/* Likewise, but do not raise SIGPIPE on EPIPE if flags contain
+   MSG_NOSIGNAL.  */
+
+_HURD_FD_H_EXTERN_INLINE int
+__hurd_sockfail (int fd, int flags, error_t err)
+{
+  if (!(flags & MSG_NOSIGNAL) || err != EPIPE)
+    err = _hurd_fd_error (fd, err);
+  errno = err;
+  return -1;
+}
+
+/* Set up *FD to have PORT its server port, doing appropriate ctty magic.
+   Does no locking or unlocking.  */
+
+extern void _hurd_port2fd (struct hurd_fd *fd, io_t port, int flags);
+
+/* Allocate a new file descriptor and install PORT in it (doing any
+   appropriate ctty magic); consumes a user reference on PORT.  FLAGS are
+   as for `open'; only O_IGNORE_CTTY and O_CLOEXEC are meaningful, but all are
+   saved.
+
+   If the descriptor table is full, set errno, and return -1.
+   If DEALLOC is nonzero, deallocate PORT first.  */
+
+extern int _hurd_intern_fd (io_t port, int flags, int dealloc);
+
+/* Allocate a new file descriptor in the table and return it, locked.  The
+   new descriptor number will be no less than FIRST_FD.  If the table is
+   full, set errno to EMFILE and return NULL.  If FIRST_FD is negative or
+   bigger than the size of the table, set errno to EINVAL and return NULL.  */
+
+extern struct hurd_fd *_hurd_alloc_fd (int *fd_ptr, int first_fd);
+
+/* Allocate a new file descriptor structure and initialize its port cells
+   with PORT and CTTY.  (This does not affect the descriptor table.)  */
+
+extern struct hurd_fd *_hurd_new_fd (io_t port, io_t ctty);
+
+/* Close a file descriptor, making it available for future reallocation.  */
+
+extern error_t _hurd_fd_close (struct hurd_fd *fd);
+
+/* Read and write data from a file descriptor; just like `read' and `write'
+   if OFFSET is -1, or like `pread' and `pwrite' if OFFSET is not -1.
+   If successful, stores the amount actually read or written in *NBYTES.  */
+
+extern error_t _hurd_fd_read (struct hurd_fd *fd,
+			      void *buf, size_t *nbytes, loff_t offset);
+extern error_t _hurd_fd_write (struct hurd_fd *fd,
+			       const void *buf, size_t *nbytes, loff_t offset);
+
+
+/* Call *RPC on PORT and/or CTTY; if a call on CTTY returns EBACKGROUND,
+   generate SIGTTIN/SIGTTOU or EIO as appropriate.  */
+
+extern error_t _hurd_ctty_input (io_t port, io_t ctty, error_t (*rpc) (io_t));
+extern error_t _hurd_ctty_output (io_t port, io_t ctty, error_t (*rpc) (io_t));
+
+
+/* The guts of `select' and `poll'.  Check the first NFDS descriptors
+   either in POLLFDS (if nonnull) or in each of READFDS, WRITEFDS,
+   EXCEPTFDS that is nonnull.  If TIMEOUT is not NULL, time out after
+   waiting the interval specified therein.  If SIGMASK is nonnull,
+   the set of blocked signals is temporarily set to that during this call.
+   Returns the number of ready descriptors, or -1 for errors.  */
+struct pollfd;
+struct timespec;
+extern int _hurd_select (int nfds, struct pollfd *pollfds,
+			 fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+			 const struct timespec *timeout,
+			 const sigset_t *sigmask);
+
+/* Variant of file_name_lookup used in *at function implementations.
+   AT_FLAGS may only contain AT_SYMLINK_FOLLOW or AT_SYMLINK_NOFOLLOW,
+   which will remove and add O_NOLINK from FLAGS respectively.
+   Other bits cause EINVAL.  */
+extern file_t __file_name_lookup_at (int fd, int at_flags,
+				     const char *file_name,
+				     int flags, mode_t mode);
+
+/* Variant of file_name_split used in *at function implementations.  */
+extern file_t __file_name_split_at (int fd, const char *file_name,
+				    char **name);
+
+/* Variant of directory_name_split used in *at function implementations.  */
+extern file_t __directory_name_split_at (int fd, const char *directory_name,
+					 char **name);
+
+
+
+#endif	/* hurd/fd.h */