示例#1
0
/* Detect if chown(2) is supported on the target directory. */
static int
is_chown_supported (const char *dir)
{
  CLEANUP_FREE char *buf = NULL;
  int fd, r, err, saved_errno;

  /* Create a randomly named file. */
  if (asprintf (&buf, "%s%s/XXXXXXXX.XXX", sysroot, dir) == -1) {
    err = errno;
    r = cancel_receive ();
    errno = err;
    reply_with_perror ("asprintf");
    return -1;
  }
  if (random_name (buf) == -1) {
    err = errno;
    r = cancel_receive ();
    errno = err;
    reply_with_perror ("random_name");
    return -1;
  }

  /* Maybe 'dir' is not a directory or filesystem not writable? */
  fd = open (buf, O_WRONLY|O_CREAT|O_NOCTTY|O_CLOEXEC, 0666);
  if (fd == -1) {
    err = errno;
    r = cancel_receive ();
    errno = err;
    reply_with_perror ("%s", dir);
    return -1;
  }

  /* This is the test. */
  r = fchown (fd, 1000, 1000);
  saved_errno = errno;

  /* Make sure the test file is removed. */
  close (fd);
  unlink (buf);

  if (r == -1 && saved_errno == EPERM) {
    /* This means chown is not supported by the filesystem. */
    return 0;
  }

  if (r == -1) {
    /* Some other error? */
    err = errno;
    r = cancel_receive ();
    errno = err;
    reply_with_perror_errno (saved_errno, "unexpected error in fchown");
    return -1;
  }

  /* Else chown is supported. */
  return 1;
}
示例#2
0
文件: tar.c 项目: imcleod/libguestfs
/* Detect if chown(2) is supported on the target directory. */
static int
is_chown_supported (const char *dir)
{
  size_t len = sysroot_len + strlen (dir) + 64;
  char buf[len];
  int fd, r, saved_errno;

  /* Create a randomly named file. */
  snprintf (buf, len, "%s%s/XXXXXXXX.XXX", sysroot, dir);
  if (random_name (buf) == -1) {
    reply_with_perror ("random_name");
    return -1;
  }

  /* Maybe 'dir' is not a directory or filesystem not writable? */
  fd = open (buf, O_WRONLY|O_CREAT|O_NOCTTY|O_CLOEXEC, 0666);
  if (fd == -1) {
    reply_with_perror ("%s", dir);
    return -1;
  }

  /* This is the test. */
  r = fchown (fd, 1000, 1000);
  saved_errno = errno;

  /* Make sure the test file is removed. */
  close (fd);
  unlink (buf);

  if (r == -1 && saved_errno == EPERM) {
    /* This means chown is not supported by the filesystem. */
    return 0;
  }

  if (r == -1) {
    /* Some other error? */
    reply_with_perror_errno (saved_errno, "unexpected error in fchown");
    return -1;
  }

  /* Else chown is supported. */
  return 1;
}