summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuca Boccassi <luca.boccassi@microsoft.com>2021-07-30 15:56:11 +0100
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2022-03-30 22:31:30 +0200
commita0c0f38cb947a16a5aebf2b59fb8481866d28f96 (patch)
treecdb566c89666f62b78bd3e432140aa86b23bf67a
parent7667b84cc34707c28ca0db8d24f046ec34e8c25d (diff)
sqfs_dir_tree_destroy/sqfs_destroy: allow NULL input
Many library destructor functions (like free()) allow a NULL pointer as input, and do nothing in that case. This allows easier cleanup patterns: initialize pointers to NULL and then always pass them to the destroyer functions, no need for verbose goto/if-else patterns. Signed-off-by: Luca Boccassi <luca.boccassi@microsoft.com>
-rw-r--r--extras/extract_one.c39
-rw-r--r--include/sqfs/dir_reader.h2
-rw-r--r--include/sqfs/predef.h5
-rw-r--r--lib/sqfs/read_tree.c3
4 files changed, 23 insertions, 26 deletions
diff --git a/extras/extract_one.c b/extras/extract_one.c
index 4f5b547..fcd8124 100644
--- a/extras/extract_one.c
+++ b/extras/extract_one.c
@@ -52,7 +52,7 @@ int main(int argc, char **argv)
ret = sqfs_super_read(&super, file);
if (ret) {
fprintf(stderr, "%s: error reading super block.\n", argv[1]);
- goto out_file;
+ goto out;
}
sqfs_compressor_config_init(&cfg, super.compression_id,
@@ -62,62 +62,62 @@ int main(int argc, char **argv)
ret = sqfs_compressor_create(&cfg, &cmp);
if (ret != 0) {
fprintf(stderr, "%s: error creating compressor: %d.\n", argv[1], ret);
- goto out_file;
+ goto out;
}
if (!(super.flags & SQFS_FLAG_NO_XATTRS)) {
xattr = sqfs_xattr_reader_create(0);
if (xattr == NULL) {
fprintf(stderr, "%s: error creating xattr reader: %d.\n", argv[1], SQFS_ERROR_ALLOC);
- goto out_cmp;
+ goto out;
}
ret = sqfs_xattr_reader_load(xattr, &super, file, cmp);
if (ret) {
fprintf(stderr, "%s: error loading xattr reader: %d.\n", argv[1], ret);
- goto out_xattr;
+ goto out;
}
}
idtbl = sqfs_id_table_create(0);
if (idtbl == NULL) {
fprintf(stderr, "%s: error creating ID table: %d.\n", argv[1], ret);
- goto out_xattr;
+ goto out;
}
ret = sqfs_id_table_read(idtbl, file, &super, cmp);
if (ret) {
fprintf(stderr, "%s: error loading ID table: %d.\n", argv[1], ret);
- goto out_idtbl;
+ goto out;
}
dirrd = sqfs_dir_reader_create(&super, cmp, file, 0);
if (dirrd == NULL) {
fprintf(stderr, "%s: error creating dir reader: %d.\n", argv[1], SQFS_ERROR_ALLOC);
- goto out_idtbl;
+ goto out;
}
data = sqfs_data_reader_create(file, super.block_size, cmp, 0);
if (data == NULL) {
fprintf(stderr, "%s: error creating data reader: %d.\n", argv[1], SQFS_ERROR_ALLOC);
- goto out_dirrd;
+ goto out;
}
ret = sqfs_data_reader_load_fragment_table(data, &super);
if (ret) {
fprintf(stderr, "%s: error loading fragment table: %d.\n", argv[1], ret);
- goto out_data;
+ goto out;
}
ret = sqfs_dir_reader_get_full_hierarchy(dirrd, idtbl, argv[2], 0, &n);
if (ret) {
fprintf(stderr, "%s: error reading filesystem hierarchy: %d.\n", argv[1], ret);
- goto out_data;
+ goto out;
}
if (!S_ISREG(n->inode->base.mode)) {
fprintf(stderr, "/%s is not a file\n", argv[2]);
- goto out_tree;
+ goto out;
}
sqfs_inode_get_file_size(n->inode, &file_size);
@@ -125,7 +125,7 @@ int main(int argc, char **argv)
output = p = malloc(file_size);
if (output == NULL) {
fprintf(stderr, "malloc failed: %d\n", errno);
- goto out_tree;
+ goto out;
}
for (size_t i = 0; i < sqfs_inode_get_file_block_count(n->inode); ++i) {
@@ -135,7 +135,7 @@ int main(int argc, char **argv)
ret = sqfs_data_reader_get_block(data, n->inode, i, &chunk_size, &chunk);
if (ret) {
fprintf(stderr, "reading data block: %d\n", ret);
- goto out_tree;
+ goto out;
}
memcpy(p, chunk, chunk_size);
@@ -152,7 +152,7 @@ int main(int argc, char **argv)
ret = sqfs_data_reader_get_fragment(data, n->inode, &chunk_size, &chunk);
if (ret) {
fprintf(stderr, "reading fragment block: %d\n", ret);
- goto out_tree;
+ goto out;
}
memcpy(p, chunk, chunk_size);
@@ -163,20 +163,13 @@ int main(int argc, char **argv)
fprintf(stdout, "%s\n", (char *)output);
status = EXIT_SUCCESS;
-out_tree:
+out:
sqfs_dir_tree_destroy(n);
-out_data:
sqfs_destroy(data);
-out_dirrd:
sqfs_destroy(dirrd);
-out_idtbl:
sqfs_destroy(idtbl);
-out_xattr:
- if (xattr != NULL)
- sqfs_destroy(xattr);
-out_cmp:
+ sqfs_destroy(xattr);
sqfs_destroy(cmp);
-out_file:
sqfs_destroy(file);
free(output);
diff --git a/include/sqfs/dir_reader.h b/include/sqfs/dir_reader.h
index 3bef7e3..2ee7204 100644
--- a/include/sqfs/dir_reader.h
+++ b/include/sqfs/dir_reader.h
@@ -320,7 +320,7 @@ SQFS_API int sqfs_dir_reader_get_full_hierarchy(sqfs_dir_reader_t *rd,
* This function can be used to clean up after
* @ref sqfs_dir_reader_get_full_hierarchy.
*
- * @param root A pointer to the root node.
+ * @param root A pointer to the root node or NULL.
*/
SQFS_API void sqfs_dir_tree_destroy(sqfs_tree_node_t *root);
diff --git a/include/sqfs/predef.h b/include/sqfs/predef.h
index 6296b4b..a976cd4 100644
--- a/include/sqfs/predef.h
+++ b/include/sqfs/predef.h
@@ -133,11 +133,12 @@ typedef struct sqfs_object_t {
*
* @memberof sqfs_object_t
*
- * @param obj A pointer to an object
+ * @param obj A pointer to an object or NULL
*/
static SQFS_INLINE void sqfs_destroy(void *obj)
{
- ((sqfs_object_t *)obj)->destroy((sqfs_object_t *)obj);
+ if (obj)
+ ((sqfs_object_t *)obj)->destroy((sqfs_object_t *)obj);
}
/**
diff --git a/lib/sqfs/read_tree.c b/lib/sqfs/read_tree.c
index 802446a..feda691 100644
--- a/lib/sqfs/read_tree.c
+++ b/lib/sqfs/read_tree.c
@@ -179,6 +179,9 @@ void sqfs_dir_tree_destroy(sqfs_tree_node_t *root)
{
sqfs_tree_node_t *it;
+ if (!root)
+ return;
+
while (root->children != NULL) {
it = root->children;
root->children = it->next;