1 /* Part of libvboxfs - (c) 2012, D.C. van Moolenbroek */
6 * Create or open a file or directory.
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
)
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.
29 /* Convert open(2) flags to VirtualBox creation flags. */
31 return EINVAL
; /* not supported at this time */
33 if (flags
& O_CREAT
) {
34 crinfo
.flags
= VBOXFS_CRFLAG_CREATE_IF_NEW
;
37 crinfo
.flags
|= VBOXFS_CRFLAG_FAIL_IF_EXISTS
;
38 else if (flags
& O_TRUNC
)
39 crinfo
.flags
|= VBOXFS_CRFLAG_TRUNC_IF_EXISTS
;
41 crinfo
.flags
|= VBOXFS_CRFLAG_OPEN_IF_EXISTS
;
43 crinfo
.flags
= VBOXFS_CRFLAG_FAIL_IF_NEW
;
46 crinfo
.flags
|= VBOXFS_CRFLAG_TRUNC_IF_EXISTS
;
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.
56 rflag
= VBOXFS_CRFLAG_READ_ATTR
;
57 wflag
= VBOXFS_CRFLAG_WRITE_ATTR
;
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
;
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(¶m
[0], vboxfs_root
);
77 vbox_set_ptr(¶m
[1], &pathbuf
, vboxfs_get_path_size(&pathbuf
),
79 vbox_set_ptr(¶m
[2], &crinfo
, sizeof(crinfo
), VBOX_DIR_INOUT
);
81 r
= vbox_call(vboxfs_conn
, VBOXFS_CALL_CREATE
, param
, 3, NULL
);
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
:
95 case VBOXFS_FILE_EXISTS
:
98 return EIO
; /* should never happen */
102 *handlep
= crinfo
.handle
;
104 *infop
= crinfo
.info
;
109 * Close an open file handle.
112 vboxfs_close_file(vboxfs_handle_t handle
)
114 vbox_param_t param
[2];
116 vbox_set_u32(¶m
[0], vboxfs_root
);
117 vbox_set_u64(¶m
[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
);