patch(1) problems workaround
[minix3.git] / lib / libvboxfs / handle.c
blobc264a8bee32e3c96726c1bc2e6347948ecabefe3
1 /* Part of libvboxfs - (c) 2012, D.C. van Moolenbroek */
3 #include "inc.h"
5 /*
6 * Create or open a file or directory.
7 */
8 int
9 vboxfs_open_file(char *path, int flags, int mode, vboxfs_handle_t *handlep,
10 vboxfs_objinfo_t *infop)
12 vbox_param_t param[3];
13 vboxfs_path_t pathbuf;
14 vboxfs_crinfo_t crinfo;
15 int r, dir, rflag, wflag;
17 if ((r = vboxfs_set_path(&pathbuf, path)) != OK)
18 return r;
20 memset(&crinfo, 0, sizeof(crinfo));
23 * Note that the mode may not be set at all. If no new file may be
24 * created, this is not a problem. The following test succeeds only if
25 * the caller explicitly specified that a directory is involved.
27 dir = S_ISDIR(mode);
29 /* Convert open(2) flags to VirtualBox creation flags. */
30 if (flags & O_APPEND)
31 return EINVAL; /* not supported at this time */
33 if (flags & O_CREAT) {
34 crinfo.flags = VBOXFS_CRFLAG_CREATE_IF_NEW;
36 if (flags & O_EXCL)
37 crinfo.flags |= VBOXFS_CRFLAG_FAIL_IF_EXISTS;
38 else if (flags & O_TRUNC)
39 crinfo.flags |= VBOXFS_CRFLAG_TRUNC_IF_EXISTS;
40 else
41 crinfo.flags |= VBOXFS_CRFLAG_OPEN_IF_EXISTS;
42 } else {
43 crinfo.flags = VBOXFS_CRFLAG_FAIL_IF_NEW;
45 if (flags & O_TRUNC)
46 crinfo.flags |= VBOXFS_CRFLAG_TRUNC_IF_EXISTS;
47 else
48 crinfo.flags |= VBOXFS_CRFLAG_OPEN_IF_EXISTS;
52 * If an object information structure is given, open the file only to
53 * retrieve or change its attributes.
55 if (infop != NULL) {
56 rflag = VBOXFS_CRFLAG_READ_ATTR;
57 wflag = VBOXFS_CRFLAG_WRITE_ATTR;
58 } else {
59 rflag = VBOXFS_CRFLAG_READ;
60 wflag = VBOXFS_CRFLAG_WRITE;
63 switch (flags & O_ACCMODE) {
64 case O_RDONLY: crinfo.flags |= rflag; break;
65 case O_WRONLY: crinfo.flags |= wflag; break;
66 case O_RDWR: crinfo.flags |= rflag | wflag; break;
67 default: return EINVAL;
70 if (S_ISDIR(mode))
71 crinfo.flags |= VBOXFS_CRFLAG_DIRECTORY;
73 crinfo.info.attr.mode = VBOXFS_SET_MODE(dir ? S_IFDIR : S_IFREG, mode);
74 crinfo.info.attr.add = VBOXFS_OBJATTR_ADD_NONE;
76 vbox_set_u32(&param[0], vboxfs_root);
77 vbox_set_ptr(&param[1], &pathbuf, vboxfs_get_path_size(&pathbuf),
78 VBOX_DIR_OUT);
79 vbox_set_ptr(&param[2], &crinfo, sizeof(crinfo), VBOX_DIR_INOUT);
81 r = vbox_call(vboxfs_conn, VBOXFS_CALL_CREATE, param, 3, NULL);
82 if (r != OK)
83 return r;
85 if (crinfo.handle == VBOXFS_INVALID_HANDLE) {
86 switch (crinfo.result) {
87 case VBOXFS_PATH_NOT_FOUND:
89 * This could also mean ENOTDIR, but there does not
90 * appear to be any way to distinguish that case.
91 * Verifying with extra lookups seems overkill.
93 case VBOXFS_FILE_NOT_FOUND:
94 return ENOENT;
95 case VBOXFS_FILE_EXISTS:
96 return EEXIST;
97 default:
98 return EIO; /* should never happen */
102 *handlep = crinfo.handle;
103 if (infop != NULL)
104 *infop = crinfo.info;
105 return OK;
109 * Close an open file handle.
111 void
112 vboxfs_close_file(vboxfs_handle_t handle)
114 vbox_param_t param[2];
116 vbox_set_u32(&param[0], vboxfs_root);
117 vbox_set_u64(&param[1], handle);
119 /* Ignore errors here. We cannot do anything with them anyway. */
120 (void) vbox_call(vboxfs_conn, VBOXFS_CALL_CLOSE, param, 2, NULL);