*** empty log message ***
[yaffs/.git] / direct / yaffsfs.c
index 8f2f06e82ff7f0cefc71a645fa3a21ee84d528ca..ec7ccf5c8b3ef2325bf30d24e4b4ebd72b520402 100644 (file)
@@ -25,7 +25,7 @@
 #endif
 
 
-const char *yaffsfs_c_version="$Id: yaffsfs.c,v 1.2 2003-01-31 00:57:35 charles Exp $";
+const char *yaffsfs_c_version="$Id: yaffsfs.c,v 1.7 2004-11-21 23:33:30 charles Exp $";
 
 // configurationList is the list of devices that are supported
 static yaffsfs_DeviceConfiguration *yaffsfs_configurationList;
@@ -180,7 +180,7 @@ static yaffs_Device *yaffsfs_FindDevice(const char *path, char **restOfPath)
                        p++;
                        leftOver++;
                }
-               if(!*p)
+               if(!*p && (!*leftOver || *leftOver == '/'))
                {
                        // Matched prefix
                        *restOfPath = (char *)leftOver;
@@ -348,6 +348,7 @@ int yaffs_open(const char *path, int oflag, int mode)
        int alreadyExclusive = 0;
        int openDenied = 0;
        int symDepth = 0;
+       int errorReported = 0;
        
        int i;
        
@@ -399,6 +400,14 @@ int yaffs_open(const char *path, int oflag, int mode)
                                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))
@@ -430,7 +439,8 @@ int yaffs_open(const char *path, int oflag, int mode)
                        }
                        else
                        {
-                       } yaffsfs_SetError(-ENOTDIR);
+                               yaffsfs_SetError(-ENOTDIR);
+                       }
                }
                
                if(obj && !openDenied)
@@ -453,7 +463,11 @@ int yaffs_open(const char *path, int oflag, int mode)
                else
                {
                        yaffsfs_PutHandle(handle);
-                       yaffsfs_SetError(-EACCESS);
+                       if(!errorReported)
+                       {
+                               yaffsfs_SetError(-EACCESS);
+                               errorReported = 1;
+                       }
                        handle = -1;
                }
                
@@ -546,7 +560,7 @@ int yaffs_read(int fd, void *buf, unsigned int nbyte)
                }
                else
                {
-                       //todo error
+                       nRead = 0;
                }
                
        }
@@ -725,27 +739,51 @@ int yaffs_rename(const char *oldPath, const char *newPath)
 {
        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);
        }
@@ -1339,5 +1377,6 @@ int yaffs_DumpDevStruct(const char *path)
                                dev->passiveGarbageCollections
                );
        }
+       return 0;
 }