Exemple #1
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])
{
  union tv
  {
    struct timeval tv;
    time_value_t tvt;
  };
  const union tv *u = (const union tv *) tvp;
  union tv nulltv[2];
  error_t err;
  file_t port;

  if (tvp == NULL)
    {
      /* Setting the number of microseconds to `-1' tells the
         underlying filesystems to use the current time.  */
      nulltv[0].tvt.microseconds = nulltv[1].tvt.microseconds = -1;
      u = nulltv;
    }

  port = __file_name_lookup (file, O_NOLINK, 0);
  if (port == MACH_PORT_NULL)
    return -1;
  err = __file_utimes (port, u[0].tvt, u[1].tvt);
  __mach_port_deallocate (__mach_task_self (), port);
  if (err)
    return __hurd_fail (err);
  return 0;
}
Exemple #2
0
/* Read the contents of the symbolic link FILE_NAME into no more than
   LEN bytes of BUF.  The contents are not null-terminated.
   Returns the number of characters read, or -1 for errors.  */
ssize_t
__readlink (const char *file_name, char *buf, size_t len)
{
  error_t err;
  file_t file;
  struct stat64 st;

  file = __file_name_lookup (file_name, O_READ | O_NOLINK, 0);
  if (file == MACH_PORT_NULL)
    return -1;

  err = __io_stat (file, &st);
  if (! err)
    if (S_ISLNK (st.st_mode))
      {
	char *rbuf = buf;

	err = __io_read (file, &rbuf, &len, 0, len);
	if (!err && rbuf != buf)
	  {
	    memcpy (buf, rbuf, len);
	    __vm_deallocate (__mach_task_self (), (vm_address_t)rbuf, len);
	  }
      }
    else
      err = EINVAL;

  __mach_port_deallocate (__mach_task_self (), file);

  if (err)
    return __hurd_fail (err);
  else
    return len;
}
Exemple #3
0
/* This returns a new stream opened on a temporary file (generated
   by tmpnam).  The file is opened with mode "w+b" (binary read/write).
   If we couldn't generate a unique filename or the file couldn't
   be opened, NULL is returned.  */
FILE *
__tmpfile (void)
{
  error_t err;
  file_t file;
  int fd;
  FILE *f;

  /* Get a port to the directory that will contain the file.  */
  const char *dirname = __libc_secure_getenv ("TMPDIR") ?: P_tmpdir;
  file_t dir = __file_name_lookup (dirname, 0, 0);
  if (dir == MACH_PORT_NULL)
    return NULL;

  /* Create an unnamed file in the temporary directory.  */
  err = __dir_mkfile (dir, O_RDWR, S_IRUSR | S_IWUSR, &file);
  __mach_port_deallocate (__mach_task_self (), dir);
  if (err)
    return __hurd_fail (err), NULL;

  /* Get a file descriptor for that port.  POSIX.1 requires that streams
     returned by tmpfile allocate file descriptors as fopen would.  */
  fd = _hurd_intern_fd (file, O_RDWR, 1); /* dealloc on error */
  if (fd < 0)
    return NULL;

  /* Open a stream on the unnamed file.
     It will cease to exist when this stream is closed.  */
  if ((f = _IO_fdopen (fd, "w+b")) == NULL)
    __close (fd);

  return f;
}
Exemple #4
0
int
_hurd_change_directory_port_from_name (struct hurd_port *portcell,
				       const char *name)
{
  size_t len;
  const char *lookup;
  file_t dir;

  /* 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 (name);
  if (len >= 2 && name[len - 2] == '/' && name[len - 1] == '.')
    lookup = name;
  else if (len == 0)
    /* Special-case empty file name according to POSIX.  */
    return __hurd_fail (ENOENT);
  else
    {
      char *n = alloca (len + 3);
      memcpy (n, name, 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;

  _hurd_port_set (portcell, dir);
  return 0;
}
Exemple #5
0
ssize_t
listxattr (const char *path, char *list, size_t size)
{
  error_t err;
  file_t port = __file_name_lookup (path, 0, 0);
  if (port == MACH_PORT_NULL)
    return -1;
  err = _hurd_xattr_list (port, list, &size);
  __mach_port_deallocate (__mach_task_self (), port);
  return err ? __hurd_fail (err) : size;
}
Exemple #6
0
ssize_t
lgetxattr (const char *path, const char *name, void *value, size_t size)
{
    error_t err;
    file_t port = __file_name_lookup (path, O_NOLINK, 0);
    if (port == MACH_PORT_NULL)
        return -1;
    err = _hurd_xattr_get (port, name, value, &size);
    __mach_port_deallocate (__mach_task_self (), port);
    return err ? __hurd_fail (err) : size;
}
Exemple #7
0
ssize_t
lremovexattr (const char *path, const char *name)
{
  error_t err;
  file_t port = __file_name_lookup (path, O_NOLINK, 0);
  if (port == MACH_PORT_NULL)
    return -1;
  err = _hurd_xattr_remove (port, name);
  __mach_port_deallocate (__mach_task_self (), port);
  return __hurd_fail (err);
}
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);
}
Exemple #9
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 #10
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 #11
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 #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
/* 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 #14
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 #15
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 #16
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 #17
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 #18
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 #19
0
/* Get information about the file descriptor FD in BUF.  */
int
__lxstat64 (int vers, const char *file, struct stat64 *buf)
{
    error_t err;
    file_t port;

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

    port = __file_name_lookup (file, O_NOLINK, 0);
    if (port == MACH_PORT_NULL)
        return -1;
    err = __io_stat (port, buf);
    __mach_port_deallocate (__mach_task_self (), port);
    if (err)
        return __hurd_fail (err);
    return 0;
}
Exemple #20
0
/* Send N bytes of BUF on socket FD to peer at address ADDR (which is
   ADDR_LEN bytes long).  Returns the number sent, or -1 for errors.  */
