Formerly ../hurd/alloc-fd.c.~6~
[kopensolaris-gnu/glibc.git] / hurd / hurd.h
index 920673d..4401eb6 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1994 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
@@ -19,390 +19,221 @@ Cambridge, MA 02139, USA.  */
 #ifndef        _HURD_H
 
 #define        _HURD_H 1
-
-#define        _GNU_SOURCE
 #include <features.h>
 
+
+/* Get types, macros, constants and function declarations
+   for all Mach microkernel interaction.  */
 #include <mach.h>
+#include <mach/mig_errors.h>
+
+/* Get types and constants necessary for Hurd interfaces.  */
 #include <hurd/hurd_types.h>
+
+/* Get MiG stub declarations for commonly used Hurd interfaces.  */
+#include <hurd/auth.h>
 #include <hurd/process.h>
 #include <hurd/fs.h>
 #include <hurd/io.h>
-#include <errno.h>
+#include <hurd/msg.h>
+
+#define __spin_lock(lockaddr) /* no-op XXX */
+#define __spin_unlock(lockaddr) /* no-op XXX */
+
+#define __mutex_lock(lockaddr) /* no-op XXX */
+#define __mutex_unlock(lockaddr) /* no-op XXX */
+
+/* Get `struct hurd_port' and related definitions implementing lightweight
+   user references for ports.  These are used pervasively throughout the C
+   library; this is here to avoid putting it in nearly every source file.  */
+#include <hurd/port.h>
 
+#include <errno.h>
 #define        __hurd_fail(err)        (errno = (err), -1)
 \f
-/* Lightweight user references for ports.  */
-
-/* Structure describing a cell containing a port.
-   With the lock held, a user extracts PORT, and sets USER_DEALLOC to point
-   to a word in his local storage.  PORT can then safely be used.  When
-   PORT is no longer needed, with the lock held, the user examines
-   USER_DEALLOC.  If it is the same address that user stored there, it
-   extracts *USER_DEALLOC, clears USER_DEALLOC to NULL, and releases the
-   lock.  If *USER_DEALLOC is set, the user deallocates the port he used.  */
-struct _hurd_port
-  {
-    spin_lock_t lock;          /* Locks rest.  */
-    mach_port_t port;          /* Port. */
-    int *user_dealloc;         /* If not NULL, points to user's flag word.  */
-  };
-
-/* Evaluate EXPR with the variable `port' bound to the port in PORTCELL.  */
-#define        _HURD_PORT_USE(portcell, expr)                                        \
-  ({ struct _hurd_port *const __p = &(portcell);                             \
-     int __dealloc;                                                          \
-     const mach_port_t port = _hurd_port_get (__p, &__dealloc);                      \
-     __typeof(expr) __result = (expr);                                       \
-     _hurd_port_free (__p, &__dealloc);                                              \
-     __result; })
-
-/* Initialize *PORT to INIT.  */
-static inline void
-_hurd_port_init (struct _hurd_port *port, mach_port_t init)
-{
-  __spin_lock_init (&port->lock);
-  port->port = init;
-  port->user_dealloc = NULL;
-}
-
-/* Get a reference to *PORT, which is locked.
-   Pass return value and MYFLAG to _hurd_port_free when done.  */
-static inline mach_port_t
-_hurd_port_locked_get (struct _hurd_port *port, int *myflag)
-{
-  mach_port_t result;
-  result = port->port;
-  if (result != MACH_PORT_NULL)
-    {
-      port->user_dealloc = myflag;
-      *myflag = 0;
-    }
-  __spin_unlock (&port->lock);
-  return result;
-}
-
-/* Same, but locks PORT first.  */
-static inline mach_port_t
-_hurd_port_get (struct _hurd_port *port, int *myflag)
-{
-  __spin_lock (&port->lock);
-  return _hurd_port_locked_get (port, myflag);
-}
-
-/* Free a reference gotten with
-   `USED_PORT = _hurd_port_get (PORT, MYFLAG);' */
-static inline void
-_hurd_port_free (struct _hurd_port *port,
-                int *myflag, mach_port_t used_port)
-{
-  __spin_lock (&port->lock);
-  if (port->user_dealloc == myflag)
-    port->user_dealloc = NULL;
-  __spin_unlock (&port->lock);
-  if (*myflag)
-    __mach_port_deallocate (__mach_task_self (), used_port);
-}
-
-/* Set *PORT's port to NEWPORT.  PORT is locked.  */
-static inline void
-_hurd_port_locked_set (struct _hurd_port *port, mach_port_t newport)
-{
-  mach_port_t old;
-  __spin_lock (&port->lock);
-  if (port->user_dealloc == NULL)
-    old = port->port;
-  else
-    {
-      old = MACH_PORT_NULL;
-      *port->user_dealloc = 1;
-    }
-  port->port = newport;
-  __spin_unlock (&port->lock);
-  if (old != MACH_PORT_NULL)
-    __mach_port_deallocate (__mach_task_self (), old);
-}
-
-/* Same, but locks PORT first.  */
-static inline void
-_hurd_port_set (struct _hurd_port *port, mach_port_t newport)
-{
-  __spin_lock (&port->lock);
-  return _hurd_port_locked_set (port, newport);
-}
-\f
 /* Basic ports and info, initialized by startup.  */
