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 implementation. > 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.