summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt11
-rw-r--r--mkdir_r.c20
-rw-r--r--posix.c40
-rw-r--r--private_include/mkdir_r_private.h28
-rw-r--r--win32.c35
5 files changed, 115 insertions, 19 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cd5bf81..dfa88de 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -12,5 +12,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
project(mkdir_r)
-add_library(${PROJECT_NAME} STATIC "mkdir_r.c")
+set(srcs "mkdir_r.c")
+
+if(WIN32)
+ set(${srcs} "${srcs}" "win32.c")
+else()
+ set(${srcs} "${srcs}" "posix.c")
+endif()
+
+add_library(${PROJECT_NAME} STATIC ${srcs})
target_include_directories(${PROJECT_NAME} PUBLIC ".")
+target_include_directories(${PROJECT_NAME} PRIVATE "private_include")
diff --git a/mkdir_r.c b/mkdir_r.c
index 20920e3..b91daae 100644
--- a/mkdir_r.c
+++ b/mkdir_r.c
@@ -14,13 +14,9 @@
limitations under the License.
*/
#include "mkdir_r.h"
+#include "mkdir_r_private.h"
#include <string.h>
#include <stdlib.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <errno.h>
#include <stdio.h>
#include <errno.h>
@@ -66,19 +62,7 @@ int mkdir_r(const char *const path)
if (!*dir)
/* Path starting with delimiter character. */
;
- else if (!access(dir, 0))
- {
- struct stat sb;
-
- if (stat(dir, &sb))
- goto exit;
- else if (!(sb.st_mode & S_IFDIR))
- {
- errno = ENOTDIR;
- goto exit;
- }
- }
- else if (mkdir(dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH))
+ else if (mkdir_r_port(dir))
goto exit;
dir = dup;
diff --git a/posix.c b/posix.c
new file mode 100644
index 0000000..d2d3651
--- /dev/null
+++ b/posix.c
@@ -0,0 +1,40 @@
+/*
+ Copyright 2020 Xavier Del Campo Romero
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+int mkdir_r_port(const char *const dir)
+{
+ if (!access(dir, 0))
+ {
+ struct stat sb;
+
+ if (stat(dir, &sb))
+ return -1;
+ else if (!(sb.st_mode & S_IFDIR))
+ {
+ errno = ENOTDIR;
+ return -1;
+ }
+ }
+ else if (mkdir(dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH))
+ return -1;
+
+ return 0;
+}
diff --git a/private_include/mkdir_r_private.h b/private_include/mkdir_r_private.h
new file mode 100644
index 0000000..12efdbb
--- /dev/null
+++ b/private_include/mkdir_r_private.h
@@ -0,0 +1,28 @@
+/*
+ Copyright 2020 Xavier Del Campo Romero
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+#ifndef MKDIR_R_PRIVATE_H
+#define MKDIR_R_PRIVATE_H
+
+/**
+ * Creates a directory using OS-specific API.
+ * @param dir Directory path.
+ * @return 0 if successful, -1 otherwise.
+ * @note Sets @c errno to @c ENOTDIR if one of the elements from @c path is not
+ * a directory.
+ */
+int mkdir_r_port(const char *const dir);
+
+#endif /* MKDIR_R_PRIVATE_H */
diff --git a/win32.c b/win32.c
new file mode 100644
index 0000000..eff119b
--- /dev/null
+++ b/win32.c
@@ -0,0 +1,35 @@
+/*
+ Copyright 2020 Xavier Del Campo Romero
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+#include <errno.h>
+#include <windows.h>
+#include <fileapi.h>
+
+int mkdir_r_port(const char *const dir)
+{
+ if (!CreateDirectoryA(dir, NULL))
+ {
+ switch (GetLastError())
+ {
+ case ERROR_ALREADY_EXISTS:
+ break;
+
+ default:
+ return -1;
+ }
+ }
+
+ return 0;
+}