sponge preserves file permissions (as mentioned in the man page), but not the file ownership. This is different from shell redirections in bash, which do preserve ownership. root@rs3:~# ls -l foo -rw-r--r-- 1 hamish hamish 0 Jan 22 09:39 foo root@rs3:~# echo hi > foo root@rs3:~# ls -l foo -rw-r--r-- 1 hamish hamish 3 Jan 22 09:39 foo root@rs3:~# echo hi | sponge foo root@rs3:~# ls -l foo -rw-r--r-- 1 root root 3 Jan 22 09:39 foo Hamish
Control: severity -1 wishlist Control: tag -1 wontfix yes, you're right. As 'sponge' is not a shell redirect, and it is not designed to emulate one, it behaves more like 'tee' than like a shell redirection. I do understand that preserving the owner might be a nice feature, but I think this could work well only if 'sponge' is called with superuser capabilities (or if installed with suid-bit set). Why do you think that sponge ought to preserve the owner? Did the man page induce that somehow? Kind regards, Nicolas
I only expect it to preserve the ownership when you run it as root, on a file which doesn't belong to root. tee preserves the file ownership in this case, just as shell redirections do. sponge does not. With tee: # id uid=0(root) gid=0(root) groups=0(root) # ls -l foo -rw-r--r-- 1 hamish hamish 257 Apr 23 09:52 foo # echo hi | tee foo hi # ls -l foo -rw-r--r-- 1 hamish hamish 3 Apr 23 09:53 foo But with sponge: # echo hi | sponge foo # ls -l foo -rw-r--r-- 1 root root 3 Apr 23 09:53 foo tee is doing this automatically because it truncates the original file. sponge is copying the permissions from the original to the new file before replacing the original. It could also copy the owner, if running as root. Hamish
Hi, I was caught out by this just now, and got as far as "bugreport moreutils" before I found this existing bug. When I read "preserves permissions" in the man page, my brain just went on auto-pilot and assumed this meant ownership as well. I think this is encouraged along by a common use-case of sponge as a replacement for IO redirection, which as Hamish already noted does preserve ownership. I appreciate there is room for difference of opinion here over what behaviour is surprising or not, but I don't think it is just Hamish and I who would get surprised. So if preserving ownership is considered not the job of sponge then perhaps this could be called out in the man page near where it currently says that permissions are preserved? Thanks, Andy
Control: retitle -1 sponge: preserves permissions but not ownership Control: severity -1 normal Control: tag -1 - wontfix Thanks for pointing that out. Personally, I think that the man page is actually correct, as 'permissions' does not include 'ownership' (from the technical point of view), but I understand that this may be confusing for others. I think I'm going to prepare a patch, clarifying the wording of the man page. I can also ask Joey (upstream author) for commenting on the differences of expected behaviour, but I am expecting that preserving ownership will not become a feature of 'sponge'. Thanks for your reports! Kind regards, Nicolas
Hi Joey,
in #920118 [1], users of sponge complained about sponge not preserving
file ownership of the output file. They argued, that sponge should
behave (more) like 'tee' and shell redirections. And they interpreted
the sentence
"sponge preserves the permissions of the output file if it
already exists."
from sponge(1) as 'sponge preserves permissions and ownership [...]'.
After thinking about it several times, I am still ambiguous; thus, I am
sending you two patches:
0001: an attempt to clarify the wording such that is becomes (more)
clear that file ownership will not be preserved.
and
0002: (might be squashed with 0001) a patch to sponge.c that
introduces the attempt to restore the original file ownership
opportunistically, neither handling nor even checking for
errors.
I am really curious about your comments, and whether you'd like to
handle the complaints somehow.
Looking forward for your reply.
Thanks and kind regards,
Nicolas
[1]: https://bugs.debian.org/920118
Nicolas Schier (2):
sponge: mention that ownership might not be preserved (Closes:
#920118)
sponge: preserve ownership if possible (Closes: #920118)
sponge.c | 7 +++++++
sponge.docbook | 5 ++++-
2 files changed, 11 insertions(+), 1 deletion(-)
Users of sponge pointed out that the wording of sponge's man page caused confusion, as "preserves the permissions" has been interpreted as "preserves the permissions and ownership". Thus, mention that file ownership might not be preserved. Bug-Debian: https://bugs.debian.org/920118 Signed-off-by: Nicolas Schier <nicolas@fjasle.eu> --- sponge.docbook | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sponge.docbook b/sponge.docbook index 31bc6db..303d6e6 100644 --- a/sponge.docbook +++ b/sponge.docbook @@ -65,7 +65,11 @@ USA <para> <command>sponge</command> preserves the permissions of the output file - if it already exists. + if it already exists. But in contrast to e.g. + <command>tee</command>, <command>sponge</command> might + not preserve or restore the original file ownership, no + matter whether it has been called by a privileged (root) + user. </para> <para> When possible, <command>sponge</command> creates or updates the
Preserve or restore the ownership of the target output file, if
possible. This converges the behaviour of sponge a little bit more to
the one of 'tee' and shell redirections.
Bug-Debian: https://bugs.debian.org/920118
Signed-off-by: Nicolas Schier <nicolas@fjasle.eu>
---
sponge.c | 7 +++++++
sponge.docbook | 7 +++----
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/sponge.c b/sponge.c
index f852ad5..59e0a2f 100644
--- a/sponge.c
+++ b/sponge.c
@@ -379,6 +379,13 @@ int main (int argc, char **argv) {
}
copy_tmpfile(tmpfile, outfile, bufstart, bufsize);
}
+
+ /* Attempt to change ownership according to the old file, but
+ * ignore errors, as most users will not have the rights to
+ * change ownership. */
+ if (exists) {
+ chown(outname, statbuf.st_uid, statbuf.st_gid);
+ }
}
else {
if (tmpfile_used) {
diff --git a/sponge.docbook b/sponge.docbook
index 303d6e6..0b34561 100644
--- a/sponge.docbook
+++ b/sponge.docbook
@@ -66,10 +66,9 @@ USA
<command>sponge</command> preserves the
permissions of the output file
if it already exists. But in contrast to e.g.
- <command>tee</command>, <command>sponge</command> might
- not preserve or restore the original file ownership, no
- matter whether it has been called by a privileged (root)
- user.
+ <command>tee</command>, <command>sponge</command> does only
+ preserve or restore the original file ownership, if the current
+ user has the necessary rights.
</para>
<para>
When possible, <command>sponge</command> creates or updates the
I don't like complicating the man page with discussion of this. The man page concisely and correctly documents the actual behavior. Varying the behavior based on whether the user is root seems to just be asking for trouble. It does not emulate tee either; a non-root user who can write to a file they don't own can tee to it and its owner will be preserved; tee simply opens the file and writes over it.
Hi Joey, thanks for having a look at it. Your reply matching my initial thoughts about this issue. Kind regards and have a blessed pre-christmas time Nicolas