if (dirOut)
*dirOut = dir;
- if (dir && *name)
+ /* At this stage we have looked up directory part and have the name part
+ * in name if there is one.
+ *
+ * eg /nand/x/ will give us a name of ""
+ * /nand/x will give us a name of "x"
+ *
+ * Since the name part might be "." or ".." which need to be fixed.
+ */
+ if (dir && (yaffs_strcmp(name, _Y("..")) == 0)) {
+ dir = dir->parent;
+ obj = dir;
+ } else if (dir && (yaffs_strcmp(name, _Y(".")) == 0))
+ obj = dir;
+ else if (dir && *name)
obj = yaffs_find_by_name(dir, name);
else
obj = dir;
oflag &= ~(O_EXCL);
/* O_TRUNC has no meaning if (O_CREAT | O_EXCL) is specified */
- if ((oflag & O_CREAT) & (oflag & O_EXCL))
+ if ((oflag & O_CREAT) && (oflag & O_EXCL))
oflag &= ~(O_TRUNC);
/* Todo: Are there any more flag combos to sanitise ? */
}
/* Check file permissions */
- if (readRequested && !(obj->yst_mode & S_IREAD))
+ if (readRequested && !(obj->yst_mode & S_IRUSR))
openDenied = 1;
- if (writeRequested && !(obj->yst_mode & S_IWRITE))
+ if (writeRequested && !(obj->yst_mode & S_IWUSR))
openDenied = 1;
if (!errorReported && writeRequested &&
return yaffs_unlink_reldir(NULL, path);
}
+int yaffs_funlink(int fd)
+{
+ struct yaffs_obj *obj;
+ int retVal = -1;
+
+ yaffsfs_Lock();
+ obj = yaffsfs_HandleToObject(fd);
+
+ if (!obj)
+ yaffsfs_SetError(-EBADF);
+ else if (obj->my_dev->read_only)
+ yaffsfs_SetError(-EROFS);
+ else if (!isDirectory &&
+ obj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY)
+ yaffsfs_SetError(-EISDIR);
+ else if (isDirectory &&
+ obj->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY)
+ yaffsfs_SetError(-ENOTDIR);
+ else if (isDirectory && obj == obj->my_dev->root_dir)
+ yaffsfs_SetError(-EBUSY); /* Can't rmdir a root */
+ else if (yaffs_unlink_obj(oobj) == YAFFS_OK)
+ retVal = 0;
+
+ yaffsfs_Unlock();
+
+ return retVal;
+}
+
+
static int rename_file_over_dir(struct yaffs_obj *obj, struct yaffs_obj *newobj)
{
if (obj && obj->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY &&
else {
int access_ok = 1;
- if ((amode & R_OK) && !(obj->yst_mode & S_IREAD))
+ if ((amode & R_OK) && !(obj->yst_mode & S_IRUSR))
access_ok = 0;
- if ((amode & W_OK) && !(obj->yst_mode & S_IWRITE))
+ if ((amode & W_OK) && !(obj->yst_mode & S_IWUSR))
access_ok = 0;
- if ((amode & X_OK) && !(obj->yst_mode & S_IEXEC))
+ if ((amode & X_OK) && !(obj->yst_mode & S_IXUSR))
access_ok = 0;
if (!access_ok)
return yaffs_mount_common(NULL, path, 0, 0);
}
-int yaffs_sync_common(struct yaffs_dev *dev, const YCHAR *path)
+static int yaffs_sync_common(struct yaffs_dev *dev,
+ const YCHAR *path,
+ int do_checkpt)
{
int retVal = -1;
YCHAR *dummy;
else {
yaffs_flush_whole_cache(dev, 0);
- yaffs_checkpoint_save(dev);
+ if (do_checkpt)
+ yaffs_checkpoint_save(dev);
retVal = 0;
}
return retVal;
}
+int yaffs_sync_files_reldev(struct yaffs_dev *dev)
+{
+ return yaffs_sync_common(dev, NULL, 0);
+}
+
+int yaffs_sync_files(const YCHAR *path)
+{
+ return yaffs_sync_common(NULL, path, 0);
+}
+
int yaffs_sync_reldev(struct yaffs_dev *dev)
{
- return yaffs_sync_common(dev, NULL);
+ return yaffs_sync_common(dev, NULL, 1);
}
int yaffs_sync(const YCHAR *path)
{
- return yaffs_sync_common(NULL, path);
+ return yaffs_sync_common(NULL, path, 1);
}
}
obj = yaffsfs_FindObject(reldir, dirname, 0, 1, NULL, ¬Dir, &loop);
+ obj = yaffsfs_FollowLink(obj, 0, &loop);
if (!obj && notDir)
yaffsfs_SetError(-ENOTDIR);
return 0;
}
+
int yaffs_closedir(yaffs_DIR *dirp)
{
int ret;
return 0;
}
+struct yaffs_obj * yaffs_get_obj_from_fd(int handle)
+{
+ return yaffsfs_HandleToObject(handle);
+}
+
int yaffs_dump_dev_reldir(struct yaffs_obj *reldir, const YCHAR *path)
{
#if 1