ssize_t
__sendto (int fd,
	  const void *buf,
	  size_t n,
	  int flags,
	  const struct sockaddr_un *addr,
	  socklen_t addr_len)
{
  addr_port_t aport = MACH_PORT_NULL;
  error_t err;
  size_t wrote;

  /* Get an address port for the desired destination address.  */
  error_t create_address_port (io_t port,
			       const struct sockaddr_un *addr,
			       socklen_t addr_len,
			       addr_port_t *aport)
    {
      error_t err_port;

      if (addr->sun_family == AF_LOCAL)
	{
	  /* For the local domain, we must look up the name as a file and talk
	     to it with the ifsock protocol.  */
	  file_t file = __file_name_lookup (addr->sun_path, 0, 0);
	  if (file == MACH_PORT_NULL)
	    return errno;
	  err_port = __ifsock_getsockaddr (file, aport);
	  __mach_port_deallocate (__mach_task_self (), file);
	  if (err_port == MIG_BAD_ID || err_port == EOPNOTSUPP)
	    /* The file did not grok the ifsock protocol.  */
	    err_port = ENOTSOCK;
	}
      else
	{
	  err_port = __socket_create_address (port,
					      addr->sun_family,
					      (char *) addr,
					      addr_len,
					      aport);
	}

      return err_port;
    }
Exemple #21
0
/* Open FILE with access OFLAG.  If O_CREAT or O_TMPFILE is in OFLAG,
   a third argument is the file protection.  */
int
__libc_open (const char *file, int oflag, ...)
{
  mode_t mode;
  io_t port;

  if (__OPEN_NEEDS_MODE (oflag))
    {
      va_list arg;
      va_start (arg, oflag);
      mode = va_arg (arg, mode_t);
      va_end (arg);
    }
  else
    mode = 0;

  port = __file_name_lookup (file, oflag, mode);
  if (port == MACH_PORT_NULL)
    return -1;

  return _hurd_intern_fd (port, oflag, 1);
}
Exemple #22
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 #23
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 #24
0
static void
check_one_fd (int fd, int mode)
{
  struct hurd_fd *d;

  d = _hurd_fd_get (fd);
  if (d == NULL)
    {
      /* This descriptor hasn't been opened.  We try to allocate the
         descriptor and open /dev/null on it so that the SUID program
         we are about to start does not accidentally use this
         descriptor.  */
      d = _hurd_alloc_fd (NULL, fd);
      if (d != NULL)
	{
	  mach_port_t port;

	  port = __file_name_lookup (_PATH_DEVNULL, mode, 0);
	  if (port)
	    {
	      /* Since /dev/null isn't supposed to be a terminal, we
		 avoid any ctty magic.  */
	      d->port.port = port;
	      d->flags = 0;

	      __spin_unlock (&d->port.lock);
	      return;
	    }
	}

      /* We cannot even give an error message here since it would run
	 into the same problems.  */
      while (1)
	/* Try for ever and ever.  */
	ABORT_INSTRUCTION;
    }
}
Exemple #25
0
/* Create a new shared memory segment file without linking it into the
   filesystem.  Return the directory and file ports in R_DIR and R_FILE.  */
static error_t
create_shm_file (size_t size, int flags, file_t *r_dir, file_t *r_file)
{
  error_t err;
  file_t dir;
  file_t file;

  flags &= 0777;

  /* Get a port to the directory that will contain the file.  */
  dir = __file_name_lookup (SHM_DIR, 0, 0);
  if (dir == MACH_PORT_NULL)
    return errno;

  /* Create an unnamed file in the directory.  */
  err = __dir_mkfile (dir, O_RDWR, flags, &file);
  if (err)
    {
      __mach_port_deallocate (__mach_task_self (), dir);
      return err;
    }

  err = __file_set_size (file, size);
  if (err)
    {
      __mach_port_deallocate (__mach_task_self (), file);
      __mach_port_deallocate (__mach_task_self (), dir);

      return err;
    }

  *r_dir = dir;
  *r_file = file;

  return 0;
}
Exemple #26
0
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA.  */

#include <ansidecl.h>
#include <errno.h>
#include <stddef.h>
#include <unistd.h>
#include <hurd.h>
#include <fcntl.h>
#include <hurd/port.h>

/* Change the current root to FILE_NAME.  */
int
DEFUN(chroot, (file_name), CONST char *file_name)
{
  file_t file, dir;
  error_t err;

  file = __file_name_lookup (file_name, O_EXEC, 0);
  if (file == MACH_PORT_NULL)
    return -1;
  err = __USEPORT (CRDIR, __hurd_file_name_lookup (port, file, "",
						   O_EXEC, 0, &dir));
  __mach_port_deallocate (__mach_task_self (), file);
  if (err)
    return __hurd_fail (err);

  _hurd_port_set (&_hurd_ports[INIT_PORT_CRDIR], dir);
  return 0;
}
Exemple #27
0
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <hurd.h>


/* Open a directory stream on NAME.  */
DIR *
DEFUN(opendir, (name), CONST char *name)
{
  DIR *dirp;
  file_t port;

  port = __file_name_lookup (name, O_RDONLY, 0);
  if (port == MACH_PORT_NULL)
    return NULL;

  /* XXX this port should be deallocated on exec */

  dirp = (DIR *) malloc (sizeof (DIR));
  if (dirp == NULL)
    {
      __mach_port_deallocate (__mach_task_self (), port);
      return NULL;
    }    

  dirp->__port = port;
  dirp->__data = dirp->__ptr = NULL;
  dirp->__entry_data = dirp->__entry_ptr = 0;
Exemple #28
0
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., 675 Mass Ave,
Cambridge, MA 02139, USA.  */

#include <ansidecl.h>
#include <errno.h>
#include <stddef.h>
#include <sys/stat.h>
#include <hurd.h>

/* Change the flags of FILE to FLAGS.  */
int
DEFUN(chflags, (file, flags), CONST char *file AND 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 #29
0
/* Call the crash dump server to mummify us before we die.
   Returns nonzero if a core file was written.  */
static int
write_corefile (int signo, const struct hurd_signal_detail *detail)
{
  error_t err;
  mach_port_t coreserver;
  file_t file, coredir;
  const char *name;

  /* Don't bother locking since we just read the one word.  */
  rlim_t corelimit = _hurd_rlimits[RLIMIT_CORE].rlim_cur;

  if (corelimit == 0)
    /* No core dumping, thank you very much.  Note that this makes
       `ulimit -c 0' prevent crash-suspension too, which is probably
       what the user wanted.  */
    return 0;

  /* XXX RLIMIT_CORE:
     When we have a protocol to make the server return an error
     for RLIMIT_FSIZE, then tell the corefile fs server the RLIMIT_CORE
     value in place of the RLIMIT_FSIZE value.  */

  /* First get a port to the core dumping server.  */
  coreserver = MACH_PORT_NULL;
  name = _hurdsig_getenv ("CRASHSERVER");
  if (name != NULL)
    coreserver = __file_name_lookup (name, 0, 0);
  if (coreserver == MACH_PORT_NULL)
    coreserver = __file_name_lookup (_SERVERS_CRASH, 0, 0);
  if (coreserver == MACH_PORT_NULL)
    return 0;

  /* Get a port to the directory where the new core file will reside.  */
  file = MACH_PORT_NULL;
  name = _hurdsig_getenv ("COREFILE");
  if (name == NULL)
    name = "core";
  coredir = __file_name_split (name, (char **) &name);
  if (coredir != MACH_PORT_NULL)
    /* Create the new file, but don't link it into the directory yet.  */
    __dir_mkfile (coredir, O_WRONLY|O_CREAT,
		  0600 & ~_hurd_umask, /* XXX ? */
		  &file);

  /* Call the core dumping server to write the core file.  */
  err = __crash_dump_task (coreserver,
			   __mach_task_self (),
			   file,
			   signo, detail->code, detail->error,
			   detail->exc, detail->exc_code, detail->exc_subcode,
			   _hurd_ports[INIT_PORT_CTTYID].port,
			   MACH_MSG_TYPE_COPY_SEND);
  __mach_port_deallocate (__mach_task_self (), coreserver);

  if (! err && file != MACH_PORT_NULL)
    /* The core dump into FILE succeeded, so now link it into the
       directory.  */
    err = __dir_link (coredir, file, name, 1);
  __mach_port_deallocate (__mach_task_self (), file);
  __mach_port_deallocate (__mach_task_self (), coredir);
  return !err && file != MACH_PORT_NULL;
}