/* Copyright (C) 1993-2014 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_H

#define	_HURD_H	1
#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>

/* 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>

#ifndef _HURD_H_EXTERN_INLINE
#define _HURD_H_EXTERN_INLINE __extern_inline
#endif

_HURD_H_EXTERN_INLINE int
__hurd_fail (error_t err)
{
  switch (err)
    {
    case EMACH_SEND_INVALID_DEST:
    case EMIG_SERVER_DIED:
      /* The server has disappeared!  */
      err = EIEIO;
      break;

    case KERN_NO_SPACE:
      err = ENOMEM;
      break;

    case KERN_INVALID_ARGUMENT:
      err = EINVAL;
      break;

    case 0:
      return 0;

    default:
      break;
    }

  errno = err;
  return -1;
}

/* Basic ports and info, initialized by startup.  */

extern int _hurd_exec_flags;	/* Flags word passed in exec_startup.  */
extern struct hurd_port *_hurd_ports;
extern unsigned int _hurd_nports;
extern mode_t _hurd_umask;
extern sigset_t _hurdsig_traced;

/* Shorthand macro for internal library code referencing _hurd_ports (see
   <hurd/port.h>).  */

#define	__USEPORT(which, expr) \
  HURD_PORT_USE (&_hurd_ports[INIT_PORT_##which], (expr))

/* Function version of __USEPORT: calls OPERATE with a send right.  */

extern error_t _hurd_ports_use (int which, error_t (*operate) (mach_port_t));


/* 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.  */

extern mach_port_t *_hurd_init_dtable;
extern mach_msg_type_number_t _hurd_init_dtablesize;

/* Current process IDs.  */

extern pid_t _hurd_pid, _hurd_ppid, _hurd_pgrp;
extern int _hurd_orphaned;

/* This variable is incremented every time the process IDs change.  */
extern unsigned int _hurd_pids_changed_stamp;

/* This condition is broadcast every time the process IDs change.  */
extern struct condition _hurd_pids_changed_sync;

/* Unix `data break', for brk and sbrk.
   If brk and sbrk are not used, this info will not be initialized or used.  */


/* 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.  */

extern struct mutex _hurd_brk_lock;

/* 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);

#define __need_FILE
#include <stdio.h>

/* Calls to get and set basic ports.  */

extern error_t _hurd_ports_get (unsigned int which, mach_port_t *result);
extern error_t _hurd_ports_set (unsigned int which, mach_port_t newport);

extern process_t getproc (void);
extern file_t getcwdir (void), getcrdir (void);
extern auth_t getauth (void);
extern mach_port_t getcttyid (void);
extern int setproc (process_t);
extern int setcwdir (file_t), setcrdir (file_t);
extern int setcttyid (mach_port_t);

/* Does reauth with the proc server and fd io servers.  */
extern int __setauth (auth_t), setauth (auth_t);


/* Modify a port cell by looking up a directory name.
   This verifies that it is a directory and that we have search permission.  */
extern int _hurd_change_directory_port_from_name (struct hurd_port *portcell,
						  const char *name);
/* Same thing, but using an open file descriptor.
   Also verifies that it is a directory and that we have search permission.  */
extern int _hurd_change_directory_port_from_fd (struct hurd_port *portcell,
						int fd);



/* Get and set the effective UID set.  */
extern int geteuids (int __n, uid_t *__uidset);
extern int seteuids (int __n, const uid_t *__uidset);


/* 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 __file_name_split (const char *file, char **name);
extern file_t file_name_split (const char *file, char **name);

/* Split DIRECTORY into a parent directory and a name within the directory.
   This is the same as file_name_split, but ignores trailing slashes.  */

extern file_t __directory_name_split (const char *file, char **name);
extern file_t directory_name_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.  */

extern file_t __file_name_lookup (const char *file, int flags, mode_t mode);
extern file_t file_name_lookup (const char *file, int flags, mode_t mode);

/* Open a port to FILE with the given FLAGS and MODE (see <fcntl.h>).  The
   file lookup uses the current root directory, but uses STARTDIR as the
   "working directory" for file relative names.  Returns a port to the file
   if successful; otherwise sets `errno' and returns MACH_PORT_NULL.  */

extern file_t __file_name_lookup_under (file_t startdir, const char *file,
					int flags, mode_t mode);
extern file_t file_name_lookup_under (file_t startdir, const char *file,
				      int flags, mode_t mode);


/* Lookup FILE_NAME and return the node opened with FLAGS & MODE
   (see hurd_file_name_lookup for details), but a simple file name (without
   any directory prefixes) will be consecutively prefixed with the pathnames
   in the `:' separated list PATH until one succeeds in a successful lookup.
   If none succeed, then the first error that wasn't ENOENT is returned, or
   ENOENT if no other errors were returned.  If PREFIXED_NAME is non-NULL,
   then if the result is looked up directly, *PREFIXED_NAME is set to NULL, and
   if it is looked up using a prefix from PATH, *PREFIXED_NAME is set to
   malloc'd storage containing the prefixed name.  */
extern file_t file_name_path_lookup (const char *file_name, const char *path,
				     int flags, mode_t mode,
				     char **prefixed_name);



/* Open a file descriptor on a port.  FLAGS are as for `open'; flags
   affected by io_set_openmodes are not changed by this.  If successful,
   this consumes a user reference for PORT (which will be deallocated on
   close).  */

extern int openport (io_t port, int flags);

/* Open a stream on a port.  MODE is as for `fopen'.
   If successful, this consumes a user reference for PORT
   (which will be deallocated on fclose).  */

extern FILE *fopenport (io_t port, const char *mode);
extern FILE *__fopenport (io_t port, const char *mode);


/* 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 exited 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, and initialize library data
   structures that require proc server interaction.  This includes
   initializing signals; see _hurdsig_init in <hurd/signal.h>.  */

extern void _hurd_proc_init (char **argv,
			     const int *intarray, size_t intarraysize);


/* Return the socket server for sockaddr domain DOMAIN.  If DEAD is
   nonzero, remove the old cached port and always do a fresh lookup.

   It is assumed that a socket server will stay alive during a complex socket
   operation involving several RPCs.  But a socket server may die during
   long idle periods between socket operations.  Callers should first pass
   zero for DEAD; if the first socket RPC tried on the returned port fails
   with MACH_SEND_INVALID_DEST or MIG_SERVER_DIED (indicating the server
   went away), the caller should call _hurd_socket_server again with DEAD
   nonzero and retry the RPC on the new socket server port.  */

extern socket_t _hurd_socket_server (int domain, int dead);

/* Send a `sig_post' RPC to process number PID.  If PID is zero,
   send the message to all processes in the current process's process group.
   If PID is < -1, send SIG to all processes in process group - PID.
   SIG and REFPORT are passed along in the request message.  */

extern error_t _hurd_sig_post (pid_t pid, int sig, mach_port_t refport);
extern error_t hurd_sig_post (pid_t pid, int sig, mach_port_t refport);

/* 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 (mach_port_t *host_priv_ptr,
					     device_t *device_master_ptr);
extern kern_return_t get_privileged_ports (mach_port_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 current thread's thread port.  This is a cheap operation (no
   system call), but it relies on Hurd signal state being set up.  */
extern thread_t hurd_thread_self (void);


/* Cancel pending operations on THREAD.  If it is doing an interruptible RPC,
   that RPC will now return EINTR; otherwise, the "cancelled" flag will be
   set, causing the next `hurd_check_cancel' call to return nonzero or the
   next interruptible RPC to return EINTR (whichever is called first).  */
extern error_t hurd_thread_cancel (thread_t thread);

/* Test and clear the calling thread's "cancelled" flag.  */
extern int hurd_check_cancel (void);


/* 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);


#include <stdarg.h>

/* Write formatted output to PORT, a Mach port supporting the i/o protocol,
   according to the format string FORMAT, using the argument list in ARG.  */
int vpprintf (io_t port, const char *format, va_list arg);


#endif	/* hurd.h */
