I’m writing an implementation of Ex (hopefully Vi eventually) as a personal project. I need to somehow store an identifier for the file associated with each buffer. In terms of security/race conditions and performance (and convention, if there is one), should I store the name of the file as given by the user, the file descriptor as returned by open()
, or the file pointer as returned by fopen()
/fdopen()
?
These are the methods I came up with, but I’m entirely open to any others.
4
After further thought (and your comment), I realise there’s a solid behavioural basis for choosing.
If I:
- open an existing file in your editor
- begin altering it
- realise I want a backup and move (not copy) the original
- save my modifications
should it alter the backup (the original inode with a new name)? Or write the altered file to the original name, leaving the backup alone?
I think the latter, which implies it shouldn’t keep the original file open as it won’t be able to use that file descriptor/FILE*
safely anyway. You might decide you want different behaviour, though.
Well, what state do ex (or vi) need to track for each file?
Off the top of my head, vim needs:
- file name
-
file descriptor or
FILE*
could this be
-1
orNULL
if it isn’t open? (are files in the buffer list held open even when not displayed? I don’t know, but it might be reasonable to close files and preserve an entry for them) -
swapfile – should the fd above refer to this? do we need to track the swapfile name as well?
- modification state
-
last read stat of the original file (so you can tell if it changed before overwriting)
or maybe just an “underlying file has changed” flag, if you want to use file change notifications
-
whether it’s read-only or read-write (you could just try to write and get an error, but … ick)
- line-ending convention, encoding
Note that I can have multiple buffers looking at different positions in the same file, and possibly with different settings (syntax highlighting, line numbers etc.) so those can’t be properties of the file itself.
Now, unless you can robustly infer all that from a single file descriptor, I think you need some struct storing all of that (and possibly more).
4