Exemple #1
0
/* Write up to N chars from BUF to COOKIE.
   Return how many chars were written or -1 for error.  */
static ssize_t
writeio (void *cookie, const char *buf, size_t n)
{
  mach_msg_type_number_t wrote;
  error_t err;

  if (err = __io_write ((io_t) cookie, buf, n, -1, &wrote))
    return __hurd_fail (err);

  return wrote;
}
/* Return the number of available physical pages */
long int
__get_avphys_pages ()
{
  vm_statistics_data_t vs;
  kern_return_t err;

  err = __vm_statistics (__mach_task_self (), &vs);
  if (err)
    return __hurd_fail (err);

  return vs.free_count;
}
ssize_t
setxattr (const char *path, const char *name, const void *value, size_t size,
	  int flags)
{
  error_t err;
  file_t port = __file_name_lookup (path, 0, 0);
  if (port == MACH_PORT_NULL)
    return -1;
  err = _hurd_xattr_set (port, name, value, size, flags);
  __mach_port_deallocate (__mach_task_self (), port);
  return __hurd_fail (err);
}
/* Move COOKIE's file position *POS bytes, according to WHENCE.
   The current file position is stored in *POS.
   Returns zero if successful, nonzero if not.  */
static int
seekio (void *cookie,
#ifdef USE_IN_LIBIO
	_IO_off64_t *pos,
#else
	fpos_t *pos,
#endif
	int whence)
{
  error_t err = __io_seek ((file_t) cookie, *pos, whence, pos);
  return err ? __hurd_fail (err) : 0;
}
Exemple #5
0
int
fchmodat (int fd, const char *file, mode_t mode, int flag)
{
  error_t err;
  file_t port = __file_name_lookup_at (fd, flag, file, 0, 0);
  if (port == MACH_PORT_NULL)
    return -1;
  err = __file_chmod (port, mode);
  __mach_port_deallocate (__mach_task_self (), port);
  if (err)
    return __hurd_fail (err);
  return 0;
}
Exemple #6
0
/* Make PATH be the root directory (the starting point for absolute
   paths).  Note that while on traditional UNIX systems this call is
   restricted to the super-user, it isn't on the Hurd.  */
int
chroot (const char *path)
{
  const char *lookup;
  size_t len;
  file_t dir, root;
  error_t err;

  /* Append trailing "/." to directory name to force ENOTDIR if it's not a
     directory and EACCES if we don't have search permission.  */
  len = strlen (path);
  if (len >= 2 && path[len - 2] == '/' && path[len - 1] == '.')
    lookup = path;
  else if (len == 0)
    /* Special-case empty file name according to POSIX.  */
    return __hurd_fail (ENOENT);
  else
    {
      char *n = alloca (len + 3);
      memcpy (n, path, len);
      n[len] = '/';
      n[len + 1] = '.';
      n[len + 2] = '\0';
      lookup = n;
    }

  dir = __file_name_lookup (lookup, 0, 0);
  if (dir == MACH_PORT_NULL)
    return -1;

  /* Prevent going through DIR's ..  */
  err = __file_reparent (dir, MACH_PORT_NULL, &root);
  __mach_port_deallocate (__mach_task_self (), dir);
  if (err)
    return __hurd_fail (err);

  _hurd_port_set (&_hurd_ports[INIT_PORT_CRDIR], root);
  return 0;
}
Exemple #7
0
/* Change the owner and group of FILE; if it's a link, do the link and
   not the target.  */
