Skip to content

Commit

Permalink
directory_iterator: return bool instead of int
Browse files Browse the repository at this point in the history
This commit changes the return type of sqsh_directory_iterator_next()
from int to bool. The return value is now used to indicate whether
there is more data to read from the directory iterator. The error code
is now stored in a pointer to an int instead of being returned directly.
  • Loading branch information
Gottox committed Aug 21, 2023
1 parent 4a098e5 commit 06f3fe9
Show file tree
Hide file tree
Showing 12 changed files with 79 additions and 41 deletions.
2 changes: 1 addition & 1 deletion examples/list_dir_ll.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ main(int argc, char *argv[]) {
return 1;
}

while ((error_code = sqsh_directory_iterator_next(iterator)) > 0) {
while (sqsh_directory_iterator_next(iterator, &error_code)) {
const char *name = sqsh_directory_iterator_name(iterator);
size_t size = sqsh_directory_iterator_name_size(iterator);
fwrite(name, size, 1, stdout);
Expand Down
2 changes: 1 addition & 1 deletion fuzzer/simple.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ LLVMFuzzerTestOneInput(char *data, size_t size) {
if (iter == NULL) {
goto out;
}
while ((rv = sqsh_directory_iterator_next(iter)) > 0) {
while (sqsh_directory_iterator_next(iter, &rv)) {
if (read_file(iter) < 0)
break;
}
Expand Down
10 changes: 6 additions & 4 deletions include/sqsh_directory.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,14 @@ sqsh_directory_iterator_new(struct SqshFile *file, int *err);
* @brief Advances the iterator to the next entry.
*
* @param[in,out] iterator The iterator to advance.
* @param[out] err Pointer to an int where the error code will be
* stored.
*
* @return amount of bytes available in the current block on success, 0 if the
* end of the directory has been reached, a negative value on error.
* @retval true if the iterator has been advanced
* @retval false if the iterator has reached the end of the directory
*/
SQSH_NO_UNUSED int
sqsh_directory_iterator_next(struct SqshDirectoryIterator *iterator);
SQSH_NO_UNUSED bool
sqsh_directory_iterator_next(struct SqshDirectoryIterator *iterator, int *err);

/**
* @memberof SqshDirectoryIterator
Expand Down
34 changes: 23 additions & 11 deletions lib/directory/directory_iterator.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ sqsh_directory_iterator_lookup(
}
}

while (sqsh_directory_iterator_next(iterator) > 0) {
while (sqsh_directory_iterator_next(iterator, &rv) > 0) {
const size_t entry_name_size =
sqsh_directory_iterator_name_size(iterator);
const char *entry_name = sqsh_directory_iterator_name(iterator);
Expand All @@ -170,7 +170,11 @@ sqsh_directory_iterator_lookup(
}
}

return -SQSH_ERROR_NO_SUCH_FILE;
if (rv < 0) {
return rv;
} else {
return -SQSH_ERROR_NO_SUCH_FILE;
}
}

int
Expand Down Expand Up @@ -301,18 +305,19 @@ process_fragment(struct SqshDirectoryIterator *iterator) {
return rv;
}

int
sqsh_directory_iterator_next(struct SqshDirectoryIterator *iterator) {
bool
sqsh_directory_iterator_next(struct SqshDirectoryIterator *iterator, int *err) {
int rv = 0;
size_t size;
bool has_next = false;

if (iterator->remaining_size == 0) {
return 0;
goto out;
} else if (iterator->remaining_entries == 0) {
/* New fragment begins */
rv = process_fragment(iterator);
if (rv < 0) {
return rv;
goto out;
}
}

Expand All @@ -323,19 +328,20 @@ sqsh_directory_iterator_next(struct SqshDirectoryIterator *iterator) {
rv = sqsh__metablock_reader_advance(
&iterator->metablock, iterator->next_offset, size);
if (rv < 0) {
return rv;
goto out;
}

/* Make sure next entry has its name populated */
if (SQSH_ADD_OVERFLOW(
size, sqsh_directory_iterator_name_size(iterator), &size)) {
return -SQSH_ERROR_INTEGER_OVERFLOW;
rv = -SQSH_ERROR_INTEGER_OVERFLOW;
goto out;
}
/* May invalidate pointers into directory entries. that's why the */
/* get_entry() call is repeated below. */
rv = sqsh__metablock_reader_advance(&iterator->metablock, 0, size);
if (rv < 0) {
return rv;
goto out;
}

iterator->next_offset = size;
Expand All @@ -345,9 +351,15 @@ sqsh_directory_iterator_next(struct SqshDirectoryIterator *iterator) {
}
rv = check_consistency(iterator);
if (rv < 0) {
return rv;
goto out;
}

has_next = true;
out:
if (err != NULL) {
*err = rv;
}
return 1;
return has_next;
}

const char *
Expand Down
2 changes: 1 addition & 1 deletion lib/easy/directory.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ sqsh_easy_directory_list(
goto out;
}

while ((rv = sqsh_directory_iterator_next(iterator)) > 0) {
while (sqsh_directory_iterator_next(iterator, &rv)) {
const char *name = sqsh_directory_iterator_name(iterator);
size_t name_len = sqsh_directory_iterator_name_size(iterator);
size_t index = sqsh__buffer_size(&dir_list_names);
Expand Down
10 changes: 8 additions & 2 deletions lib/tree/walker.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,13 +172,19 @@ sqsh_tree_walker_up(struct SqshTreeWalker *walker) {
int
sqsh_tree_walker_next(struct SqshTreeWalker *walker) {
struct SqshDirectoryIterator *iterator = &walker->iterator;
int rv = sqsh_directory_iterator_next(iterator);
int rv = 0;
walker->begin_iterator = false;

bool has_next = sqsh_directory_iterator_next(iterator, &rv);
if (rv < 0) {
return rv;
}

return update_inode_from_iterator(walker);
if (has_next == false) {
return 0;
} else {
return update_inode_from_iterator(walker);
}
}

enum SqshFileType
Expand Down
16 changes: 10 additions & 6 deletions test/directory/directory_iterator.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,9 @@ iter_invalid_file_name_with_0(void) {
rv = sqsh__directory_iterator_init(&iter, &file);
assert(rv == 0);

rv = sqsh_directory_iterator_next(&iter);
bool has_next = sqsh_directory_iterator_next(&iter, &rv);
assert(rv == -SQSH_ERROR_CORRUPTED_DIRECTORY_ENTRY);
assert(has_next == false);

sqsh__directory_iterator_cleanup(&iter);
sqsh__file_cleanup(&file);
Expand Down Expand Up @@ -105,8 +106,9 @@ iter_invalid_file_name_with_slash(void) {
rv = sqsh__directory_iterator_init(&iter, &file);
assert(rv == 0);

rv = sqsh_directory_iterator_next(&iter);
bool has_next = sqsh_directory_iterator_next(&iter, &rv);
assert(rv == -SQSH_ERROR_CORRUPTED_DIRECTORY_ENTRY);
assert(has_next == false);

sqsh__directory_iterator_cleanup(&iter);
sqsh__file_cleanup(&file);
Expand Down Expand Up @@ -150,16 +152,18 @@ iter_two_files(void) {
rv = sqsh__directory_iterator_init(&iter, &file);
assert(rv == 0);

rv = sqsh_directory_iterator_next(&iter);
assert(rv > 0);
bool has_next = sqsh_directory_iterator_next(&iter, &rv);
assert(rv == 0);
assert(has_next == true);

const char *name = sqsh_directory_iterator_name(&iter);
size_t size = sqsh_directory_iterator_name_size(&iter);
assert(size == 1);
assert(name[0] == '1');

rv = sqsh_directory_iterator_next(&iter);
assert(rv > 0);
has_next = sqsh_directory_iterator_next(&iter, &rv);
assert(rv == 0);
assert(has_next == true);

name = sqsh_directory_iterator_name(&iter);
size = sqsh_directory_iterator_name_size(&iter);
Expand Down
18 changes: 11 additions & 7 deletions test/integration.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,30 +136,34 @@ sqsh_ls(void) {
assert(iter != NULL);
assert(rv == 0);

rv = sqsh_directory_iterator_next(iter);
assert(rv > 0);
bool has_next = sqsh_directory_iterator_next(iter, &rv);
assert(rv == 0);
assert(has_next);
name = sqsh_directory_iterator_name_dup(iter);
assert(name != NULL);
assert(strcmp("a", name) == 0);
free(name);

rv = sqsh_directory_iterator_next(iter);
has_next = sqsh_directory_iterator_next(iter, &rv);
assert(rv >= 0);
assert(has_next == true);
name = sqsh_directory_iterator_name_dup(iter);
assert(name != NULL);
assert(strcmp("b", name) == 0);
free(name);

rv = sqsh_directory_iterator_next(iter);
assert(rv >= 0);
has_next = sqsh_directory_iterator_next(iter, &rv);
assert(rv == 0);
assert(has_next == true);
name = sqsh_directory_iterator_name_dup(iter);
assert(name != NULL);
assert(strcmp("large_dir", name) == 0);
free(name);

rv = sqsh_directory_iterator_next(iter);
has_next = sqsh_directory_iterator_next(iter, &rv);
// End of file list
assert(rv == 0);
assert(has_next == false);

rv = sqsh_directory_iterator_free(iter);
assert(rv == 0);
Expand Down Expand Up @@ -529,7 +533,7 @@ multithreaded_walker(void *arg) {
if (sqsh_file_type(file) == SQSH_FILE_TYPE_DIRECTORY) {
struct SqshDirectoryIterator *iter =
sqsh_directory_iterator_new(file, &rv);
while (sqsh_directory_iterator_next(iter) > 0) {
while (sqsh_directory_iterator_next(iter, &rv) > 0) {
multithreaded_walker(&my_walker);
}
sqsh_directory_iterator_free(iter);
Expand Down
7 changes: 5 additions & 2 deletions tools/fs2.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,15 @@ fs_readdir(
}
filler(buf, ".", NULL, 0);
filler(buf, "..", NULL, 0);
while ((rv = sqsh_directory_iterator_next(iterator)) > 0) {
while (sqsh_directory_iterator_next(iterator, &rv)) {
rv = fs_readdir_item(buf, iterator, filler);
if (rv < 0) {
goto out;
break;
}
}
if (rv < 0) {
goto out;
}

out:
sqsh_directory_iterator_free(iterator);
Expand Down
4 changes: 2 additions & 2 deletions tools/fs3.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,11 +261,11 @@ fs_readdir(
struct FsDirHandle *handle = get_dir_handle(fi);
char buf[size];

rv = sqsh_directory_iterator_next(handle->iterator);
bool has_next = sqsh_directory_iterator_next(handle->iterator, &rv);
if (rv < 0) {
fuse_reply_err(req, -fs_common_map_err(rv));
goto out;
} else if (rv == 0) {
} else if (has_next == false) {
fuse_reply_buf(req, NULL, 0);
goto out;
}
Expand Down
9 changes: 6 additions & 3 deletions tools/ls.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,13 +201,16 @@ ls(struct SqshArchive *archive, const char *path, struct SqshFile *file) {
goto out;
}

while (sqsh_directory_iterator_next(iter) > 0) {
while (sqsh_directory_iterator_next(iter, &rv)) {
rv = ls_item(archive, path, iter);
if (rv < 0) {
rv = EXIT_FAILURE;
goto out;
break;
}
}
if (rv < 0) {
rv = EXIT_FAILURE;
goto out;
}

out:
sqsh_directory_iterator_free(iter);
Expand Down
6 changes: 5 additions & 1 deletion tools/unpack.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,17 @@ extract_directory(
goto out;
}

while (sqsh_directory_iterator_next(iter) > 0) {
while (sqsh_directory_iterator_next(iter, &rv)) {
rv = extract_directory_entry(iter, path_stack);
// Don't stop on error, but continue with next entry.
/*if (rv < 0) {
goto out;
}*/
}
if (rv < 0) {
print_err(rv, "sqsh_directory_iterator_next", path_stack);
goto out;
}

rv = chdir(cwd);
if (rv < 0) {
Expand Down

0 comments on commit 06f3fe9

Please sign in to comment.