As much as the Win32 API is criticised for many of its functions containing often-unused parameters, symlink() having a flag parameter to control whether to overwrite the original link's contents if it exists would've made this much easier.
You would need the extra parameter + the guarantee that the symlink syscall did the overwrite atomically. And I don't think proliferating such guarantees througought the API is going to end well.
In Unix we have this convention that `rename()` is our atomicity swiss-army knife. I guess it makes it easier for implementers to only have to make their strong guarantees for one system call (+ a few related friends like `renameat`).
Now you could argue that `rename()` is a bit too under-powered for this job, and maybe we want transactions or something. But NTFS tried that too and deprecated them.
What I would like to see in Unix is better support for anonymous files and directories. You could use this with things like `renameat()` so that the temporary never touches the filesystem and is automatically cleaned up if the rename fails.
> What I would like to see in Unix is better support for anonymous files and directories. You could use this with things like `renameat()` so that the temporary never touches the filesystem and is automatically cleaned up if the rename fails.
Exactly. This approach makes the various calls orthogonal. Various syscalls create anonymous reference-counted inodes on a filesystem (which disappear when all references to them do), and syscalls like linkat or renameat or installs such an inode (referenced by file descriptor) into the filesystem with a name.
O_TMPFILE allows creating an anonymous file inode. Ideally, a syscall would exist to do the same for an anonymous symlink inode.
The most general thing -- involving the fewest new interfaces, even if the implementation is a big deal, would be an anonymous tmpfs. Where applications could stage a sort of poor-mans transaction.
The hard bit is that for it to be useful, you would need atomic renames from the TMPFS to some other arbitrary filesystem.
I guess abolishing the EXDEV error would be possible where the target filesystem has journaling, but it sounds like a big job to me.
On GNU/Linux there's also the (badly designed) memfd_create() syscall which allows you to create an anonymous inode even if / is entirely read-only and you don't have mounting permission. While you could do it with a user+mount namespace and sending the fd over a UNIX socket, sometimes making a syscall is a better idea. :P
memfd_create() does not create an inode. It only creates a file descriptor.
With a file descriptor you can create multiple mappings to the same physical address -- something otherwise impossible on UNIX or Linux (although mach allows you to vm_remap[1] which is often sufficient).
> memfd_create() does not create an inode. It only creates a file descriptor.
It creates both; memfd_create (and timerfd_create, signalfd, eventfd, userfaultfd, epoll, and others) use a kernel subsystem called "anon_inode" to create an in-memory inode to back the file descriptor.
I have been indelicate: What Linux calls an "struct inode" is not what UNIX traditionally called an inode[1], and I meant the latter without perhaps enough specificity.
The fact that the first argument (the "name") is only used as a debugging interface so that the /proc/self/fd/... "symlinks" have the name you set. I don't agree that this is useful for any real debugging, and constructing your syscalls so that they "make debugging easier" is not something that I really understand the motivations behind -- your ABI should be consistent and logical, not based on what you think a good debugging interface should be.