int
__lchown (const char *file, uid_t owner, gid_t group)
{
  error_t err;
  file_t port = __file_name_lookup (file, O_NOLINK, 0);
  if (port == MACH_PORT_NULL)
    return -1;
  err = __file_chown (port, owner, group);
  __mach_port_deallocate (__mach_task_self (), port);
  if (err)
    return __hurd_fail (err);
  return 0;
}
Exemple #8
0
/* Change the protections of FILE to MODE.  */
int
lchmod (const char *file, mode_t mode)
{
  error_t err;
  file_t port = __file_name_lookup (file, O_NOLINK, 0);
  if (port == MACH_PORT_NULL)
    return -1;
  err = __file_chmod (port, mode);
  __mach_port_deallocate (__mach_task_self (), port);
  if (err)
    return __hurd_fail (err);
  return 0;
}
Exemple #9
0
int
getloadavg (double loadavg[], int nelem)
{
  host_load_info_data_t info;
  mach_msg_type_number_t size = HOST_LOAD_INFO_COUNT;
  error_t err;
  int i;

  err = __host_info (__mach_host_self (), HOST_LOAD_INFO,
		     (host_info_t) &info, &size);
  if (err)
    return __hurd_fail (err);
  if (size < HOST_LOAD_INFO_COUNT)
    return __hurd_fail (EGRATUITOUS);

  if (nelem > 3)
    nelem = 3;
  for (i = 0; i < nelem; ++i)
    loadavg[i] = (double) info.avenrun[i] / (double) LOAD_SCALE;

  return i;
}
Exemple #10
0
/* XXX shouldn't this be __chflags? */
int
chflags (const char *file, int flags)
{
  error_t err;
  file_t port = __file_name_lookup (file, 0, 0);
  if (port == MACH_PORT_NULL)
    return -1;
  err = __file_chflags (port, flags);
  __mach_port_deallocate (__mach_task_self (), port);
  if (err)
    return __hurd_fail (err);
  return 0;
}
Exemple #11
0
/* Get information about the file descriptor FD in BUF.  */
int
__fxstat64 (int vers, int fd, struct stat64 *buf)
{
  error_t err;

  if (vers != _STAT_VER)
    return __hurd_fail (EINVAL);

  if (err = HURD_DPORT_USE (fd, __io_stat (port, buf)))
    return __hurd_dfail (fd, err);

  return 0;
}
Exemple #12
0
file_t
__file_name_lookup_at (int fd, int at_flags,
		       const char *file_name, int flags, mode_t mode)
{
  error_t err;
  file_t result;
  int empty = at_flags & AT_EMPTY_PATH;

  at_flags &= ~AT_EMPTY_PATH;

  err = __hurd_at_flags (&at_flags, &flags);
  if (err)
    return (__hurd_fail (err), MACH_PORT_NULL);

  if (fd == AT_FDCWD || file_name[0] == '/')
    return __file_name_lookup (file_name, flags, mode);

  if (empty != 0 && file_name[0] == '\0')
    {
      enum retry_type doretry;
      char retryname[1024];	/* XXX string_t LOSES! */

      err = HURD_DPORT_USE (fd, __dir_lookup (port, "", flags, mode,
					      &doretry, retryname,
					      &result));

      if (! err)
	err = __hurd_file_name_lookup_retry (&_hurd_ports_use, &__getdport,
					     NULL, doretry, retryname,
					     flags, mode, &result);

      return err ? (__hurd_dfail (fd, err), MACH_PORT_NULL) : result;
    }

  file_t startdir;
  error_t use_init_port (int which, error_t (*operate) (mach_port_t))
    {
      return (which == INIT_PORT_CWDIR ? (*operate) (startdir) :
	      _hurd_ports_use (which, operate));
    }

  err = HURD_DPORT_USE (fd, (startdir = port,
			     __hurd_file_name_lookup (&use_init_port,
						      &__getdport, NULL,
						      file_name,
						      flags,
						      mode & ~_hurd_umask,
						      &result)));

  return err ? (__hurd_dfail (fd, err), MACH_PORT_NULL) : result;
}
Exemple #13
0
/* Store the CPU time used by this process and all its
   dead children (and their dead children) in BUFFER.
   Return the elapsed real time, or (clock_t) -1 for errors.
   All times are in CLK_TCKths of a second.  */
