#endif
-const char *yaffsfs_c_version="$Id: yaffsfs.c,v 1.1 2003-01-21 03:32:17 charles Exp $";
+const char *yaffsfs_c_version="$Id: yaffsfs.c,v 1.8 2005-08-31 09:21:12 charles Exp $";
// configurationList is the list of devices that are supported
static yaffsfs_DeviceConfiguration *yaffsfs_configurationList;
p++;
leftOver++;
}
- if(!*p)
+ if(!*p && (!*leftOver || *leftOver == '/'))
{
// Matched prefix
*restOfPath = (char *)leftOver;
int alreadyExclusive = 0;
int openDenied = 0;
int symDepth = 0;
+ int errorReported = 0;
int i;
openDenied = 1;
}
+ // Open should fail if O_CREAT and O_EXCL are specified
+ if((oflag & O_EXCL) && (oflag & O_CREAT))
+ {
+ openDenied = 1;
+ yaffsfs_SetError(-EEXIST);
+ errorReported = 1;
+ }
+
// Check file permissions
if( (oflag & (O_RDWR | O_WRONLY)) == 0 && // ie O_RDONLY
- !(obj->st_mode & S_IREAD))
+ !(obj->yst_mode & S_IREAD))
{
openDenied = 1;
}
if( (oflag & O_RDWR) &&
- !(obj->st_mode & S_IREAD))
+ !(obj->yst_mode & S_IREAD))
{
openDenied = 1;
}
if( (oflag & (O_RDWR | O_WRONLY)) &&
- !(obj->st_mode & S_IWRITE))
+ !(obj->yst_mode & S_IWRITE))
{
openDenied = 1;
}
{
// Let's see if we can create this file
dir = yaffsfs_FindDirectory(NULL,path,&name,0);
- obj = yaffs_MknodFile(dir,name,mode,0,0);
+ if(dir)
+ {
+ obj = yaffs_MknodFile(dir,name,mode,0,0);
+ }
+ else
+ {
+ yaffsfs_SetError(-ENOTDIR);
+ }
}
if(obj && !openDenied)
else
{
yaffsfs_PutHandle(handle);
- yaffsfs_SetError(-EACCESS);
+ if(!errorReported)
+ {
+ yaffsfs_SetError(-EACCESS);
+ errorReported = 1;
+ }
handle = -1;
}
}
else
{
- //todo error
+ nRead = 0;
}
}
{
yaffs_Object *olddir = NULL;
yaffs_Object *newdir = NULL;
+ yaffs_Object *obj = NULL;
char *oldname;
char *newname;
int result= YAFFS_FAIL;
+ int renameAllowed = 1;
yaffsfs_Lock();
olddir = yaffsfs_FindDirectory(NULL,oldPath,&oldname,0);
newdir = yaffsfs_FindDirectory(NULL,newPath,&newname,0);
+ obj = yaffsfs_FindObject(NULL,oldPath,0);
- if(!olddir || !newdir)
+ if(!olddir || !newdir || !obj)
{
- // bad handle
- yaffsfs_SetError(-EBADF);
+ // bad file
+ yaffsfs_SetError(-EBADF);
+ renameAllowed = 0;
}
else if(olddir->myDev != newdir->myDev)
{
// oops must be on same device
// todo error
yaffsfs_SetError(-EXDEV);
+ renameAllowed = 0;
}
- else
+ else if(obj && obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY)
+ {
+ // It is a directory, check that it is not being renamed to
+ // being its own decendent.
+ // Do this by tracing from the new directory back to the root, checking for obj
+
+ yaffs_Object *xx = newdir;
+
+ while( renameAllowed && xx)
+ {
+ if(xx == obj)
+ {
+ renameAllowed = 0;
+ }
+ xx = xx->parent;
+ }
+ if(!renameAllowed) yaffsfs_SetError(-EACCESS);
+ }
+
+ if(renameAllowed)
{
result = yaffs_RenameObject(olddir,oldname,newdir,newname);
}
if(obj && buf)
{
- buf->st_dev = (int)obj->myDev->genericDevice;
- buf->st_ino = obj->objectId;
- buf->st_mode = obj->st_mode & ~S_IFMT; // clear out file type bits
+ buf->yst_dev = (int)obj->myDev->genericDevice;
+ buf->yst_ino = obj->objectId;
+ buf->yst_mode = obj->yst_mode & ~S_IFMT; // clear out file type bits
if(obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY)
{
- buf->st_mode |= S_IFDIR;
+ buf->yst_mode |= S_IFDIR;
}
else if(obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK)
{
- buf->st_mode |= S_IFLNK;
+ buf->yst_mode |= S_IFLNK;
}
else if(obj->variantType == YAFFS_OBJECT_TYPE_FILE)
{
- buf->st_mode |= S_IFREG;
+ buf->yst_mode |= S_IFREG;
}
- buf->st_nlink = yaffs_GetObjectLinkCount(obj);
- buf->st_uid = 0;
- buf->st_gid = 0;;
- buf->st_rdev = obj->st_rdev;
- buf->st_size = yaffs_GetObjectFileLength(obj);
- buf->st_blksize = YAFFS_BYTES_PER_CHUNK;
- buf->st_blocks = (buf->st_size + YAFFS_BYTES_PER_CHUNK -1)/YAFFS_BYTES_PER_CHUNK;
- buf->st_atime = obj->st_atime;
- buf->st_ctime = obj->st_ctime;
- buf->st_mtime = obj->st_mtime;
+ buf->yst_nlink = yaffs_GetObjectLinkCount(obj);
+ buf->yst_uid = 0;
+ buf->yst_gid = 0;;
+ buf->yst_rdev = obj->yst_rdev;
+ buf->yst_size = yaffs_GetObjectFileLength(obj);
+ buf->yst_blksize = YAFFS_BYTES_PER_CHUNK;
+ buf->yst_blocks = (buf->yst_size + YAFFS_BYTES_PER_CHUNK -1)/YAFFS_BYTES_PER_CHUNK;
+ buf->yst_atime = obj->yst_atime;
+ buf->yst_ctime = obj->yst_ctime;
+ buf->yst_mtime = obj->yst_mtime;
retVal = 0;
}
return retVal;
if(obj)
{
- obj->st_mode = mode;
+ obj->yst_mode = mode;
obj->dirty = 1;
result = yaffs_FlushFile(obj,0);
}
dev->passiveGarbageCollections
);
}
+ return 0;
}