diff --git a/fs/tmpfs/fs_tmpfs.c b/fs/tmpfs/fs_tmpfs.c index a360c6ea76..a60d70c8fe 100644 --- a/fs/tmpfs/fs_tmpfs.c +++ b/fs/tmpfs/fs_tmpfs.c @@ -83,7 +83,7 @@ static int tmpfs_realloc_file(FAR struct tmpfs_file_s *tfo, static void tmpfs_release_lockedobject(FAR struct tmpfs_object_s *to); static void tmpfs_release_lockedfile(FAR struct tmpfs_file_s *tfo); static int tmpfs_find_dirent(FAR struct tmpfs_directory_s *tdo, - FAR const char *name); + FAR const char *name, size_t len); static int tmpfs_remove_dirent(FAR struct tmpfs_directory_s *tdo, FAR const char *name); static int tmpfs_add_dirent(FAR struct tmpfs_directory_s *tdo, @@ -95,14 +95,15 @@ static FAR struct tmpfs_directory_s *tmpfs_alloc_directory(void); static int tmpfs_create_directory(FAR struct tmpfs_s *fs, FAR const char *relpath, FAR struct tmpfs_directory_s **tdo); static int tmpfs_find_object(FAR struct tmpfs_s *fs, - FAR const char *relpath, FAR struct tmpfs_object_s **object, + FAR const char *relpath, size_t len, + FAR struct tmpfs_object_s **object, FAR struct tmpfs_directory_s **parent); static int tmpfs_find_file(FAR struct tmpfs_s *fs, FAR const char *relpath, FAR struct tmpfs_file_s **tfo, FAR struct tmpfs_directory_s **parent); static int tmpfs_find_directory(FAR struct tmpfs_s *fs, - FAR const char *relpath, + FAR const char *relpath, size_t len, FAR struct tmpfs_directory_s **tdo, FAR struct tmpfs_directory_s **parent); static int tmpfs_statfs_callout(FAR struct tmpfs_directory_s *tdo, @@ -450,7 +451,7 @@ static void tmpfs_release_lockedfile(FAR struct tmpfs_file_s *tfo) ****************************************************************************/ static int tmpfs_find_dirent(FAR struct tmpfs_directory_s *tdo, - FAR const char *name) + FAR const char *name, size_t len) { int i; @@ -458,7 +459,8 @@ static int tmpfs_find_dirent(FAR struct tmpfs_directory_s *tdo, for (i = 0; i < tdo->tdo_nentries && - strcmp(tdo->tdo_entry[i].tde_name, name) != 0; + (strncmp(tdo->tdo_entry[i].tde_name, name, len) != 0 || + tdo->tdo_entry[i].tde_name[len] != 0); i++); /* Return what we found, if anything */ @@ -478,7 +480,7 @@ static int tmpfs_remove_dirent(FAR struct tmpfs_directory_s *tdo, /* Search the list of directory entries for a match */ - index = tmpfs_find_dirent(tdo, name); + index = tmpfs_find_dirent(tdo, name, strlen(name)); if (index < 0) { return index; @@ -594,28 +596,19 @@ static int tmpfs_create_file(FAR struct tmpfs_s *fs, { FAR struct tmpfs_directory_s *parent; FAR struct tmpfs_file_s *newtfo; - FAR char *copy; - FAR char *name; + FAR const char *name; int ret; - /* Duplicate the path variable so that we can modify it */ - - copy = strdup(relpath); - if (copy == NULL) - { - return -ENOMEM; - } - /* Separate the path into the file name and the path to the parent * directory. */ - name = strrchr(copy, '/'); + name = strrchr(relpath, '/'); if (name == NULL) { /* No subdirectories... use the root directory */ - name = copy; + name = relpath; parent = (FAR struct tmpfs_directory_s *)fs->tfs_root.tde_object; /* Lock the root directory to emulate the behavior of @@ -625,7 +618,6 @@ static int tmpfs_create_file(FAR struct tmpfs_s *fs, ret = tmpfs_lock_directory(parent); if (ret < 0) { - kmm_free(copy); return ret; } @@ -633,25 +625,25 @@ static int tmpfs_create_file(FAR struct tmpfs_s *fs, } else { - /* Terminate the parent directory path */ - - *name++ = '\0'; - /* Locate the parent directory that should contain this name. * On success, tmpfs_find_directory() will lock the parent * directory and increment the reference count. */ - ret = tmpfs_find_directory(fs, copy, &parent, NULL); + ret = tmpfs_find_directory(fs, relpath, name - relpath, &parent, NULL); if (ret < 0) { - goto errout_with_copy; + return ret; } + + /* Skip the '/' path separator */ + + name++; } /* Verify that no object of this name already exists in the directory */ - ret = tmpfs_find_dirent(parent, name); + ret = tmpfs_find_dirent(parent, name, strlen(name)); if (ret != -ENOENT) { /* Something with this name already exists in the directory. @@ -690,9 +682,8 @@ static int tmpfs_create_file(FAR struct tmpfs_s *fs, parent->tdo_refs--; tmpfs_unlock_directory(parent); - /* Free the copy of the relpath and return success */ + /* Return success */ - kmm_free(copy); *tfo = newtfo; return OK; @@ -705,9 +696,6 @@ errout_with_file: errout_with_parent: parent->tdo_refs--; tmpfs_unlock_directory(parent); - -errout_with_copy: - kmm_free(copy); return ret; } @@ -752,34 +740,24 @@ static int tmpfs_create_directory(FAR struct tmpfs_s *fs, { FAR struct tmpfs_directory_s *parent; FAR struct tmpfs_directory_s *newtdo; - FAR char *copy; - FAR char *name; + FAR const char *name; int ret; - /* Duplicate the path variable so that we can modify it */ - - copy = strdup(relpath); - if (copy == NULL) - { - return -ENOMEM; - } - /* Separate the path into the file name and the path to the parent * directory. */ - name = strrchr(copy, '/'); + name = strrchr(relpath, '/'); if (name == NULL) { /* No subdirectories... use the root directory */ - name = copy; + name = relpath; parent = (FAR struct tmpfs_directory_s *)fs->tfs_root.tde_object; ret = tmpfs_lock_directory(parent); if (ret < 0) { - kmm_free(copy); return ret; } @@ -787,25 +765,25 @@ static int tmpfs_create_directory(FAR struct tmpfs_s *fs, } else { - /* Terminate the parent directory path */ - - *name++ = '\0'; - /* Locate the parent directory that should contain this name. * On success, tmpfs_find_directory() will lockthe parent * directory and increment the reference count. */ - ret = tmpfs_find_directory(fs, copy, &parent, NULL); + ret = tmpfs_find_directory(fs, relpath, name - relpath, &parent, NULL); if (ret < 0) { - goto errout_with_copy; + return ret; } + + /* Skip the '/' path separator */ + + name++; } /* Verify that no object of this name already exists in the directory */ - ret = tmpfs_find_dirent(parent, name); + ret = tmpfs_find_dirent(parent, name, strlen(name)); if (ret != -ENOENT) { /* Something with this name already exists in the directory. @@ -845,7 +823,6 @@ static int tmpfs_create_directory(FAR struct tmpfs_s *fs, parent->tdo_refs--; tmpfs_unlock_directory(parent); - kmm_free(copy); /* Return the (unlocked, unreferenced) directory object to the caller */ @@ -865,9 +842,6 @@ errout_with_directory: errout_with_parent: parent->tdo_refs--; tmpfs_unlock_directory(parent); - -errout_with_copy: - kmm_free(copy); return ret; } @@ -876,43 +850,40 @@ errout_with_copy: ****************************************************************************/ static int tmpfs_find_object(FAR struct tmpfs_s *fs, - FAR const char *relpath, + FAR const char *relpath, size_t len, FAR struct tmpfs_object_s **object, FAR struct tmpfs_directory_s **parent) { FAR struct tmpfs_object_s *to = NULL; FAR struct tmpfs_directory_s *tdo = NULL; FAR struct tmpfs_directory_s *next_tdo; - FAR char *segment; - FAR char *next_segment; - FAR char *tkptr; - FAR char *copy; + FAR const char *segment; + FAR const char *next_segment; int index; int ret; - /* Make a copy of the path (so that we can modify it via strtok) */ - - copy = strdup(relpath); - if (copy == NULL) - { - return -ENOMEM; - } - /* Traverse the file system for any object with the matching name */ to = fs->tfs_root.tde_object; next_tdo = (FAR struct tmpfs_directory_s *)fs->tfs_root.tde_object; - for (segment = strtok_r(copy, "/", &tkptr); - segment != NULL; - segment = next_segment) + for (segment = relpath; len != 0; segment = next_segment + 1) { /* Get the next segment after the one we are currently working on. * This will be NULL is we are working on the final segment of the * relpath. */ - next_segment = strtok_r(NULL, "/", &tkptr); + next_segment = memchr(segment, '/', len); + if (next_segment) + { + len -= next_segment + 1 - segment; + } + else + { + next_segment = segment + len; + len = 0; + } /* Search the next directory. */ @@ -922,12 +893,11 @@ static int tmpfs_find_object(FAR struct tmpfs_s *fs, * directory. */ - index = tmpfs_find_dirent(tdo, segment); + index = tmpfs_find_dirent(tdo, segment, next_segment - segment); if (index < 0) { /* No object with this name exists in the directory. */ - kmm_free(copy); return index; } @@ -939,7 +909,7 @@ static int tmpfs_find_object(FAR struct tmpfs_s *fs, { /* No. Was this the final segment in the path? */ - if (next_segment == NULL) + if (len == 0) { /* Then we can break out of the loop now */ @@ -951,7 +921,6 @@ static int tmpfs_find_object(FAR struct tmpfs_s *fs, * segments do no correspond to directories. */ - kmm_free(copy); return -ENOTDIR; } @@ -968,10 +937,6 @@ static int tmpfs_find_object(FAR struct tmpfs_s *fs, * Increment the reference count on the located object. */ - /* Free the dup'ed string */ - - kmm_free(copy); - /* Return what we found */ if (parent) @@ -1034,7 +999,7 @@ static int tmpfs_find_file(FAR struct tmpfs_s *fs, * reference count on both. */ - ret = tmpfs_find_object(fs, relpath, &to, parent); + ret = tmpfs_find_object(fs, relpath, strlen(relpath), &to, parent); if (ret >= 0) { /* We found it... but is it a regular file? */ @@ -1069,7 +1034,7 @@ static int tmpfs_find_file(FAR struct tmpfs_s *fs, ****************************************************************************/ static int tmpfs_find_directory(FAR struct tmpfs_s *fs, - FAR const char *relpath, + FAR const char *relpath, size_t len, FAR struct tmpfs_directory_s **tdo, FAR struct tmpfs_directory_s **parent) { @@ -1078,7 +1043,7 @@ static int tmpfs_find_directory(FAR struct tmpfs_s *fs, /* Find the object at this path */ - ret = tmpfs_find_object(fs, relpath, &to, parent); + ret = tmpfs_find_object(fs, relpath, len, &to, parent); if (ret >= 0) { /* We found it... but is it a regular file? */ @@ -1907,7 +1872,7 @@ static int tmpfs_opendir(FAR struct inode *mountpt, FAR const char *relpath, * lock on the returned directory. */ - ret = tmpfs_find_directory(fs, relpath, &tdo, NULL); + ret = tmpfs_find_directory(fs, relpath, strlen(relpath), &tdo, NULL); if (ret >= 0) { dir->u.tmpfs.tf_tdo = tdo; @@ -2377,7 +2342,7 @@ static int tmpfs_rmdir(FAR struct inode *mountpt, FAR const char *relpath) * on each. */ - ret = tmpfs_find_directory(fs, relpath, &tdo, &parent); + ret = tmpfs_find_directory(fs, relpath, strlen(relpath), &tdo, &parent); if (ret < 0) { goto errout_with_lock; @@ -2458,8 +2423,7 @@ static int tmpfs_rename(FAR struct inode *mountpt, FAR struct tmpfs_object_s *to; FAR struct tmpfs_s *fs; FAR const char *oldname; - FAR char *newname; - FAR char *copy; + FAR const char *newname; int ret; finfo("mountpt: %p oldrelpath: %s newrelpath: %s\n", @@ -2471,20 +2435,11 @@ static int tmpfs_rename(FAR struct inode *mountpt, fs = mountpt->i_private; DEBUGASSERT(fs != NULL && fs->tfs_root.tde_object != NULL); - /* Duplicate the newpath variable so that we can modify it */ - - copy = strdup(newrelpath); - if (copy == NULL) - { - return -ENOMEM; - } - /* Get exclusive access to the file system */ ret = tmpfs_lock(fs); if (ret < 0) { - kmm_free(copy); return ret; } @@ -2492,12 +2447,12 @@ static int tmpfs_rename(FAR struct inode *mountpt, * parent directory. */ - newname = strrchr(copy, '/'); + newname = strrchr(newrelpath, '/'); if (newname == NULL) { /* No subdirectories... use the root directory */ - newname = copy; + newname = newrelpath; newparent = (FAR struct tmpfs_directory_s *)fs->tfs_root.tde_object; tmpfs_lock_directory(newparent); @@ -2505,27 +2460,28 @@ static int tmpfs_rename(FAR struct inode *mountpt, } else { - /* Terminate the parent directory path */ - - *newname++ = '\0'; - /* Locate the parent directory that should contain this name. * On success, tmpfs_find_directory() will lockthe parent * directory and increment the reference count. */ - ret = tmpfs_find_directory(fs, copy, &newparent, NULL); + ret = tmpfs_find_directory(fs, newrelpath, newname - newrelpath, + &newparent, NULL); if (ret < 0) { goto errout_with_lock; } + + /* Skip the '/' path separator */ + + newname++; } /* Verify that no object of this name already exists in the destination * directory. */ - ret = tmpfs_find_dirent(newparent, newname); + ret = tmpfs_find_dirent(newparent, newname, strlen(newname)); if (ret != -ENOENT) { /* Something with this name already exists in the directory. @@ -2545,7 +2501,8 @@ static int tmpfs_rename(FAR struct inode *mountpt, * the reference count on both. */ - ret = tmpfs_find_object(fs, oldrelpath, &to, &oldparent); + ret = tmpfs_find_object(fs, oldrelpath, strlen(oldrelpath), + &to, &oldparent); if (ret < 0) { goto errout_with_newparent; @@ -2591,7 +2548,6 @@ errout_with_newparent: errout_with_lock: tmpfs_unlock(fs); - kmm_free(copy); return ret; } @@ -2675,7 +2631,7 @@ static int tmpfs_stat(FAR struct inode *mountpt, FAR const char *relpath, * reference count on the object. */ - ret = tmpfs_find_object(fs, relpath, &to, NULL); + ret = tmpfs_find_object(fs, relpath, strlen(relpath), &to, NULL); if (ret < 0) { goto errout_with_fslock;