clock_t
__times (struct tms *tms)
{
    struct task_basic_info bi;
    struct task_thread_times_info tti;
    mach_msg_type_number_t count;
    union {
        time_value_t tvt;
        struct timeval tv;
    } now;
    error_t err;

    count = TASK_BASIC_INFO_COUNT;
    err = __task_info (__mach_task_self (), TASK_BASIC_INFO,
                       (task_info_t) &bi, &count);
    if (err)
        return __hurd_fail (err);

    count = TASK_THREAD_TIMES_INFO_COUNT;
    err = __task_info (__mach_task_self (), TASK_THREAD_TIMES_INFO,
                       (task_info_t) &tti, &count);
    if (err)
        return __hurd_fail (err);

    tms->tms_utime = (clock_from_time_value (&bi.user_time)
                      + clock_from_time_value (&tti.user_time));
    tms->tms_stime = (clock_from_time_value (&bi.system_time)
                      + clock_from_time_value (&tti.system_time));

    /* XXX This can't be implemented until getrusage(RUSAGE_CHILDREN) can be.  */
    tms->tms_cutime = tms->tms_cstime = 0;

    if (__gettimeofday (&now.tv, NULL) < 0)
        return -1;

    return (clock_from_time_value (&now.tvt)
            - clock_from_time_value (&bi.creation_time));
}
Exemple #14
0
file_t
__file_name_lookup_at (int fd, int at_flags,
		       const char *file_name, int flags, mode_t mode)
{
  error_t err;
  file_t result;

  if ((at_flags & AT_SYMLINK_FOLLOW) && (at_flags & AT_SYMLINK_NOFOLLOW))
    return (__hurd_fail (EINVAL), MACH_PORT_NULL);

  flags |= (at_flags & AT_SYMLINK_NOFOLLOW) ? O_NOLINK : 0;
  at_flags &= ~AT_SYMLINK_NOFOLLOW;
  if (at_flags & AT_SYMLINK_FOLLOW)
    flags &= ~O_NOLINK;
  at_flags &= ~AT_SYMLINK_FOLLOW;
  if (at_flags != 0)
    return (__hurd_fail (EINVAL), MACH_PORT_NULL);

  if (fd == AT_FDCWD || file_name[0] == '/')
    return __file_name_lookup (file_name, flags, mode);

  file_t startdir;
  error_t use_init_port (int which, error_t (*operate) (mach_port_t))
    {
      return (which == INIT_PORT_CWDIR ? (*operate) (startdir) :
	      _hurd_ports_use (which, operate));
    }

  err = HURD_DPORT_USE (fd, (startdir = port,
			     __hurd_file_name_lookup (&use_init_port,
						      &__getdport, NULL,
						      file_name,
						      flags,
						      mode & ~_hurd_umask,
						      &result)));

  return err ? (__hurd_dfail (fd, err), MACH_PORT_NULL) : result;
}
Exemple #15
0
/* Remove the directory FILE_NAME.  */
int
__rmdir (const char *file_name)
{
  error_t err;
  const char *name;
  file_t parent = __directory_name_split (file_name, (char **) &name);
  if (parent == MACH_PORT_NULL)
    return -1;
  err = __dir_rmdir (parent, name);
  __mach_port_deallocate (__mach_task_self (), parent);
  if (err)
    return __hurd_fail (err);
  return 0;
}
Exemple #16
0
pid_t
getsid (pid_t pid)
{
  error_t err;
  pid_t sid;

  if (pid == 0)
    pid = _hurd_pid;

  err = __USEPORT (PROC, __proc_getsid (port, pid, &sid));
  if (err)
    return (pid_t) __hurd_fail (err);
  return sid;
}
Exemple #17
0
  /* Fetch a thread state structure from PID and store it at ADDR.  */
  int get_regs (int flavor, mach_msg_type_number_t count)
    {
      error_t err;
      task_t task = __pid2task (pid);
      thread_t thread;
      if (task == MACH_PORT_NULL)
	return -1;
      err = fetch_user_thread (task, &thread);
      __mach_port_deallocate (__mach_task_self (), task);
      if (!err)
	err = __thread_get_state (thread, flavor, addr, &count);
      __mach_port_deallocate (__mach_task_self (), thread);
      return err ? __hurd_fail (err) : 0;
    }
Exemple #18
0
/* Get file-specific information about FILE.  */
long int
__pathconf (const char *file, int name)
{
  error_t err;
  int value;			/* RPC returns an `int', not a `long int'.  */
  file_t port = __file_name_lookup (file, 0, 0);
  if (port == MACH_PORT_NULL)
    return -1L;
  err = __io_pathconf (port, name, &value);
  __mach_port_deallocate (__mach_task_self (), port);
  if (err)
    return __hurd_fail (err), -1L;
  return value;
}
Exemple #19
0
/* Return information about the filesystem on which FILE resides.  */
int
__statfs64 (const char *file, struct statfs64 *buf)
{
  error_t err;
  file_t port;

  port = __file_name_lookup (file, 0, 0);
  if (port == MACH_PORT_NULL)
    return -1;
  err = __file_statfs (port, buf);
  __mach_port_deallocate (__mach_task_self (), port);
  if (err)
    return __hurd_fail (err);
  return 0;
}
Exemple #20
0
/* Adjust the current time of day by the amount in DELTA.
   If OLDDELTA is not NULL, it is filled in with the amount
   of time adjustment remaining to be done from the last `__adjtime' call.
   This call is restricted to the super-user.  */
