mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2025-10-29 05:40:16 -04:00
scanner: Ensure parent directory exists for output file
Signed-off-by: ComixHe <heyuming@deepin.org>
This commit is contained in:
parent
264da6a92b
commit
3cbf08f29e
1 changed files with 94 additions and 2 deletions
|
|
@ -37,6 +37,8 @@
|
|||
#include <getopt.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if HAVE_LIBXML
|
||||
#include <libxml/parser.h>
|
||||
|
|
@ -2031,6 +2033,87 @@ free_protocol(struct protocol *protocol)
|
|||
free_description(protocol->description);
|
||||
}
|
||||
|
||||
static int
|
||||
ensure_parent_dir(const char *path, mode_t mode) {
|
||||
if (path == NULL || *path == '\0') {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
char path_copy[PATH_MAX];
|
||||
size_t len = strlen(path);
|
||||
if (len >= sizeof(path_copy)) {
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
memcpy(path_copy, path, len + 1);
|
||||
|
||||
/* Remove trailing slashes unless it's the root */
|
||||
while (len > 1 && path_copy[len - 1] == '/')
|
||||
path_copy[--len] = '\0';
|
||||
|
||||
char *last_slash = strrchr(path_copy, '/');
|
||||
if (last_slash == NULL || last_slash == path_copy)
|
||||
return 0;
|
||||
*last_slash = '\0';
|
||||
|
||||
/* start walking directories */
|
||||
int dfd = AT_FDCWD;
|
||||
int ret = 0;
|
||||
char *p = path_copy;
|
||||
|
||||
if (*p == '/') {
|
||||
dfd = open("/", O_RDONLY | O_DIRECTORY);
|
||||
if (dfd < 0)
|
||||
return -1;
|
||||
|
||||
while (*p == '/')
|
||||
++p;
|
||||
}
|
||||
|
||||
while (*p != '\0') {
|
||||
char *slash = strchr(p, '/');
|
||||
if (slash != NULL)
|
||||
*slash = '\0';
|
||||
|
||||
int new_dfd = openat(dfd, p, O_RDONLY | O_DIRECTORY);
|
||||
if (new_dfd < 0) {
|
||||
if (errno == ENOENT) {
|
||||
if (mkdirat(dfd, p, mode) < 0 && errno != EEXIST) {
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
new_dfd = openat(dfd, p, O_RDONLY | O_DIRECTORY);
|
||||
if (new_dfd < 0) {
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if (dfd != AT_FDCWD)
|
||||
close(dfd);
|
||||
dfd = new_dfd;
|
||||
|
||||
if (slash == NULL)
|
||||
break;
|
||||
|
||||
*slash = '/';
|
||||
p = slash + 1;
|
||||
while (*p == '/')
|
||||
++p;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (dfd != AT_FDCWD)
|
||||
close(dfd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct parse_context ctx;
|
||||
|
|
@ -2120,8 +2203,17 @@ int main(int argc, char *argv[])
|
|||
fprintf(stderr, "Could not open input file: %s\n",
|
||||
strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (freopen(argv[2], "w", stdout) == NULL) {
|
||||
}
|
||||
|
||||
/* ensure the parent directory of the output file exists */
|
||||
if (ensure_parent_dir(argv[2], 0755) < 0) {
|
||||
fprintf(stderr, "Could not create parent directory of output file: %s\n",
|
||||
strerror(errno));
|
||||
fclose(input);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (freopen(argv[2], "w", stdout) == NULL) {
|
||||
fprintf(stderr, "Could not open output file: %s\n",
|
||||
strerror(errno));
|
||||
fclose(input);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue