 94e65446c4
			
		
	
	
		94e65446c4
		
	
	
	
	
		
			
			And a few other related warning fixes. Change-Id: I1a49b9ee04c2b1bf80bc943272f72ffd6de77ef6
		
			
				
	
	
		
			170 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			170 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* Part of libvboxfs - (c) 2012, D.C. van Moolenbroek */
 | |
| 
 | |
| #include "inc.h"
 | |
| 
 | |
| /*
 | |
|  * Convert a VirtualBox timestamp to a POSIX timespec structure.
 | |
|  * VirtualBox' timestamps are in nanoseconds since the UNIX epoch.
 | |
|  */
 | |
| static void
 | |
| get_time(struct timespec *tsp, u64_t nsecs)
 | |
| {
 | |
| 
 | |
| 	tsp->tv_sec = (unsigned long)(nsecs / 1000000000);
 | |
| 	tsp->tv_nsec = (unsigned)(nsecs % 1000000000);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Convert a POSIX timespec structure to a VirtualBox timestamp.
 | |
|  */
 | |
| static u64_t
 | |
| set_time(struct timespec *tsp)
 | |
| {
 | |
| 
 | |
| 	return ((u64_t)tsp->tv_sec * 1000000000) + tsp->tv_nsec;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Fill the given attribute structure with VirtualBox object information.
 | |
|  */
 | |
| void
 | |
| vboxfs_get_attr(struct sffs_attr *attr, vboxfs_objinfo_t *info)
 | |
| {
 | |
| 
 | |
| 	if (attr->a_mask & SFFS_ATTR_SIZE)
 | |
| 		attr->a_size = info->size;
 | |
| 	if (attr->a_mask & SFFS_ATTR_MODE)
 | |
| 		attr->a_mode = VBOXFS_GET_MODE(info->attr.mode);
 | |
| 	if (attr->a_mask & SFFS_ATTR_ATIME)
 | |
| 		get_time(&attr->a_atime, info->atime);
 | |
| 	if (attr->a_mask & SFFS_ATTR_MTIME)
 | |
| 		get_time(&attr->a_mtime, info->mtime);
 | |
| 	if (attr->a_mask & SFFS_ATTR_CTIME)
 | |
| 		get_time(&attr->a_ctime, info->ctime);
 | |
| 	if (attr->a_mask & SFFS_ATTR_CRTIME)
 | |
| 		get_time(&attr->a_crtime, info->crtime);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Get file attributes.
 | |
|  */
 | |
| int
 | |
| vboxfs_getattr(const char *path, struct sffs_attr *attr)
 | |
| {
 | |
| 	vbox_param_t param[3];
 | |
| 	vboxfs_path_t pathbuf;
 | |
| 	vboxfs_crinfo_t crinfo;
 | |
| 	int r;
 | |
| 
 | |
| 	if ((r = vboxfs_set_path(&pathbuf, path)) != OK)
 | |
| 		return r;
 | |
| 
 | |
| 	memset(&crinfo, 0, sizeof(crinfo));
 | |
| 	crinfo.flags = VBOXFS_CRFLAG_LOOKUP;
 | |
| 	/* crinfo.info.attr.add is not checked */
 | |
| 
 | |
| 	vbox_set_u32(¶m[0], vboxfs_root);
 | |
| 	vbox_set_ptr(¶m[1], &pathbuf, vboxfs_get_path_size(&pathbuf),
 | |
| 	    VBOX_DIR_OUT);
 | |
| 	vbox_set_ptr(¶m[2], &crinfo, sizeof(crinfo), VBOX_DIR_INOUT);
 | |
| 
 | |
| 	r = vbox_call(vboxfs_conn, VBOXFS_CALL_CREATE, param, 3, NULL);
 | |
| 	if (r != OK)
 | |
| 		return r;
 | |
| 
 | |
| 	switch (crinfo.result) {
 | |
| 	case VBOXFS_PATH_NOT_FOUND:
 | |
| 		/* This could also be ENOTDIR. See note in handle.c. */
 | |
| 	case VBOXFS_FILE_NOT_FOUND:
 | |
| 		return ENOENT;
 | |
| 	case VBOXFS_FILE_EXISTS:
 | |
| 		break;			/* success */
 | |
| 	default:
 | |
| 		return EIO;		/* should never happen */
 | |
| 	}
 | |
| 
 | |
| 	vboxfs_get_attr(attr, &crinfo.info);
 | |
| 
 | |
| 	return OK;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Set file size.
 | |
|  */
 | |
| static int
 | |
| set_size(const char *path, u64_t size)
 | |
| {
 | |
| 	vboxfs_objinfo_t info;
 | |
| 	vboxfs_handle_t h;
 | |
| 	int r;
 | |
| 
 | |
| 	if ((r = vboxfs_open_file(path, O_WRONLY, S_IFREG, &h, NULL)) != OK)
 | |
| 		return r;
 | |
| 
 | |
| 	memset(&info, 0, sizeof(info));
 | |
| 	info.size = size;
 | |
| 
 | |
| 	r = vboxfs_getset_info(h, VBOXFS_INFO_SET | VBOXFS_INFO_SIZE, &info,
 | |
| 	    sizeof(info));
 | |
| 
 | |
| 	vboxfs_close_file(h);
 | |
| 
 | |
| 	return r;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Set file attributes.
 | |
|  */
 | |
| int
 | |
| vboxfs_setattr(const char *path, struct sffs_attr *attr)
 | |
| {
 | |
| 	vboxfs_objinfo_t info;
 | |
| 	vboxfs_handle_t h;
 | |
| 	int r;
 | |
| 
 | |
| 	/*
 | |
| 	 * Setting the size of a path cannot be combined with other attribute
 | |
| 	 * modifications, because we cannot fail atomically.
 | |
| 	 */
 | |
| 	if (attr->a_mask & SFFS_ATTR_SIZE) {
 | |
| 		assert(attr->a_mask == SFFS_ATTR_SIZE);
 | |
| 
 | |
| 		return set_size(path, attr->a_size);
 | |
| 	}
 | |
| 
 | |
| 	/*
 | |
| 	 * By passing a pointer to an object information structure, we open the
 | |
| 	 * file for attribute manipulation.  Note that this call will open the
 | |
| 	 * file as a regular file.  This works on directories as well.
 | |
| 	 */
 | |
| 	if ((r = vboxfs_open_file(path, O_WRONLY, 0, &h, &info)) != OK)
 | |
| 		return r;
 | |
| 
 | |
| 	info.attr.add = VBOXFS_OBJATTR_ADD_NONE;
 | |
| 
 | |
| 	/* Update the file's permissions if requested. */
 | |
| 	if (attr->a_mask & SFFS_ATTR_MODE)
 | |
| 		info.attr.mode =
 | |
| 		    VBOXFS_SET_MODE(info.attr.mode & S_IFMT, attr->a_mode);
 | |
| 
 | |
| 	/*
 | |
| 	 * Update various file times if requested.  Not all changes may
 | |
| 	 * be honered.  A zero time indicates no change.
 | |
| 	 */
 | |
| 	info.atime = (attr->a_mask & SFFS_ATTR_ATIME) ?
 | |
| 	    set_time(&attr->a_atime) : 0;
 | |
| 	info.mtime = (attr->a_mask & SFFS_ATTR_MTIME) ?
 | |
| 	    set_time(&attr->a_mtime) : 0;
 | |
| 	info.ctime = (attr->a_mask & SFFS_ATTR_CTIME) ?
 | |
| 	    set_time(&attr->a_ctime) : 0;
 | |
| 	info.crtime = (attr->a_mask & SFFS_ATTR_CRTIME) ?
 | |
| 	    set_time(&attr->a_crtime) : 0;
 | |
| 
 | |
| 	r = vboxfs_getset_info(h, VBOXFS_INFO_SET | VBOXFS_INFO_FILE, &info,
 | |
| 	    sizeof(info));
 | |
| 
 | |
| 	vboxfs_close_file(h);
 | |
| 
 | |
| 	return r;
 | |
| }
 |