X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=direct%2Fyaffsfs.c;h=8593cbe72d82bb1745396c43fdf5f8a3873009d0;hp=05cd22977720acd42e1bc925f9fc119e05a81584;hb=5e0db4930940ade57ea3bf3dce0d3db0362a9f0e;hpb=bfde38bff96a421dcb73ffbb8b9b69f3f6500677 diff --git a/direct/yaffsfs.c b/direct/yaffsfs.c index 05cd229..8593cbe 100644 --- a/direct/yaffsfs.c +++ b/direct/yaffsfs.c @@ -19,6 +19,7 @@ #include "string.h" +#define YAFFS_MAX_RW_SIZE 0x70000000 #define YAFFSFS_MAX_SYMLINK_DEREFERENCES 5 #ifndef NULL @@ -346,8 +347,10 @@ static int yaffsfs_PutFileDes(int fdId) fd = &yaffsfs_fd[fdId]; fd->handleCount--; if (fd->handleCount < 1) { - if (fd->isDir) + if (fd->isDir) { yaffsfs_closedir_no_lock(fd->v.dir); + fd->v.dir = NULL; + } if (fd->inodeId >= 0) { yaffsfs_PutInode(fd->inodeId); fd->inodeId = -1; @@ -836,7 +839,7 @@ int yaffs_open_sharing_reldir(struct yaffs_obj *reldir, const YCHAR *path, int notDir = 0; int loop = 0; int is_dir = 0; - yaffs_DIR *dsc; + yaffs_DIR *dsc = NULL; if (yaffsfs_CheckMemRegion(path, 0, 0)< 0) { yaffsfs_SetError(-EFAULT); @@ -869,7 +872,7 @@ int yaffs_open_sharing_reldir(struct yaffs_obj *reldir, const YCHAR *path, if (handle < 0) { yaffsfs_SetError(-ENFILE); - errorReported = 1; + errorReported = __LINE__; } else { fd = yaffsfs_HandleToFileDes(handle); @@ -890,21 +893,22 @@ int yaffs_open_sharing_reldir(struct yaffs_obj *reldir, const YCHAR *path, is_dir = (obj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY); - /* A directory can't be opened except for read */ - if ( is_dir && - (writeRequested || !readRequested || - (oflag & ~O_RDONLY))) { - openDenied = 1; - yaffsfs_SetError(-EISDIR); - errorReported = 1; + /* + * A directory can't be opened except for read, so we + * ignore other flags + */ + if (is_dir) { + writeRequested = 0; + readRequested = 1; + rwflags = O_RDONLY; } if(is_dir) { dsc = yaffsfs_opendir_reldir_no_lock(reldir, path); if (!dsc) { - openDenied = 1; + openDenied = __LINE__; yaffsfs_SetError(-ENFILE); - errorReported = 1; + errorReported = __LINE__; } } @@ -913,28 +917,28 @@ int yaffs_open_sharing_reldir(struct yaffs_obj *reldir, const YCHAR *path, */ if (!errorReported && (oflag & O_EXCL) && (oflag & O_CREAT)) { - openDenied = 1; + openDenied = __LINE__; yaffsfs_SetError(-EEXIST); - errorReported = 1; + errorReported = __LINE__; } /* Check file permissions */ if (readRequested && !(obj->yst_mode & S_IRUSR)) - openDenied = 1; + openDenied = __LINE__; if (writeRequested && !(obj->yst_mode & S_IWUSR)) - openDenied = 1; + openDenied = __LINE__; if (!errorReported && writeRequested && obj->my_dev->read_only) { - openDenied = 1; + openDenied = __LINE__; yaffsfs_SetError(-EROFS); - errorReported = 1; + errorReported = __LINE__; } if (openDenied && !errorReported) { yaffsfs_SetError(-EACCES); - errorReported = 1; + errorReported = __LINE__; } /* Check sharing of an existing object. */ @@ -967,9 +971,9 @@ int yaffs_open_sharing_reldir(struct yaffs_obj *reldir, const YCHAR *path, (!shareRead && alreadyReading) || (!sharedWriteAllowed && writeRequested) || (!shareWrite && alreadyWriting)) { - openDenied = 1; + openDenied = __LINE__; yaffsfs_SetError(-EBUSY); - errorReported = 1; + errorReported = __LINE__; } } @@ -983,13 +987,13 @@ int yaffs_open_sharing_reldir(struct yaffs_obj *reldir, const YCHAR *path, ¬Dir, &loop); if (!dir && notDir) { yaffsfs_SetError(-ENOTDIR); - errorReported = 1; + errorReported = __LINE__; } else if (loop) { yaffsfs_SetError(-ELOOP); - errorReported = 1; + errorReported = __LINE__; } else if (!dir) { yaffsfs_SetError(-ENOENT); - errorReported = 1; + errorReported = __LINE__; } } @@ -997,22 +1001,22 @@ int yaffs_open_sharing_reldir(struct yaffs_obj *reldir, const YCHAR *path, /* Let's see if we can create this file */ if (dir->my_dev->read_only) { yaffsfs_SetError(-EROFS); - errorReported = 1; + errorReported = __LINE__; } else if (yaffsfs_TooManyObjects(dir->my_dev)) { yaffsfs_SetError(-ENFILE); - errorReported = 1; + errorReported = __LINE__; } else obj = yaffs_create_file(dir, name, mode, 0, 0); if (!obj && !errorReported) { yaffsfs_SetError(-ENOSPC); - errorReported = 1; + errorReported = __LINE__; } } if (!obj && dir && !errorReported && !(oflag & O_CREAT)) { yaffsfs_SetError(-ENOENT); - errorReported = 1; + errorReported = __LINE__; } if (obj && !openDenied) { @@ -1045,6 +1049,9 @@ int yaffs_open_sharing_reldir(struct yaffs_obj *reldir, const YCHAR *path, if (!is_dir && (oflag & O_TRUNC) && fd->writing) yaffs_resize_file(obj, 0); } else { + if (dsc) + yaffsfs_closedir_no_lock(dsc); + dsc = NULL; yaffsfs_PutHandle(handle); if (!errorReported) yaffsfs_SetError(0); /* Problem */ @@ -1183,7 +1190,7 @@ static int yaffsfs_do_read(int handle, void *vbuf, unsigned int nbyte, /* Not a reading handle */ yaffsfs_SetError(-EINVAL); totalRead = -1; - } else if (nbyte > YAFFS_MAX_FILE_SIZE) { + } else if (nbyte > YAFFS_MAX_RW_SIZE) { yaffsfs_SetError(-EINVAL); totalRead = -1; } else { @@ -1207,7 +1214,7 @@ static int yaffsfs_do_read(int handle, void *vbuf, unsigned int nbyte, endPos = pos + nbyte; if (pos < 0 || pos > YAFFS_MAX_FILE_SIZE || - nbyte > YAFFS_MAX_FILE_SIZE || + nbyte > YAFFS_MAX_RW_SIZE || endPos < 0 || endPos > YAFFS_MAX_FILE_SIZE) { totalRead = -1; nbyte = 0; @@ -1216,7 +1223,7 @@ static int yaffsfs_do_read(int handle, void *vbuf, unsigned int nbyte, while (nbyte > 0) { nToRead = YAFFSFS_RW_SIZE - (pos & (YAFFSFS_RW_SIZE - 1)); - if (nToRead > nbyte) + if (nToRead > (int)nbyte) nToRead = nbyte; /* Tricky bit... @@ -1320,7 +1327,7 @@ static int yaffsfs_do_write(int handle, const void *vbuf, unsigned int nbyte, endPos = pos + nbyte; if (pos < 0 || pos > YAFFS_MAX_FILE_SIZE || - nbyte > YAFFS_MAX_FILE_SIZE || + nbyte > YAFFS_MAX_RW_SIZE || endPos < 0 || endPos > YAFFS_MAX_FILE_SIZE) { totalWritten = -1; nbyte = 0; @@ -1330,7 +1337,7 @@ static int yaffsfs_do_write(int handle, const void *vbuf, unsigned int nbyte, nToWrite = YAFFSFS_RW_SIZE - (pos & (YAFFSFS_RW_SIZE - 1)); - if (nToWrite > nbyte) + if (nToWrite > (int)nbyte) nToWrite = nbyte; /* Tricky bit... @@ -1601,15 +1608,12 @@ int yaffs_funlink(int fd) 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) + else if (obj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY && + !(list_empty(&obj->variant.dir_variant.children))) + yaffsfs_SetError(-ENOTEMPTY); + else if (obj == obj->my_dev->root_dir) yaffsfs_SetError(-EBUSY); /* Can't rmdir a root */ - else if (yaffs_unlink_obj(oobj) == YAFFS_OK) + else if (yaffs_unlink_obj(obj) == YAFFS_OK) retVal = 0; yaffsfs_Unlock(); @@ -1617,6 +1621,30 @@ int yaffs_funlink(int fd) return retVal; } +int yaffs_fgetfl(int fd, int *flags) +{ + struct yaffsfs_FileDes *fdp = yaffsfs_HandleToFileDes(fd); + int retVal; + + yaffsfs_Lock(); + + if(!flags || !fdp) { + yaffsfs_SetError(-EINVAL); + retVal = -1; + } else { + if (fdp->reading && fdp->writing) + *flags = O_RDWR; + else if (fdp->writing) + *flags = O_WRONLY; + else + *flags = O_RDONLY; + retVal = 0; + } + + yaffsfs_Unlock(); + return retVal; +} + static int rename_file_over_dir(struct yaffs_obj *obj, struct yaffs_obj *newobj) { @@ -1765,7 +1793,7 @@ static int yaffsfs_DoStat(struct yaffs_obj *obj, struct yaffs_stat *buf) obj = yaffs_get_equivalent_obj(obj); if (obj && buf) { - buf->st_dev = (int)obj->my_dev->os_context; + buf->st_dev = 0; buf->st_ino = obj->obj_id; buf->st_mode = obj->yst_mode & ~S_IFMT; @@ -3553,7 +3581,7 @@ struct yaffs_dirent *yaffsfs_readdir_no_lock(yaffs_DIR * dirp) if (dsc->nextReturn) { dsc->de.d_ino = yaffs_get_equivalent_obj(dsc->nextReturn)->obj_id; - dsc->de.d_dont_use = (unsigned)dsc->nextReturn; + dsc->de.d_dont_use = 0; dsc->de.d_off = dsc->offset++; yaffs_get_obj_name(dsc->nextReturn, dsc->de.d_name, NAME_MAX); @@ -3609,7 +3637,7 @@ struct yaffs_dirent *yaffs_readdir_fd(int fd) yaffsfs_Lock(); f = yaffsfs_HandleToFileDes(fd); - if(f && f->isDir) + if(f && f->isDir && f->v.dir) ret = yaffsfs_readdir_no_lock(f->v.dir); yaffsfs_Unlock(); return ret;