Pharos
0.7.23
Modern Web Framework & Web App Hosting Service.
Toggle main menu visibility
Loading...
Searching...
No Matches
native_fs.c
Go to the documentation of this file.
1
/**
2
* @file
3
* @brief Provides filesystem helpers for directory creation, recursive copy or removal, and file writes.
4
*/
5
6
#include "
native_fs.h
"
7
8
#include "
native_support.h
"
9
10
#include <errno.h>
11
#include <stdio.h>
12
#include <stdlib.h>
13
#include <string.h>
14
15
#ifdef _WIN32
16
#include <direct.h>
17
#include <io.h>
18
#include <sys/stat.h>
19
#define PHAROS_FS_PATH_SEP '\\'
20
#define pharos_fs_mkdir(path, mode) _mkdir(path)
21
#define pharos_fs_unlink _unlink
22
#else
23
#include <dirent.h>
24
#include <sys/stat.h>
25
#include <unistd.h>
26
#define PHAROS_FS_PATH_SEP '/'
27
#define pharos_fs_mkdir mkdir
28
#define pharos_fs_unlink unlink
29
#endif
30
31
int
ensure_directory
(
const
char
*path) {
32
char
*copy;
33
char
*cursor;
34
if
(path == NULL || path[0] ==
'\0'
) {
35
return
0;
36
}
37
if
(
path_is_directory
(path)) {
38
return
0;
39
}
40
#ifdef _WIN32
41
copy = _strdup(path);
42
#else
43
copy = strdup(path);
44
#endif
45
if
(copy == NULL) {
46
return
69;
47
}
48
for
(cursor = copy + 1; *cursor !=
'\0'
; cursor++) {
49
if
(*cursor ==
PHAROS_FS_PATH_SEP
) {
50
*cursor =
'\0'
;
51
if
(copy[0] !=
'\0'
&& !
path_is_directory
(copy) &&
pharos_fs_mkdir
(copy, 0755) != 0 && errno != EEXIST) {
52
free(copy);
53
return
69;
54
}
55
*cursor =
PHAROS_FS_PATH_SEP
;
56
}
57
}
58
if
(!
path_is_directory
(copy) &&
pharos_fs_mkdir
(copy, 0755) != 0 && errno != EEXIST) {
59
free(copy);
60
return
69;
61
}
62
free(copy);
63
return
0;
64
}
65
66
int
write_text_file
(
const
char
*path,
const
char
*content) {
67
FILE *file;
68
char
*dir;
69
size_t
content_len = content != NULL ? strlen(content) : 0;
70
dir =
path_dirname
(path);
71
if
(dir == NULL) {
72
return
69;
73
}
74
if
(
ensure_directory
(dir) != 0) {
75
free(dir);
76
return
69;
77
}
78
free(dir);
79
file = fopen(path,
"wb"
);
80
if
(file == NULL) {
81
return
69;
82
}
83
if
(content_len > 0 && fwrite(content, 1, content_len, file) != content_len) {
84
fclose(file);
85
return
69;
86
}
87
if
(fclose(file) != 0) {
88
return
69;
89
}
90
return
0;
91
}
92
93
int
copy_file_binary
(
const
char
*source_path,
const
char
*target_path) {
94
FILE *source = NULL;
95
FILE *target = NULL;
96
char
*target_dir = NULL;
97
char
chunk[4096];
98
size_t
bytes_read;
99
int
code = 0;
100
target_dir =
path_dirname
(target_path);
101
if
(target_dir == NULL ||
ensure_directory
(target_dir) != 0) {
102
code = 69;
103
goto
cleanup;
104
}
105
source = fopen(source_path,
"rb"
);
106
if
(source == NULL) {
107
code = 66;
108
goto
cleanup;
109
}
110
target = fopen(target_path,
"wb"
);
111
if
(target == NULL) {
112
code = 69;
113
goto
cleanup;
114
}
115
while
((bytes_read = fread(chunk, 1,
sizeof
(chunk), source)) > 0) {
116
if
(fwrite(chunk, 1, bytes_read, target) != bytes_read) {
117
code = 69;
118
goto
cleanup;
119
}
120
}
121
cleanup:
122
if
(source != NULL && fclose(source) != 0 && code == 0) {
123
code = 69;
124
}
125
if
(target != NULL && fclose(target) != 0 && code == 0) {
126
code = 69;
127
}
128
free(target_dir);
129
return
code;
130
}
131
132
int
copy_directory_recursive
(
const
char
*source_dir,
const
char
*target_dir) {
133
#ifndef _WIN32
134
DIR *dir;
135
struct
dirent *entry;
136
if
(
ensure_directory
(target_dir) != 0) {
137
return
69;
138
}
139
dir = opendir(source_dir);
140
if
(dir == NULL) {
141
return
66;
142
}
143
while
((entry = readdir(dir)) != NULL) {
144
char
*source_path;
145
char
*target_path;
146
int
code;
147
if
(
streq
(entry->d_name,
"."
) ||
streq
(entry->d_name,
".."
)) {
148
continue
;
149
}
150
source_path =
path_join
(source_dir, entry->d_name);
151
target_path =
path_join
(target_dir, entry->d_name);
152
if
(source_path == NULL || target_path == NULL) {
153
free(source_path);
154
free(target_path);
155
closedir(dir);
156
return
69;
157
}
158
if
(
path_is_directory
(source_path)) {
159
code =
copy_directory_recursive
(source_path, target_path);
160
}
else
{
161
code =
copy_file_binary
(source_path, target_path);
162
}
163
free(source_path);
164
free(target_path);
165
if
(code != 0) {
166
closedir(dir);
167
return
code;
168
}
169
}
170
closedir(dir);
171
return
0;
172
#else
173
(void)source_dir;
174
(void)target_dir;
175
return
78;
176
#endif
177
}
178
179
int
remove_directory_recursive
(
const
char
*target_dir) {
180
#ifndef _WIN32
181
DIR *dir;
182
struct
dirent *entry;
183
if
(target_dir == NULL || !
path_exists
(target_dir)) {
184
return
0;
185
}
186
if
(!
path_is_directory
(target_dir)) {
187
return
pharos_fs_unlink
(target_dir) == 0 ? 0 : 69;
188
}
189
dir = opendir(target_dir);
190
if
(dir == NULL) {
191
return
69;
192
}
193
while
((entry = readdir(dir)) != NULL) {
194
char
*child_path;
195
int
code;
196
if
(
streq
(entry->d_name,
"."
) ||
streq
(entry->d_name,
".."
)) {
197
continue
;
198
}
199
child_path =
path_join
(target_dir, entry->d_name);
200
if
(child_path == NULL) {
201
closedir(dir);
202
return
69;
203
}
204
if
(
path_is_directory
(child_path)) {
205
code =
remove_directory_recursive
(child_path);
206
}
else
{
207
code =
pharos_fs_unlink
(child_path) == 0 ? 0 : 69;
208
}
209
free(child_path);
210
if
(code != 0) {
211
closedir(dir);
212
return
code;
213
}
214
}
215
closedir(dir);
216
return
rmdir(target_dir) == 0 ? 0 : 69;
217
#else
218
(void)target_dir;
219
return
78;
220
#endif
221
}
ensure_directory
int ensure_directory(const char *path)
Creates a directory path and any missing parent directories.
Definition
native_fs.c:31
write_text_file
int write_text_file(const char *path, const char *content)
Writes a text buffer to a file path.
Definition
native_fs.c:66
PHAROS_FS_PATH_SEP
#define PHAROS_FS_PATH_SEP
Definition
native_fs.c:26
remove_directory_recursive
int remove_directory_recursive(const char *target_dir)
Recursively removes a directory tree.
Definition
native_fs.c:179
copy_directory_recursive
int copy_directory_recursive(const char *source_dir, const char *target_dir)
Recursively copies one directory tree into another location.
Definition
native_fs.c:132
pharos_fs_unlink
#define pharos_fs_unlink
Definition
native_fs.c:28
copy_file_binary
int copy_file_binary(const char *source_path, const char *target_path)
Copies one file as binary data.
Definition
native_fs.c:93
pharos_fs_mkdir
#define pharos_fs_mkdir
Definition
native_fs.c:27
native_fs.h
Declares native filesystem helper routines.
path_join
char * path_join(const char *left, const char *right)
Joins two path segments using the native path separator.
Definition
native_support.c:115
streq
int streq(const char *a, const char *b)
Tests whether two strings are exactly equal.
Definition
native_support.c:111
path_is_directory
int path_is_directory(const char *path)
Tests whether a filesystem path refers to a directory.
Definition
native_support.c:172
path_dirname
char * path_dirname(const char *path)
Returns the parent directory component of a path.
Definition
native_support.c:145
path_exists
int path_exists(const char *path)
Tests whether a filesystem path currently exists.
Definition
native_support.c:168
native_support.h
Declares shared low-level support helpers used across the Pharos native runtime.
src
native_runtime
c
native_fs.c
Generated by
1.17.0