Editing an /etc/fstab entry in C++
I'm trying to edit the /etc/fstab
file on a CentOS installation using C++. The idea being that based on another config file I will add entries that don't exist in the fstab, or edit entries in the fstab file where the mount point is the same. This lets us set the system up properly on initial bootup.
I've found setmntent()
and getmntent()
开发者_开发问答 for iterating over the exiting entries so I can easily check whether an entry in fstab also exists in my config file. And I can then use addmntent()
to add any entry that doesn't already exist - the documentation says nothing about this being able to edit an entry, only add a new entry to the end of the file. There seems to be no way to edit an existing entry or delete an entry. It seems odd that this feature doesn't exist, only the CR and not the UD of CRUD.
I'd rather not have to write my own parser if I can at all help it.
My other alternative is to:
- open the file using
setmntent()
- read the whole of fstab into memory using
getmentent()
and perform any additions and/or edits - close the file using
endmntent()
- open
/etc/fstab
for writing - close
/etc/fstab
(thus emptying the file) - open the fstab using
setmntent()
- loop through the entries I read in previously and write them out using
addmntent()
Which although probably fine, just seems a bit messy.
When modifying system configuration files such as /etc/fstab
keep in mind that these are critical state and, should your "edit" be interrupted by a power loss, might result in a failure to reboot.
The way to deal with this is:
- create an empty output:
FILE* out = setmntent("/etc/fstab.new", "rw");
- open the original for input:
FILE* in = setmntent("/etc/fstab", "r");
- copy the contents:
while (m = getmntent(in)) { addmntent(out, m); }
- make sure the output has it all:
fflush(out); endmntent(out); endmntent(in);
- atomically replace
/etc/fstab
:
rename("/etc/fstab.new", "/etc/fstab");
It's left as an exercise to the reader to change the body of the while loop to make a modification to an existing element, to substitute a specifically crafted mntent
or whatever. If you have specific questions on that please ask.
UN*X semantics for rename()
guarantee that even in the case of power loss, you'll have either the original version or your new updated one.
There's a reason why there is no modifymntent()
- because that would encourage bad programming / bad ways of changing system critical files. You say at the end of your post "... probably fine ..." - not. The only safe way to change a system configuration file is to write a complete modified copy, sync that to safe storage, and then use rename to replace the old one.
精彩评论