-extern struct _hurd_port _hurd_proc, _hurd_auth;
-extern struct _hurd_port _hurd_ccdir, _hurd_cwdir, _hurd_crdir;
-extern mode_t _hurd_umask;
 
-extern struct mutex _hurd_ctty_lock;
-extern int _hurd_ctty_fstype;
-extern fsid_t _hurd_ctty_fsid;
-extern ino_t _hurd_ctty_fileid;
+extern struct hurd_port *_hurd_ports;
+extern unsigned int _hurd_nports;
+extern volatile mode_t _hurd_umask;
+
+/* Shorthand macro for referencing _hurd_ports (see <hurd/port.h>).  */
+
+#define        __USEPORT(which, expr) \
+  HURD_PORT_USE (&_hurd_ports[INIT_PORT_##which], (expr))
 
-extern vm_address_t _hurd_stack_low, _hurd_stack_high; /* Not locked.  */
 
-extern thread_t _hurd_sigport_thread;
-extern mach_port_t _hurd_sigport; /* Locked by _hurd_siglock.  */
+/* Base address and size of the initial stack set up by the exec server.
+   If using cthreads, this stack is deallocated in startup.
+   Not locked.  */
+
+extern vm_address_t _hurd_stack_base;
+extern vm_size_t _hurd_stack_size;
+
+/* Initial file descriptor table we were passed at startup.  If we are
+   using a real dtable, these are turned into that and then cleared at
+   startup.  If not, these are never changed after startup.  Not locked.  */
 
-/* Not locked.  If we are using a real dtable,
-   these are turned into that and then cleared at startup.
-   If not, these are never changed after startup.  */
 extern mach_port_t *_hurd_init_dtable;
-extern size_t _hurd_init_dtablesize;
+extern mach_msg_type_number_t _hurd_init_dtablesize;
 \f
-/* File descriptor table.  */
-struct _hurd_dtable
-  {
-    int size;                  /* Number of elts in `d' array.  */
-    /* Individual descriptors are not locked.  It is up to the user to
-       synchronize descriptor operations on a single descriptor.  */
-    struct
-      {
-       struct _hurd_port port;
-       /* Locked by port.lock.  */
-       int isctty;             /* Is a port to the controlling tty.  */
-       int flags;              /* fcntl flags.  */
-      } *d;
-  };
-extern struct _hurd_dtable _hurd_dtable;
-extern struct mutex _hurd_dtable_lock; /* Locks _hurd_dtable.  */
-
-/* Allocate a new file descriptor and set it to PORT.  */
-static inline int
-_hurd_dalloc (io_t port, int flags)
-{
-  int i;
-  __mutex_lock (&hurd_dtable_lock);
-  for (i = 0; i < _hurd_dtable.size; ++i)
-    {
-      __typeof (&_hurd_dtable.d[i]) d = &_hurd_dtable.d[i];
-      __spin_lock (&d->port.lock);
-      if (d->port.port == MACH_PORT_NULL)
-       {
-         d->isctty = -1;
-         d->flags = flags;
-         d->port.port = port;
-         d->port.user_dealloc = NULL;
-         __spin_unlock (&d->port.lock);
-         __mutex_unlock (&hurd_dtable_lock);
-         return i;
-       }
-      __spin_unlock (&d->port.lock);
-    }
-  __mutex_unlock (&hurd_dtable_lock);
-  __mach_port_deallocate (__mach_task_self (), port);
-  errno = EMFILE;
-  return -1;
-}
-
-/* Returns the port cell for FD, locked.  */
-static inline struct _hurd_port *
-_hurd_dport (int fd)
-{
-  struct _hurd_port *port;
-  __mutex_lock (&_hurd_dtable.lock);
-  if (fd < 0 || fd >= _hurd_dtable.size ||
-      _hurd_dtable.d[fd].server == MACH_PORT_NULL)
-    {
-      errno = EBADF;
-      port = NULL;
-    }
-  else
-    {
-      port = &_hurd_dtable.d[fd].port;
-      __spin_lock (&port->lock);
-    }
-  __mutex_unlock (&_hurd_dtable.lock);
-  return port;
-}
-
-/* Evaluate EXPR with the variable `port' bound to the port to FD.  */
-#define        _HURD_DPORT_USE(fd, expr)                                             \
-  ({ struct _hurd_port *__port = _hurd_dport (fd);                           \
-     if (__port == NULL)                                                     \
-       {                                                                     \
-        errno = EBADF;                                                       \
-        -1;                                                                  \
-       }                                                                     \
-     else                                                                    \
-       {                                                                     \
-        int __dealloc = 0;                                                   \
-        io_t port = _hurd_port_locked_get (__port, &__dealloc);              \
-        __typeof (expr) __result;                                            \
-        __result = (expr);                                                   \
-        _hurd_port_free (port, &__dealloc);                                  \
-        __result;                                                            \
-       }                                                                     \
-   })                                                                        \
-\f
-/* Return the socket server for sockaddr domain DOMAIN.  */
-extern socket_t _hurd_socket_server (int domain);
-
-/* Return a receive right which will not be sent to.  */
-extern mach_port_t _hurd_dead_recv (void);
+/* Miscellaneous library state.  */
 
 
 /* Current process IDs.  */
+
 extern pid_t _hurd_pid, _hurd_ppid, _hurd_pgrp;
 extern int _hurd_orphaned;
+#ifdef noteven
+extern struct mutex _hurd_pid_lock; /* Locks above.  */
+#endif
+\f
+/* Unix `data break', for brk and sbrk.
+   If brk and sbrk are not used, this info will not be initialized or used.  */
 
 
-/* User and group IDs.  */
-extern mutex_t _hurd_idlock;
-extern int _hurd_id_valid;     /* Nonzero if _hurd_id is valid.  */
-extern idblock_t _hurd_id;
-extern auth_t _hurd_rid_auth;  /* Cache used by access.  */
+/* Data break.  This is what `sbrk (0)' returns.  */
 
+extern vm_address_t _hurd_brk;
+
+/* End of allocated space.  This is generally `round_page (_hurd_brk)'.  */
+
+extern vm_address_t _hurd_data_end;
+
+/* This mutex locks _hurd_brk and _hurd_data_end.  */
+
+#ifdef noteven
+extern struct mutex _hurd_brk_lock;
+#endif
+
+/* Set the data resource limit (RLIM_DATA).  */
 
-/* Unix `data break', for brk and sbrk.
-   If brk and sbrk are not used, this info will not be initialized or used.  */
-extern vm_address_t _hurd_brk; /* Data break.  */
-extern vm_address_t _hurd_data_end; /* End of allocated space.  */
-extern struct mutex _hurd_brk_lock; /* Locks brk and data_end.  */
 extern int _hurd_set_data_limit (const struct rlimit *);
 
-/* Set the data break; the brk lock must
+/* Set the data break to NEWBRK; _hurd_brk_lock must
    be held, and is released on return.  */
-extern int _hurd_set_brk (vm_address_t newbrk);
 
-/* Resource limit on core file size.  Enforced by hurdsig.c.  */
-extern int _hurd_core_limit;
-\f
-#include <signal.h>
-
-/* Per-thread signal state.  */
-struct _hurd_sigstate
-  {
-    thread_t thread;
-    struct _hurd_sigstate *next; /* Linked-list of thread sigstates.  */
-
-    struct mutex lock;         /* Locks the rest of this structure.  */
-    sigset_t blocked;
-    sigset_t pending;
-    struct sigaction actions[NSIG];
-    struct sigstack sigstack;
-    int sigcodes[NSIG];                /* Codes for pending signals.  */
-
-    int suspended;             /* If nonzero, sig_post signals `arrived'.  */
-    struct condition arrived;
-    mach_port_t suspend_reply; /* Reply port for sig_post RPC.  */
-
-    int vforked;               /* Nonzero if this thread is a vfork child.  */
-    struct
-      {
-       process_t proc;
-       file_t ccdir, cwdir, crdir, auth;
-       mode_t umask;
-       int ctty_fstype;
-       fsid_t ctty_fsid;
-       ino_t ctty_fileid;
-       struct _hurd_dtable *dtable;
-       jmp_buf continuation;
-      } *vfork_saved;
-
-    /* Not locked.  Used only by this thread,
-       or by signal thread with this thread suspended.  */
-    mach_port_t intr_port;     /* Port an interruptible RPC was sent on.  */
-    int intr_restart;          /* If nonzero, restart interrupted RPC.  */
-  };
-/* Linked list of states of all threads
-   whose state has been inquired about.  */
-extern struct _hurd_sigstate *_hurd_sigstates;
-extern struct mutex _hurd_siglock; /* Locks _hurd_sigstates.  */
-/* Get the sigstate of a given thread, taking its lock.  */
-extern struct _hurd_sigstate *_hurd_thread_sigstate (thread_t);
-
-/* Thread to receive process-global signals.  */
-extern thread_t _hurd_sigthread;
-
-/* Called by the machine-dependent exception handler.  */
-extern void _hurd_exc_post_signal (thread_t, int sig, int code);
-
-/* SS->lock is held on entry, and released before return.  */
-extern void _hurd_internal_post_signal (reply_port_t,
-                                       struct _hurd_sigstate *ss,
-                                       int signo, int sigcode,
-                                       sigset_t *restore_blocked);
-
-/* Function run by the signal thread to receive from the signal port.  */
-extern void _hurd_sigport_receive (void);
-
-/* Set the signal-receiving thread.  */
-extern int sigsetthread (thread_t);
-
-
-/* Perform interruptible RPC CALL on PORT.
-   The args in CALL should be constant or local variable refs.
-   They may be evaluated many times, and must not change.
-   PORT must not be deallocated before this RPC is finished.  */
-#define        _HURD_EINTR_RPC(port, call) \
-  ({
-    error_t __err;
-    struct _hurd_sigstate *__ss
-      = _hurd_thread_sigstate (__mach_thread_self ());
-    __mutex_unlock (&__ss->lock); /* Lock not needed.  */
-    __ss->intr_restart = 1;
-    /* This one needs to be last.  A signal can arrive before here,
-       and if intr_port were set before intr_restart are
-       initialized, the signal thread would get confused.  */
-    __ss->intr_port = (port);
-    /* A signal may arrive here, after intr_port is set,
-       but before the mach_msg system call.  The signal handler might do an
-       interruptible RPC, and clobber intr_port; then it would not be set
-       properly when we actually did send the RPC, and a later signal
-       wouldn't interrupt that RPC.  So, _hurd_run_sighandler saves
-       intr_port in the sigcontext, and sigreturn restores them.  */
-  __do_call:
-    switch (__err = (call))
-      {
-      case EINTR:              /* RPC went out and was interrupted.  */
-      case MACH_SEND_INTERRUPTED: /* RPC didn't get out.  */
-      case MACH_RCV_INTERRUPTED: /* RPC pending.  */
-       if (__ss->intr_restart)
-         /* Restart the interrupted call.  */
-         goto __do_call;
-       /* Return EINTR.  */
-       __err = EINTR;
-       break;
-      }
-    __ss->intr_port = MACH_PORT_NULL;
-    __err;
-  })
+extern int _hurd_set_brk (vm_address_t newbrk);
 \f
 /* Calls to get and set basic ports.  */
+
 extern process_t getproc (void);
 extern file_t getccdir (void), getcwdir (void), getcrdir (void);
 extern auth_t getauth (void);
 extern int setproc (process_t);
-extern int setccdir (file_t), setcwdir (file_t), setcrdir (file_t);
+extern int setcwdir (file_t), setcrdir (file_t);
 
 /* Does reauth with the proc server and fd io servers.  */
 extern int __setauth (auth_t), setauth (auth_t);
-#define        setauth __setauth
 
 
+/* Split FILE into a directory and a name within the directory.  Look up a
+   port for the directory and store it in *DIR; store in *NAME a pointer
+   into FILE where the name within directory begins.  The directory lookup
+   uses CRDIR for the root directory and CWDIR for the current directory.
+   Returns zero on success or an error code.  */
+
 extern error_t __hurd_path_split (file_t crdir, file_t cwdir,
                                  const char *file,
-                                 file_t *dir, const char **name);
-#define        hurd_path_split __hurd_path_split
+                                 file_t *dir, char **name);
+extern error_t hurd_path_split (file_t crdir, file_t cwdir,
+                               const char *file,
+                               file_t *dir, char **name);
+
+/* Open a port to FILE with the given FLAGS and MODE (see <fcntl.h>).
+   The file lookup uses CRDIR for the root directory and CWDIR for the
+   current directory.  If successful, returns zero and store the port
+   to FILE in *PORT; otherwise returns an error code. */
+
 extern error_t __hurd_path_lookup (file_t crdir, file_t cwdir,
                                   const char *file,
                                   int flags, mode_t mode,
-                                  file_t *file);
-#define        hurd_path_lookup __hurd_path_lookup
+                                  file_t *port);
+extern error_t hurd_path_lookup (file_t crdir, file_t cwdir,
+                                const char *filename,
+                                int flags, mode_t mode,
+                                file_t *port);
+
+/* Split FILE into a directory and a name within the directory.  The
+   directory lookup uses the current root and working directory.  If
+   successful, stores in *NAME a pointer into FILE where the name
+   within directory begins and returns a port to the directory;
+   otherwise sets `errno' and returns MACH_PORT_NULL.  */
+
+extern file_t __path_split (const char *file, char **name);
+extern file_t path_split (const char *file, char **name);
+
+/* Open a port to FILE with the given FLAGS and MODE (see <fcntl.h>).
+   The file lookup uses the current root and working directory.
+   Returns a port to the file if successful; otherwise sets `errno'
+   and returns MACH_PORT_NULL.  */
 
