qemu/hw/9pfs/9p-util.c
<<
>>
Prefs
   1/*
   2 * 9p utilities
   3 *
   4 * Copyright IBM, Corp. 2017
   5 *
   6 * Authors:
   7 *  Greg Kurz <groug@kaod.org>
   8 *
   9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
  10 * See the COPYING file in the top-level directory.
  11 */
  12
  13#include "qemu/osdep.h"
  14#include "qemu/xattr.h"
  15#include "9p-util.h"
  16
  17int relative_openat_nofollow(int dirfd, const char *path, int flags,
  18                             mode_t mode)
  19{
  20    int fd;
  21
  22    fd = dup(dirfd);
  23    if (fd == -1) {
  24        return -1;
  25    }
  26
  27    while (*path) {
  28        const char *c;
  29        int next_fd;
  30        char *head;
  31
  32        /* Only relative paths without consecutive slashes */
  33        assert(path[0] != '/');
  34
  35        head = g_strdup(path);
  36        c = strchr(path, '/');
  37        if (c) {
  38            head[c - path] = 0;
  39            next_fd = openat_dir(fd, head);
  40        } else {
  41            next_fd = openat_file(fd, head, flags, mode);
  42        }
  43        g_free(head);
  44        if (next_fd == -1) {
  45            close_preserve_errno(fd);
  46            return -1;
  47        }
  48        close(fd);
  49        fd = next_fd;
  50
  51        if (!c) {
  52            break;
  53        }
  54        path = c + 1;
  55    }
  56
  57    return fd;
  58}
  59
  60ssize_t fgetxattrat_nofollow(int dirfd, const char *filename, const char *name,
  61                             void *value, size_t size)
  62{
  63    char *proc_path = g_strdup_printf("/proc/self/fd/%d/%s", dirfd, filename);
  64    int ret;
  65
  66    ret = lgetxattr(proc_path, name, value, size);
  67    g_free(proc_path);
  68    return ret;
  69}
  70