virtio-9p: Add P9_TREAD support
[qemu/aliguori-queue.git] / hw / virtio-9p-local.c
blob81d19710404b0eba30ebbc88c682def41e75e126
1 /*
2 * Virtio 9p Posix callback
4 * Copyright IBM, Corp. 2010
6 * Authors:
7 * Anthony Liguori <aliguori@us.ibm.com>
9 * This work is licensed under the terms of the GNU GPL, version 2. See
10 * the COPYING file in the top-level directory.
13 #include "virtio.h"
14 #include "virtio-9p.h"
15 #include <pwd.h>
16 #include <grp.h>
18 static const char *rpath(FsContext *ctx, const char *path)
20 /* FIXME: so wrong... */
21 static char buffer[4096];
22 snprintf(buffer, sizeof(buffer), "%s/%s", ctx->fs_root, path);
23 return buffer;
26 static int local_lstat(FsContext *ctx, const char *path, struct stat *stbuf)
28 return lstat(rpath(ctx, path), stbuf);
31 static int local_setuid(FsContext *ctx, uid_t uid)
33 struct passwd *pw;
34 gid_t groups[33];
35 int ngroups;
36 static uid_t cur_uid = -1;
38 if (cur_uid == uid) {
39 return 0;
42 if (setreuid(0, 0)) {
43 return -1;
46 pw = getpwuid(uid);
47 if (pw == NULL) {
48 return -1;
51 ngroups = 33;
52 if (getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups) == -1) {
53 return -1;
56 if (setgroups(ngroups, groups)) {
57 return -1;
60 if (setregid(-1, pw->pw_gid)) {
61 return -1;
64 if (setreuid(-1, uid)) {
65 return -1;
68 cur_uid = uid;
70 return 0;
73 static ssize_t local_readlink(FsContext *ctx, const char *path,
74 char *buf, size_t bufsz)
76 return readlink(rpath(ctx, path), buf, bufsz);
79 static int local_close(FsContext *ctx, int fd)
81 return close(fd);
84 static int local_closedir(FsContext *ctx, DIR *dir)
86 return closedir(dir);
89 static int local_open(FsContext *ctx, const char *path, int flags)
91 return open(rpath(ctx, path), flags);
94 static DIR *local_opendir(FsContext *ctx, const char *path)
96 return opendir(rpath(ctx, path));
99 static void local_rewinddir(FsContext *ctx, DIR *dir)
101 return rewinddir(dir);
104 static off_t local_telldir(FsContext *ctx, DIR *dir)
106 return telldir(dir);
109 static struct dirent *local_readdir(FsContext *ctx, DIR *dir)
111 return readdir(dir);
114 static void local_seekdir(FsContext *ctx, DIR *dir, off_t off)
116 return seekdir(dir, off);
119 static ssize_t local_readv(FsContext *ctx, int fd, const struct iovec *iov,
120 int iovcnt)
122 return readv(fd, iov, iovcnt);
125 static off_t local_lseek(FsContext *ctx, int fd, off_t offset, int whence)
127 return lseek(fd, offset, whence);
130 FileOperations local_ops = {
131 .lstat = local_lstat,
132 .setuid = local_setuid,
133 .readlink = local_readlink,
134 .close = local_close,
135 .closedir = local_closedir,
136 .open = local_open,
137 .opendir = local_opendir,
138 .rewinddir = local_rewinddir,
139 .telldir = local_telldir,
140 .readdir = local_readdir,
141 .seekdir = local_seekdir,
142 .readv = local_readv,
143 .lseek = local_lseek,