-/* Returns a port to the directory, and sets *NAME to the file name.  */
-extern file_t __path_split (const char *file, const char **name);
-#define        path_split      __path_split
-
-/* Looks up FILE with the given FLAGS and MODE (as for dir_pathtrans).  */
 extern file_t __path_lookup (const char *file, int flags, mode_t mode);
-#define path_lookup __path_lookup
+extern file_t path_lookup (const char *file, int flags, mode_t mode);
+
 
 /* Open a file descriptor on a port.  */
-extern int openport (io_t port);
+
+extern int openport (io_t port, int flags);
+
+
+/* Execute a file, replacing TASK's current program image.  */
+
+extern error_t _hurd_exec (task_t task,
+                          file_t file,
+                          char *const argv[],
+                          char *const envp[]);
+
+
+/* Inform the proc server we have exitted with STATUS, and kill the
+   task thoroughly.  This function never returns, no matter what.  */
+
+extern void _hurd_exit (int status) __attribute__ ((noreturn));
+
+
+/* Initialize the library data structures from the
+   ints and ports passed to us by the exec server.
+   Then vm_deallocate PORTARRAY and INTARRAY.  */
+
+extern void _hurd_init (int flags, char **argv,
+                       mach_port_t *portarray, size_t portarraysize,
+                       int *intarray, size_t intarraysize);
+
+/* Do startup handshaking with the proc server.  */
+
+extern void _hurd_proc_init (char **argv);
+
+/* Return the socket server for sockaddr domain DOMAIN.  */
+
+extern socket_t _hurd_socket_server (int domain);
+
+/* Fetch the host privileged port and device master port from the proc
+   server.  They are fetched only once and then cached in the
+   variables below.  A special program that gets them from somewhere
+   other than the proc server (such as a bootstrap filesystem) can set
+   these variables to install the ports.  */
+
+extern kern_return_t get_privileged_ports (host_priv_t *host_priv_ptr,
+                                          device_t *device_master_ptr);
+extern mach_port_t _hurd_host_priv, _hurd_device_master;
+
+/* Return the PID of the task whose control port is TASK.
+   On error, sets `errno' and returns -1.  */
+
+extern pid_t __task2pid (task_t task), task2pid (task_t task);
+
+/* Return the task control port of process PID.
+   On error, sets `errno' and returns MACH_PORT_NULL.  */
+
+extern task_t __pid2task (pid_t pid), pid2task (pid_t pid);
+
+
+/* Return the io server port for file descriptor FD.
+   This adds a Mach user reference to the returned port.
+   On error, sets `errno' and returns MACH_PORT_NULL.  */
+
+extern io_t __getdport (int fd), getdport (int fd);
+
 
 
 #endif /* hurd.h */