diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2020-01-25 22:49:35 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2020-01-25 22:49:35 -0800 |
commit | b21778b7f432c9c5a9c3e5e442b2305cbcc0d524 (patch) | |
tree | 10953b0d2021da652277f9a033c3e33cb69563df /sysif.c | |
parent | 208319c21734bbb829fd6b8e2bc9da819b454bad (diff) | |
download | txr-b21778b7f432c9c5a9c3e5e442b2305cbcc0d524.tar.gz txr-b21778b7f432c9c5a9c3e5e442b2305cbcc0d524.tar.bz2 txr-b21778b7f432c9c5a9c3e5e442b2305cbcc0d524.zip |
ensure-dir: fail if exists and not dir.
* sysif.c (do_stat, do_lstat): Functions relocated before
mkdir_nothrow_exists.
(mkdir_nothrow_exists): In the EEXIST case, call stat on the
object. If it's not a directory or a symlink to a directory,
then do not suppress the error; propagate it to the caller,
where it will become an exception.
* txr.1: Specify the behavior of ensure-dir more precisely:
that it only supresses the existence error for directories
and directory symlinks.
Diffstat (limited to 'sysif.c')
-rw-r--r-- | sysif.c | 50 |
1 files changed, 30 insertions, 20 deletions
@@ -301,6 +301,28 @@ static val mkdir_wrap(val path, val mode) } #endif +#if HAVE_SYS_STAT +static int do_stat(val wpath, struct stat *buf) +{ + char *path = utf8_dup_to(c_str(wpath)); + int res = stat(path, buf); + free(path); + return res; +} + +#ifdef S_IFLNK +static int do_lstat(val wpath, struct stat *buf) +{ + char *path = utf8_dup_to(c_str(wpath)); + int res = lstat(path, buf); + free(path); + return res; +} +#else +#define do_lstat do_stat +#endif +#endif + #if HAVE_MKDIR || HAVE_WINDOWS_H static val mkdir_nothrow_exists(val path, val mode) { @@ -317,6 +339,14 @@ static val mkdir_nothrow_exists(val path, val mode) ret = num(errno); break; case EEXIST: +#if HAVE_SYS_STAT + { + struct stat st; + int err = do_stat(path, &st); + if (err == 0 && !S_ISDIR(st.st_mode)) + ret = num(EEXIST); + } +#endif break; default: uw_throw(esym, eobj); @@ -797,26 +827,6 @@ static val exit_star_wrap(val status) #endif #if HAVE_SYS_STAT -static int do_stat(val wpath, struct stat *buf) -{ - char *path = utf8_dup_to(c_str(wpath)); - int res = stat(path, buf); - free(path); - return res; -} - -#ifdef S_IFLNK -static int do_lstat(val wpath, struct stat *buf) -{ - char *path = utf8_dup_to(c_str(wpath)); - int res = lstat(path, buf); - free(path); - return res; -} -#else -#define do_lstat do_stat -#endif - static int do_fstat(val stream, struct stat *buf) { val self = lit("fstat"); |