Skip to content

Commit

Permalink
[C] add and use aeron_mkdir_recursive (#1602)
Browse files Browse the repository at this point in the history
* [C] add and use aeron_mkdir_recursive

* [C] switch mode_t to int for windows

* [C] error handling

* [C] fix windows build
  • Loading branch information
nbradac committed May 26, 2024
1 parent a3bfb6d commit 98b9cf3
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 3 deletions.
48 changes: 48 additions & 0 deletions aeron-client/src/main/c/util/aeron_fileutil.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,54 @@ int aeron_open_file_rw(const char *path)
}
#endif

int aeron_mkdir_recursive(const char *pathname, int permission)
{
if (aeron_mkdir(pathname, permission) == 0)
{
return 0;
}

if (errno != ENOENT)
{
AERON_SET_ERR(errno, "aeron_mkdir failed for %s", pathname);
return -1;
}

char *_pathname = strdup(pathname);
char *p;

for (p = _pathname + strlen(_pathname) - 1; p != _pathname; p--)
{
if (*p == AERON_FILE_SEP)
{
*p = '\0';

// _pathname is now the parent directory of the original pathname
int rc = aeron_mkdir_recursive(_pathname, permission);

free(_pathname);

if (0 == rc)
{
// if rc is 0, then we were able to create the parent directory
// so retry the original pathname
return aeron_mkdir(pathname, permission);
}
else
{
AERON_APPEND_ERR("pathname=%s", pathname);
return rc;
}
}
}

free(_pathname);

AERON_SET_ERR(EINVAL, "aeron_mkdir_recursive failed to find parent directory in %s", pathname);

return -1;
}

#include <inttypes.h>

#define AERON_BLOCK_SIZE (4 * 1024)
Expand Down
1 change: 1 addition & 0 deletions aeron-client/src/main/c/util/aeron_fileutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ aeron_mapped_buffer_t;

int aeron_is_directory(const char *path);
int aeron_delete_directory(const char *directory);
int aeron_mkdir_recursive(const char *pathname, int permission);

int aeron_map_new_file(aeron_mapped_file_t *mapped_file, const char *path, bool fill_with_zeroes);
int aeron_map_existing_file(aeron_mapped_file_t *mapped_file, const char *path);
Expand Down
46 changes: 46 additions & 0 deletions aeron-client/src/test/c/util/aeron_fileutil_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@ extern "C"
#include "util/aeron_error.h"
}

#if defined(AERON_COMPILER_GCC)
#define removeDir remove
#elif defined(AERON_COMPILER_MSVC)
#define removeDir RemoveDirectoryA
#endif

#ifdef _MSC_VER
#define AERON_FILE_SEP_STR "\\"
#else
#define AERON_FILE_SEP_STR "/"
#endif

class FileUtilTest : public testing::Test {
public:
FileUtilTest() = default;
Expand Down Expand Up @@ -324,3 +336,37 @@ TEST_F(FileUtilTest, shouldNotErrorIfAddressIsNull)
{
ASSERT_EQ(0, aeron_msync(nullptr, 10));
}

TEST_F(FileUtilTest, simpleMkdir)
{
const char *dirA = "dirA";
const char *dirB = "dirA" AERON_FILE_SEP_STR "dirB";
const char *dirC = "dirA" AERON_FILE_SEP_STR "dirNOPE" AERON_FILE_SEP_STR "dirC";

removeDir("dirA" AERON_FILE_SEP_STR "dirNOPE" AERON_FILE_SEP_STR "dirC");
removeDir("dirA" AERON_FILE_SEP_STR "dirNOPE");
removeDir("dirA" AERON_FILE_SEP_STR "dirB");
removeDir("dirA");

ASSERT_EQ(0, aeron_mkdir(dirA, S_IRWXU | S_IRWXG | S_IRWXO));
ASSERT_EQ(0, aeron_mkdir(dirB, S_IRWXU | S_IRWXG | S_IRWXO));
ASSERT_EQ(-1, aeron_mkdir(dirC, S_IRWXU | S_IRWXG | S_IRWXO));
}

TEST_F(FileUtilTest, recursiveMkdir)
{
const char *dirW = "dirW";
const char *dirY = "dirX" AERON_FILE_SEP_STR "dirY";
const char *dirZ = "dirW" AERON_FILE_SEP_STR "dirX" AERON_FILE_SEP_STR "dirY" AERON_FILE_SEP_STR "dirZ";

removeDir("dirW" AERON_FILE_SEP_STR "dirX" AERON_FILE_SEP_STR "dirY" AERON_FILE_SEP_STR "dirZ");
removeDir("dirW" AERON_FILE_SEP_STR "dirX" AERON_FILE_SEP_STR "dirY");
removeDir("dirW" AERON_FILE_SEP_STR "dirX");
removeDir("dirW");
removeDir("dirX" AERON_FILE_SEP_STR "dirY");
removeDir("dirX");

ASSERT_EQ(0, aeron_mkdir_recursive(dirW, S_IRWXU | S_IRWXG | S_IRWXO));
ASSERT_EQ(0, aeron_mkdir_recursive(dirY, S_IRWXU | S_IRWXG | S_IRWXO));
ASSERT_EQ(0, aeron_mkdir_recursive(dirZ, S_IRWXU | S_IRWXG | S_IRWXO));
}
6 changes: 3 additions & 3 deletions aeron-driver/src/main/c/aeron_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ int aeron_driver_ensure_dir_is_recreated(aeron_driver_context_t *context)
}
}

if (aeron_mkdir(context->aeron_dir, S_IRWXU | S_IRWXG | S_IRWXO) != 0)
if (aeron_mkdir_recursive(context->aeron_dir, S_IRWXU | S_IRWXG | S_IRWXO) != 0)
{
AERON_SET_ERR(errno, "Failed to mkdir aeron directory: %s", context->aeron_dir);
return -1;
Expand All @@ -256,7 +256,7 @@ int aeron_driver_ensure_dir_is_recreated(aeron_driver_context_t *context)
return -1;
}

if (aeron_mkdir(filename, S_IRWXU | S_IRWXG | S_IRWXO) != 0)
if (aeron_mkdir_recursive(filename, S_IRWXU | S_IRWXG | S_IRWXO) != 0)
{
AERON_SET_ERR(errno, "Failed to mkdir publications directory: %s", context->aeron_dir);
return -1;
Expand All @@ -268,7 +268,7 @@ int aeron_driver_ensure_dir_is_recreated(aeron_driver_context_t *context)
return -1;
}

if (aeron_mkdir(filename, S_IRWXU | S_IRWXG | S_IRWXO) != 0)
if (aeron_mkdir_recursive(filename, S_IRWXU | S_IRWXG | S_IRWXO) != 0)
{
AERON_SET_ERR(errno, "Failed to mkdir images directory: %s", context->aeron_dir);
return -1;
Expand Down

0 comments on commit 98b9cf3

Please sign in to comment.