1 /* Part of libvboxfs - (c) 2012, D.C. van Moolenbroek */
6 * Convert a VirtualBox timestamp to a POSIX timespec structure.
7 * VirtualBox' timestamps are in nanoseconds since the UNIX epoch.
10 get_time(struct timespec
*tsp
, u64_t nsecs
)
13 tsp
->tv_sec
= div64u(nsecs
, 1000000000);
14 tsp
->tv_nsec
= rem64u(nsecs
, 1000000000);
18 * Convert a POSIX timespec structure to a VirtualBox timestamp.
21 set_time(struct timespec
*tsp
)
24 return add64u(mul64u(tsp
->tv_sec
, 1000000000), tsp
->tv_nsec
);
28 * Fill the given attribute structure with VirtualBox object information.
31 vboxfs_get_attr(struct sffs_attr
*attr
, vboxfs_objinfo_t
*info
)
34 if (attr
->a_mask
& SFFS_ATTR_SIZE
)
35 attr
->a_size
= info
->size
;
36 if (attr
->a_mask
& SFFS_ATTR_MODE
)
37 attr
->a_mode
= VBOXFS_GET_MODE(info
->attr
.mode
);
38 if (attr
->a_mask
& SFFS_ATTR_ATIME
)
39 get_time(&attr
->a_atime
, info
->atime
);
40 if (attr
->a_mask
& SFFS_ATTR_MTIME
)
41 get_time(&attr
->a_mtime
, info
->mtime
);
42 if (attr
->a_mask
& SFFS_ATTR_CTIME
)
43 get_time(&attr
->a_ctime
, info
->ctime
);
44 if (attr
->a_mask
& SFFS_ATTR_CRTIME
)
45 get_time(&attr
->a_crtime
, info
->crtime
);
49 * Get file attributes.
52 vboxfs_getattr(char *path
, struct sffs_attr
*attr
)
54 vbox_param_t param
[3];
55 vboxfs_path_t pathbuf
;
56 vboxfs_crinfo_t crinfo
;
59 if ((r
= vboxfs_set_path(&pathbuf
, path
)) != OK
)
62 memset(&crinfo
, 0, sizeof(crinfo
));
63 crinfo
.flags
= VBOXFS_CRFLAG_LOOKUP
;
64 /* crinfo.info.attr.add is not checked */
66 vbox_set_u32(¶m
[0], vboxfs_root
);
67 vbox_set_ptr(¶m
[1], &pathbuf
, vboxfs_get_path_size(&pathbuf
),
69 vbox_set_ptr(¶m
[2], &crinfo
, sizeof(crinfo
), VBOX_DIR_INOUT
);
71 r
= vbox_call(vboxfs_conn
, VBOXFS_CALL_CREATE
, param
, 3, NULL
);
75 switch (crinfo
.result
) {
76 case VBOXFS_PATH_NOT_FOUND
:
77 /* This could also be ENOTDIR. See note in handle.c. */
78 case VBOXFS_FILE_NOT_FOUND
:
80 case VBOXFS_FILE_EXISTS
:
83 return EIO
; /* should never happen */
86 vboxfs_get_attr(attr
, &crinfo
.info
);
95 set_size(char *path
, u64_t size
)
97 vboxfs_objinfo_t info
;
101 if ((r
= vboxfs_open_file(path
, O_WRONLY
, S_IFREG
, &h
, NULL
)) != OK
)
104 memset(&info
, 0, sizeof(info
));
107 r
= vboxfs_getset_info(h
, VBOXFS_INFO_SET
| VBOXFS_INFO_SIZE
, &info
,
110 vboxfs_close_file(h
);
116 * Set file attributes.
119 vboxfs_setattr(char *path
, struct sffs_attr
*attr
)
121 vboxfs_objinfo_t info
;
126 * Setting the size of a path cannot be combined with other attribute
127 * modifications, because we cannot fail atomically.
129 if (attr
->a_mask
& SFFS_ATTR_SIZE
) {
130 assert(attr
->a_mask
== SFFS_ATTR_SIZE
);
132 return set_size(path
, attr
->a_size
);
136 * By passing a pointer to an object information structure, we open the
137 * file for attribute manipulation. Note that this call will open the
138 * file as a regular file. This works on directories as well.
140 if ((r
= vboxfs_open_file(path
, O_WRONLY
, 0, &h
, &info
)) != OK
)
143 info
.attr
.add
= VBOXFS_OBJATTR_ADD_NONE
;
145 /* Update the file's permissions if requested. */
146 if (attr
->a_mask
& SFFS_ATTR_MODE
)
148 VBOXFS_SET_MODE(info
.attr
.mode
& S_IFMT
, attr
->a_mode
);
151 * Update various file times if requested. Not all changes may
152 * be honered. A zero time indicates no change.
154 info
.atime
= (attr
->a_mask
& SFFS_ATTR_ATIME
) ?
155 set_time(&attr
->a_atime
) : 0;
156 info
.mtime
= (attr
->a_mask
& SFFS_ATTR_MTIME
) ?
157 set_time(&attr
->a_ctime
) : 0;
158 info
.ctime
= (attr
->a_mask
& SFFS_ATTR_CTIME
) ?
159 set_time(&attr
->a_ctime
) : 0;
160 info
.crtime
= (attr
->a_mask
& SFFS_ATTR_CRTIME
) ?
161 set_time(&attr
->a_crtime
) : 0;
163 r
= vboxfs_getset_info(h
, VBOXFS_INFO_SET
| VBOXFS_INFO_FILE
, &info
,
166 vboxfs_close_file(h
);