int
__adjtime (const struct timeval *delta, struct timeval *olddelta)
{
  error_t err;
  mach_port_t hostpriv;

  hostpriv = __pid2task (-1);
  if (hostpriv == MACH_PORT_NULL)
    return -1;
  err = __host_adjust_time (hostpriv, delta, olddelta);
  __mach_port_deallocate (__mach_task_self (), hostpriv);
  if (err)
    return __hurd_fail (err);
  return 0;
}
Exemple #21
0
int
revoke (const char *file_name)
{
  error_t err;
  file_t file = __file_name_lookup (file_name, 0, 0);

  if (file == MACH_PORT_NULL)
    return -1;

  err = __io_revoke (file);
  __mach_port_deallocate (__mach_task_self (), file);

  if (err)
    return __hurd_fail (err);
  return 0;
}
Exemple #22
0
/* Truncate FILE_NAME to LENGTH bytes.  */
int
__truncate64 (const char *file_name, off64_t length)
{
  error_t err;
  file_t file = __file_name_lookup (file_name, O_WRITE, 0);

  if (file == MACH_PORT_NULL)
    return -1;

  err = __file_set_size (file, length);
  __mach_port_deallocate (__mach_task_self (), file);

  if (err)
    return __hurd_fail (err);
  return 0;
}
Exemple #23
0
/* Change the access time of FILE to TVP[0] and
   the modification time of FILE to TVP[1].  */
int
__lutimes (const char *file, const struct timeval tvp[2])
{
  error_t err;
  file_t port;

  port = __file_name_lookup (file, O_NOLINK, 0);
  if (port == MACH_PORT_NULL)
    return -1;

  err = hurd_futimes (port, tvp);

  __mach_port_deallocate (__mach_task_self (), port);
  if (err)
    return __hurd_fail (err);
  return 0;
}
Exemple #24
0
/* Replace the current process, executing FILE_NAME with arguments ARGV and
   environment ENVP.  ARGV and ENVP are terminated by NULL pointers.  */
int
__execve (const char *file_name, char *const argv[], char *const envp[])
{
  error_t err;
  file_t file = __file_name_lookup (file_name, O_EXEC, 0);

  if (file == MACH_PORT_NULL)
    return -1;

  /* Hopefully this will not return.  */
  err = _hurd_exec (__mach_task_self (), file, argv, envp);

  /* Oh well.  Might as well be tidy.  */
  __mach_port_deallocate (__mach_task_self (), file);

  return __hurd_fail (err);
}
Exemple #25
0
/* Remove the link named NAME.  */
int
__unlink (const char *name)
{
  error_t err;
  file_t dir;
  const char *file;

  dir = __directory_name_split (name, (char **) &file);
  if (dir == MACH_PORT_NULL)
    return -1;

  err = __dir_unlink (dir, file);
  __mach_port_deallocate (__mach_task_self (), dir);

  if (err)
    return __hurd_fail (err);
  return 0;
}
/* Create a new session with the calling process as its leader.
   The process group IDs of the session and the calling process
   are set to the process ID of the calling process, which is returned.  */
