fs: split mkdir's recursive functionality into "mkpath"
This commit is contained in:
parent
78b55f2205
commit
dac9418d8e
1 changed files with 29 additions and 27 deletions
56
lfs.c
56
lfs.c
|
@ -365,21 +365,32 @@ fs_isfile(lua_State *L)
|
||||||
return ismode(L, S_IFREG);
|
return ismode(L, S_IFREG);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/***
|
||||||
* Taken from OpenBSD mkdir(1)
|
* Creates a new directory, creating intermediate directories as required.
|
||||||
* mkpath -- create directories.
|
*
|
||||||
* path - path
|
* On success, returns true. Otherwise returns nil, an error
|
||||||
* mode - file mode of terminal directory
|
* message and a platform-dependent error code.
|
||||||
* dir_mode - file mode of intermediate directories
|
*
|
||||||
|
* @function mkpath
|
||||||
|
* @usage fs.mkpath("/usr/local/bin")
|
||||||
|
* @tparam string path The path to create.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
mkpath(char *path, mode_t mode, mode_t dir_mode)
|
fs_mkpath(lua_State *L)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Code derived from OpenBSD mkdir(1)
|
||||||
|
*/
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
const char *path; /* path to make */
|
||||||
char *slash;
|
char *slash;
|
||||||
|
mode_t mode; /* file mode of terminal directory */
|
||||||
|
mode_t dir_mode; /* file mode of intermediate directories */
|
||||||
int done;
|
int done;
|
||||||
|
|
||||||
slash = path;
|
path = luaL_checkstring(L, 1);
|
||||||
|
mode = dir_mode = 0777;
|
||||||
|
slash = (char *)path;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
slash += strspn(slash, "/");
|
slash += strspn(slash, "/");
|
||||||
|
@ -390,19 +401,19 @@ mkpath(char *path, mode_t mode, mode_t dir_mode)
|
||||||
|
|
||||||
if (mkdir(path, done ? mode : dir_mode) == 0) {
|
if (mkdir(path, done ? mode : dir_mode) == 0) {
|
||||||
if (mode > 0777 && chmod(path, mode) == -1)
|
if (mode > 0777 && chmod(path, mode) == -1)
|
||||||
return -1;
|
return lfail(L);
|
||||||
} else {
|
} else {
|
||||||
int mkdir_errno = errno;
|
int mkdir_errno = errno;
|
||||||
|
|
||||||
if (stat(path, &sb) == -1) {
|
if (stat(path, &sb) == -1) {
|
||||||
/* Not there; use mkdir()s errno */
|
/* Not there; use mkdir()s errno */
|
||||||
errno = mkdir_errno;
|
errno = mkdir_errno;
|
||||||
return -1;
|
return lfail(L);
|
||||||
}
|
}
|
||||||
if (!S_ISDIR(sb.st_mode)) {
|
if (!S_ISDIR(sb.st_mode)) {
|
||||||
/* Is there, but isn't a directory */
|
/* Is there, but isn't a directory */
|
||||||
errno = ENOTDIR;
|
errno = ENOTDIR;
|
||||||
return -1;
|
return lfail(L);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,15 +423,15 @@ mkpath(char *path, mode_t mode, mode_t dir_mode)
|
||||||
*slash = '/';
|
*slash = '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
lua_pushboolean(L, 1);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Creates a new directory.
|
* Creates a new directory.
|
||||||
*
|
*
|
||||||
* If *recursive* is true, creates intermediate directories
|
* If you need to create multiple directories at once (similar to
|
||||||
* (parent directories) as required; behaves as POSIX
|
* the behaviour of `mkdir -p`), use *fs.mkpath* instead.
|
||||||
* `mkdir -p` would.
|
|
||||||
*
|
*
|
||||||
* On success, returns true. Otherwise returns nil, an error
|
* On success, returns true. Otherwise returns nil, an error
|
||||||
* message and a platform-dependent error code.
|
* message and a platform-dependent error code.
|
||||||
|
@ -428,25 +439,15 @@ mkpath(char *path, mode_t mode, mode_t dir_mode)
|
||||||
* @function mkdir
|
* @function mkdir
|
||||||
* @usage fs.mkdir("/usr/local/bin")
|
* @usage fs.mkdir("/usr/local/bin")
|
||||||
* @tparam string dir The path of the directory to create.
|
* @tparam string dir The path of the directory to create.
|
||||||
* @tparam[opt] boolean recursive Whether to create intermediate directories.
|
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
fs_mkdir(lua_State *L)
|
fs_mkdir(lua_State *L)
|
||||||
{
|
{
|
||||||
char *dir; /* parameter 1 (string) */
|
char *dir; /* parameter 1 (string) */
|
||||||
int recursive; /* parameter 2 (boolean) */
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
dir = strdup(luaL_checkstring(L, 1));
|
dir = strdup(luaL_checkstring(L, 1));
|
||||||
|
ret = mkdir(dir, 0777);
|
||||||
if (!lua_isboolean(L, 2) && !lua_isnoneornil(L, 2))
|
|
||||||
luaL_typeerror(L, 2, "boolean");
|
|
||||||
recursive = lua_toboolean(L, 2);
|
|
||||||
|
|
||||||
if (recursive)
|
|
||||||
ret = mkpath(dir, 0777, 0777);
|
|
||||||
else
|
|
||||||
ret = mkdir(dir, 0777);
|
|
||||||
free(dir);
|
free(dir);
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
|
@ -694,6 +695,7 @@ static const luaL_Reg fslib[] = {
|
||||||
{"isdirectory", fs_isdirectory},
|
{"isdirectory", fs_isdirectory},
|
||||||
{"isfile", fs_isfile},
|
{"isfile", fs_isfile},
|
||||||
{"mkdir", fs_mkdir},
|
{"mkdir", fs_mkdir},
|
||||||
|
{"mkpath", fs_mkpath},
|
||||||
{"move", fs_move},
|
{"move", fs_move},
|
||||||
{"remove", fs_remove},
|
{"remove", fs_remove},
|
||||||
{"rmdir", fs_rmdir},
|
{"rmdir", fs_rmdir},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue