X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=direct%2Fyaffsfs.c;h=3ee5f0c8644a9449b6ae3776533bd747c7cee6b5;hp=f95c19906ac7f6cde771177700eacab25e7d01e9;hb=62003e4e28d993ae2182cb45276bc305ee656ce4;hpb=41573908f821bcb40750e7c069ea8f5178f630e5 diff --git a/direct/yaffsfs.c b/direct/yaffsfs.c index f95c199..3ee5f0c 100644 --- a/direct/yaffsfs.c +++ b/direct/yaffsfs.c @@ -571,6 +571,8 @@ int yaffs_dup(int fd) } + + int yaffs_open_sharing(const YCHAR *path, int oflag, int mode, int sharing) { yaffs_obj_t *obj = NULL; @@ -581,6 +583,7 @@ int yaffs_open_sharing(const YCHAR *path, int oflag, int mode, int sharing) int openDenied = 0; int symDepth = 0; int errorReported = 0; + int rwflags = oflag & ( O_RDWR | O_RDONLY | O_WRONLY); __u8 shareRead = (sharing & YAFFS_SHARE_READ) ? 1 : 0; __u8 shareWrite = (sharing & YAFFS_SHARE_WRITE) ? 1 : 0; __u8 sharedReadAllowed; @@ -600,12 +603,19 @@ int yaffs_open_sharing(const YCHAR *path, int oflag, int mode, int sharing) /* Todo: Are there any more flag combos to sanitise ? */ + /* Figure out if reading or writing is requested */ + + readRequested = (rwflags == O_RDWR || rwflags == O_RDONLY) ? 1 : 0; + writeRequested = (rwflags == O_RDWR || rwflags == O_WRONLY) ? 1 : 0; yaffsfs_Lock(); handle = yaffsfs_GetNewHandle(); - if(handle >= 0){ + if(handle < 0){ + yaffsfs_SetError(-ENFILE); + errorReported = 1; + } else { yh = yaffsfs_GetHandlePointer(handle); @@ -640,16 +650,10 @@ int yaffs_open_sharing(const YCHAR *path, int oflag, int mode, int sharing) } /* Check file permissions */ - if( (oflag & (O_RDWR | O_WRONLY)) == 0 && /* ie O_RDONLY */ - !(obj->yst_mode & S_IREAD)) - openDenied = 1; - - if( (oflag & O_RDWR) && - !(obj->yst_mode & S_IREAD)) + if( readRequested && !(obj->yst_mode & S_IREAD)) openDenied = 1; - if( (oflag & (O_RDWR | O_WRONLY)) && - !(obj->yst_mode & S_IWRITE)) + if( writeRequested && !(obj->yst_mode & S_IWRITE)) openDenied = 1; /* Check sharing of an existing object. */ @@ -672,12 +676,11 @@ int yaffs_open_sharing(const YCHAR *path, int oflag, int mode, int sharing) if(hx->reading) alreadyReading = 1; if(hx->writing) - alreadyWriting = 0; + alreadyWriting = 1; } } - readRequested = (oflag & (O_RDWR | O_RDONLY)) ? 1 : 0; - writeRequested = (oflag & (O_RDWR | O_WRONLY)) ? 1 : 0; + if((!sharedReadAllowed && readRequested)|| (!shareRead && alreadyReading) || @@ -714,8 +717,8 @@ int yaffs_open_sharing(const YCHAR *path, int oflag, int mode, int sharing) } yh->inodeId = inodeId; - yh->reading = (oflag & (O_RDONLY | O_RDWR)) ? 1 : 0; - yh->writing = (oflag & (O_WRONLY | O_RDWR)) ? 1 : 0; + yh->reading = readRequested; + yh->writing = writeRequested; yh->append = (oflag & O_APPEND) ? 1 : 0; yh->position = 0; yh->shareRead = shareRead; @@ -831,7 +834,11 @@ int yaffsfs_do_read(int fd, void *vbuf, unsigned int nbyte, int isPread, int off /* bad handle */ yaffsfs_SetError(-EBADF); totalRead = -1; - } else if( h && obj){ + } else if(!h->reading){ + /* Not a reading handle */ + yaffsfs_SetError(-EINVAL); + totalRead = -1; + } else { if(isPread) startPos = offset; else @@ -926,7 +933,7 @@ int yaffsfs_do_write(int fd, const void *vbuf, unsigned int nbyte, int isPwrite, } else if( h && obj && (!h->writing || obj->my_dev->read_only)){ yaffsfs_SetError(-EINVAL); totalWritten=-1; - } else if( h && obj){ + } else { if(h->append) startPos = yaffs_get_obj_length(obj); else if(isPwrite) @@ -1051,30 +1058,28 @@ off_t yaffs_lseek(int fd, off_t offset, int whence) h = yaffsfs_GetHandlePointer(fd); obj = yaffsfs_GetHandleObject(fd); - if(!h || !obj) + if(!h || !obj){ /* bad handle */ yaffsfs_SetError(-EBADF); - else if(whence == SEEK_SET){ - if(offset >= 0) - pos = offset; - } - else if(whence == SEEK_CUR) { - if( (h->position + offset) >= 0) - pos = (h->position + offset); - } - else if(whence == SEEK_END) { - fSize = yaffs_get_obj_length(obj); - if(fSize >= 0 && (fSize + offset) >= 0) - pos = fSize + offset; - } - - if(pos >= 0) - h->position = pos; - else { - /* todo error */ + } else { + if(whence == SEEK_SET){ + if(offset >= 0) + pos = offset; + } else if(whence == SEEK_CUR) { + if( (h->position + offset) >= 0) + pos = (h->position + offset); + } else if(whence == SEEK_END) { + fSize = yaffs_get_obj_length(obj); + if(fSize >= 0 && (fSize + offset) >= 0) + pos = fSize + offset; + } + + if(pos >= 0) + h->position = pos; + else + yaffsfs_SetError(-EINVAL); } - yaffsfs_Unlock(); return pos; @@ -1723,8 +1728,40 @@ int yaffs_mkdir(const YCHAR *path, mode_t mode) yaffs_obj_t *parent = NULL; yaffs_obj_t *dir = NULL; YCHAR *name; + YCHAR *use_path = NULL; + int path_length = 0; int retVal= -1; + int i; + + + /* + * We don't have a definition for max path length. + * We will use 3 * max name length instead. + */ + + path_length = strnlen(path,(YAFFS_MAX_NAME_LENGTH+1)*3 +1); + /* If the last character is a path divider, then we need to + * trim it back so that the name look-up works properly. + * eg. /foo/new_dir/ -> /foo/newdir + * Curveball: Need to handle multiple path dividers: + * eg. /foof/sdfse///// -> /foo/sdfse + */ + if(path_length > 0 && + yaffsfs_IsPathDivider(path[path_length-1])){ + use_path = YMALLOC(path_length + 1); + if(!use_path){ + yaffsfs_SetError(-ENOMEM); + return -1; + } + strcpy(use_path, path); + for(i = path_length-1; + i >= 0 && yaffsfs_IsPathDivider(use_path[i]); + i--) + use_path[i] = (YCHAR) 0; + path = use_path; + } + yaffsfs_Lock(); parent = yaffsfs_FindDirectory(NULL,path,&name,0); if(parent && yaffs_strnlen(name,5) == 0){ @@ -1750,6 +1787,9 @@ int yaffs_mkdir(const YCHAR *path, mode_t mode) yaffsfs_Unlock(); + if(use_path) + YFREE(use_path); + return retVal; } @@ -2326,6 +2366,11 @@ int yaffs_n_handles(const YCHAR *path) return yaffsfs_CountHandles(obj); } +int yaffs_get_error(void) +{ + return yaffsfs_GetLastError(); +} + int yaffs_dump_dev(const YCHAR *path) { #if 0