pid_t
__setsid (void)
{
  error_t err;
  unsigned int stamp;

  HURD_CRITICAL_BEGIN;
  __mutex_lock (&_hurd_dtable_lock);

  stamp = _hurd_pids_changed_stamp; /* Atomic fetch.  */

  /* Tell the proc server we want to start a new session.  */
  err = __USEPORT (PROC, __proc_setsid (port));
  if (err)
    __mutex_unlock (&_hurd_dtable_lock);
  else
    {
      /* Punt our current ctty, and update the dtable accordingly.  We hold
	 the dtable lock from before the proc_setsid call through clearing
	 the cttyid port and processing the dtable, so that we can be sure
	 that it's all done by the time the signal thread processes the
	 pgrp change notification.  */
      _hurd_locked_install_cttyid (MACH_PORT_NULL);

      /* Synchronize with the signal thread to make sure we have received
	 and processed proc_newids before returning to the user.
	 This is necessary to ensure that _hurd_pgrp (and thus the value
	 returned by `getpgrp ()' in other threads) has been updated before
	 we return.  */
      while (_hurd_pids_changed_stamp == stamp)
	{
#ifdef noteven
	  /* XXX we have no need for a mutex, but cthreads demands one.  */
	  __condition_wait (&_hurd_pids_changed_sync, NULL);
#else
	  __swtch_pri (0);
#endif
	}
    }

  HURD_CRITICAL_END;

  return err ? __hurd_fail (err) : _hurd_pgrp;
}
Exemple #27
0
/* Make a link to FROM called TO.  */
int
__symlink (const char *from, const char *to)
{
  error_t err;
  file_t dir, node;
  char *name;
  const size_t len = strlen (from) + 1;
  char buf[sizeof (_HURD_SYMLINK) + len];

  /* A symlink is a file whose translator is "/hurd/symlink\0target\0".  */

  memcpy (buf, _HURD_SYMLINK, sizeof (_HURD_SYMLINK));
  memcpy (&buf[sizeof (_HURD_SYMLINK)], from, len);

  dir = __file_name_split (to, &name);
  if (dir == MACH_PORT_NULL)
    return -1;

  /* Create a new, unlinked node in the target directory.  */
  err = __dir_mkfile (dir, O_WRITE, 0777 & ~_hurd_umask, &node);

  if (! err)
    {
      /* Set the node's translator to make it a symlink.  */
      err = __file_set_translator (node,
                                   FS_TRANS_EXCL|FS_TRANS_SET,
                                   FS_TRANS_EXCL|FS_TRANS_SET, 0,
                                   buf, sizeof (_HURD_SYMLINK) + len,
                                   MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND);

      if (! err)
        /* Link the node, now a valid symlink, into the target directory.  */
        err = __dir_link (dir, node, name, 1);

      __mach_port_deallocate (__mach_task_self (), node);
    }

  __mach_port_deallocate (__mach_task_self (), dir);

  if (err)
    return __hurd_fail (err);
  return 0;
}
Exemple #28
0
int
mlock (const void *addr, size_t len)
{
  mach_port_t host;
  vm_address_t page;
  error_t err;

  err = __get_privileged_ports (&host, NULL);
  if (err)
    host = __mach_host_self();

  page = trunc_page ((vm_address_t) addr);
  len = round_page ((vm_address_t) addr + len) - page;

  err = __vm_wire (host, __mach_task_self (), page, len, VM_PROT_READ);
  if (host != __mach_host_self())
    __mach_port_deallocate (__mach_task_self (), host);

  return err ? __hurd_fail (err) : 0;
}
Exemple #29
0
/* Read up to N chars into BUF from COOKIE.
   Return how many chars were read, 0 for EOF or -1 for error.  */
static ssize_t
readio (void *cookie, char *buf, size_t n)
{
  mach_msg_type_number_t nread;
  error_t err;
  char *bufp = buf;

  nread = n;
  if (err = __io_read ((io_t) cookie, &bufp, &nread, -1, n))
    return __hurd_fail (err);

  if (bufp != buf)
    {
      memcpy (buf, bufp, nread);
      __vm_deallocate (__mach_task_self (),
		       (vm_address_t) bufp, (vm_size_t) nread);
    }

  return nread;
}
Exemple #30
0
int
geteuids (int n, uid_t *uidset)
{
  error_t err;
  int nuids;
  void *crit;

  crit = _hurd_critical_section_lock ();
  __mutex_lock (&_hurd_id.lock);

  if (err = _hurd_check_ids ())
    {
      __mutex_unlock (&_hurd_id.lock);
      _hurd_critical_section_unlock (crit);
      return __hurd_fail (err);
    }

  nuids = _hurd_id.gen.nuids;

  if (n != 0)
    {
      /* Copy the uids onto stack storage and then release the idlock.  */
      uid_t uids[nuids];
      memcpy (uids, _hurd_id.gen.uids, sizeof (uids));
      __mutex_unlock (&_hurd_id.lock);
      _hurd_critical_section_unlock (crit);

      /* Now that the lock is released, we can safely copy the
	 uid set into the user's array, which might fault.  */
      if (nuids > n)
	nuids = n;
      memcpy (uidset, uids, nuids * sizeof (uid_t));
    }
  else
    {
      __mutex_unlock (&_hurd_id.lock);
      _hurd_critical_section_unlock (crit);
    }

  return nuids;
}