Re: override? argument in create-directory etc. Lassi Kortela 22 Apr 2020 21:28 UTC

> ensure-directory-exists is different, because it can return successfully
> when mkdir() call fails
> with EEXIST and the existing object is a directory.  In the current spec
> of srfi-170, create-directory
> removes the existing one.

I guess you're right. unlink() followed by mkdir() has a potential race
condition that a mere mkdir() avoids. Needlessly remaking the directory
could also change the permission bits of the mode (and other nonstandard
stuff like ACLs and MacOS attributes).

> And a trivial implementation like following is not correct:
>     (define (create-directory path perm override?)  ; omit optional
> argument handling
>        (when override?
>           (delete-filesystem-object-if-exists path))
>        (mkdir path perm))
> Since it can still fail with EEXISTS if another process may create an
> object between delete-filesystem-object-if-exists
> and mkdir.  (I just recently fixed a bug of the same nature that
> occurred in parallel build process.)

True. It would seem like a hack to silence an error from `mkdir` in that

> If we want ensure-* functionality, which seems to be more useful in
> practice, I'd suggest the optional argument
> to be a flag of "if the desired type of filesystem object
> already exists, then just change the mode and return".

I don't know of any other language with this kind of override flag in
the API. Does the flag come from scsh, and is there a particular
rationale for having it?

Usually when we want to overwrite a file, we just give the truncate flag
to open(). That will fail if the existing file system object is not a
regular file, which is the right thing IMHO.

When we want to "overwrite" a directory, we use ensure-directory-exists
which is quite popular in other languages.

BTW my proposed `ensure-directory-exists` was wrong - it should create
parent directories too if they don't exist. A version that creates only
the deepest-level directory is not that useful and is a bit confusing.