Пример #1
0
/**
 * create a new object and open it if success
 */
URET uffs_CreateObject(uffs_Object *obj, const char *fullname, int oflag)
{
	oflag |= UO_CREATE;

	if (uffs_ParseObject(obj, fullname) == U_SUCC)
		uffs_CreateObjectEx(obj, obj->dev, obj->parent, obj->name, obj->name_len, oflag);

	return (obj->err == UENOERR ? U_SUCC : U_FAIL);
}
Пример #2
0
/**
 * create a new object and open it if success
 */
URET uffs_CreateObject(uffs_Object *obj, const char *fullname, int oflag)
{
	URET ret = U_FAIL;

	oflag |= UO_CREATE;

	if (uffs_ParseObject(obj, fullname) == U_SUCC)
		uffs_CreateObjectEx(obj, obj->dev, obj->parent,
								obj->name, obj->name_len, oflag);

	if (obj->err == UENOERR) {
		ret = U_SUCC;
	}
	else {
		if (obj->dev) {
			uffs_PutDevice(obj->dev);
			obj->dev = NULL;
		}
		ret = U_FAIL;
	}

	return ret;
}
Пример #3
0
/**
 * Open object under the given dir.
 *
 * \param[in|out] obj to be open, obj is returned from uffs_GetObject()
 * \param[in] dev uffs device
 * \param[in] dir object parent dir serial NO.
 * \param[in] name point to the object name
 * \param[in] name_len object name length
 * \param[in] oflag open flag. UO_DIR should be passed for an dir object.
 *
 * \return U_SUCC or U_FAIL (error code in obj->err).
 */
URET uffs_OpenObjectEx(uffs_Object *obj, uffs_Device *dev, 
					   int dir, const char *name, int name_len, int oflag)
{

	obj->err = UENOERR;
	obj->open_succ = U_FALSE;

	if (dev == NULL) {
		obj->err = UEINVAL;
		goto ext;
	}

	if ((oflag & (UO_WRONLY | UO_RDWR)) == (UO_WRONLY | UO_RDWR)) {
		/* UO_WRONLY and UO_RDWR can't appear together */
		uffs_Perror(UFFS_MSG_NOISY,
					"UO_WRONLY and UO_RDWR can't appear together");
		obj->err = UEINVAL;
		goto ext;
	}

	obj->oflag = oflag;
	obj->parent = dir;
	obj->type = (oflag & UO_DIR ? UFFS_TYPE_DIR : UFFS_TYPE_FILE);
	obj->pos = 0;
	obj->dev = dev;
	obj->name = name;
	obj->name_len = name_len;

	// adjust the name length
	if (obj->type == UFFS_TYPE_DIR) {
		if (obj->name_len > 0 && name[obj->name_len - 1] == '/')
			obj->name_len--;	// truncate the ending '/' for dir
	}

	obj->sum = (obj->name_len > 0 ? uffs_MakeSum16(name, obj->name_len) : 0);
	obj->head_pages = obj->dev->attr->pages_per_block - 1;

	if (obj->type == UFFS_TYPE_DIR) {
		if (obj->name_len == 0) {
			if (dir != PARENT_OF_ROOT) {
				uffs_Perror(UFFS_MSG_SERIOUS, "Bad parent for root dir!");
				obj->err = UEINVAL;
			}
			else {
				obj->serial = ROOT_DIR_SERIAL;
			}
			goto ext;
		}
	}
	else {
		if (obj->name_len == 0 || name[obj->name_len - 1] == '/') {
			uffs_Perror(UFFS_MSG_SERIOUS, "Bad file name.");
			obj->err = UEINVAL;
		}
	}


	uffs_ObjectDevLock(obj);

	if (obj->type == UFFS_TYPE_DIR) {
		obj->node = uffs_TreeFindDirNodeByName(obj->dev, obj->name,
												obj->name_len, obj->sum,
												obj->parent);
	}
	else {
		obj->node = uffs_TreeFindFileNodeByName(obj->dev, obj->name,
												obj->name_len, obj->sum,
												obj->parent);
	}

	if (obj->node == NULL) {			// dir or file not exist
		if (obj->oflag & UO_CREATE) {	// expect to create a new one
			uffs_ObjectDevUnLock(obj);
			if (obj->name == NULL || obj->name_len == 0)
				obj->err = UEEXIST;
			else
				uffs_CreateObjectEx(obj, dev, dir, obj->name, obj->name_len, oflag);
			goto ext;
		}
		else {
			obj->err = UENOENT;
			goto ext_1;
		}
	}

	if ((obj->oflag & (UO_CREATE | UO_EXCL)) == (UO_CREATE | UO_EXCL)){
		obj->err = UEEXIST;
		goto ext_1;
	}

	obj->serial = GET_OBJ_NODE_SERIAL(obj);
	obj->open_succ = U_TRUE;

	if (obj->oflag & UO_TRUNC)
		if (do_TruncateObject(obj, 0, eDRY_RUN) == U_SUCC) {
			//NOTE: obj->err will be set in do_TruncateObject() if failed.
			do_TruncateObject(obj, 0, eREAL_RUN);
		}

ext_1:
	uffs_ObjectDevUnLock(obj);
ext:
	obj->open_succ = (obj->err == UENOERR ? U_TRUE : U_FALSE);

	return (obj->err == UENOERR ? U_SUCC : U_FAIL);
}