Commit Graph

23 Commits

Author SHA1 Message Date
Michael Forney f4b9b966cf cp: Default to -P when -R is specified
POSIX only specifies the -H, -L, and -P options for use with -R, and
the default is left to the implementation. Without -R, symlinks must
be followed.

Most implementations use -P as the default with -R, which makes sense
to me as default behavior (the source and destination trees are the same).

Since we use the same code for -R and without it, and we allow -H, -L,
and -P without -R, set the default based on the presence of -R. Without
it, use -L as before, as required by POSIX, and with it, use -P to match
the behavior of other implementations.
2019-12-21 21:26:19 -08:00
sin 2366164de7 No need for semicolon after ARGEND
This is also the style used in Plan 9.
2015-11-01 10:18:55 +00:00
FRIGN 11e2d472bf Add *fshut() functions to properly flush file streams
This has been a known issue for a long time. Example:

printf "word" > /dev/full

wouldn't report there's not enough space on the device.
This is due to the fact that every libc has internal buffers
for stdout which store fragments of written data until they reach
a certain size or on some callback to flush them all at once to the
kernel.
You can force the libc to flush them with fflush(). In case flushing
fails, you can check the return value of fflush() and report an error.

However, previously, sbase didn't have such checks and without fflush(),
the libc silently flushes the buffers on exit without checking the errors.
No offense, but there's no way for the libc to report errors in the exit-
condition.

GNU coreutils solve this by having onexit-callbacks to handle the flushing
and report issues, but they have obvious deficiencies.
After long discussions on IRC, we came to the conclusion that checking the
return value of every io-function would be a bit too much, and having a
general-purpose fclose-wrapper would be the best way to go.

It turned out that fclose() alone is not enough to detect errors. The right
way to do it is to fflush() + check ferror on the fp and then to a fclose().
This is what fshut does and that's how it's done before each return.
The return value is obviously affected, reporting an error in case a flush
or close failed, but also when reading failed for some reason, the error-
state is caught.

the !!( ... + ...) construction is used to call all functions inside the
brackets and not "terminating" on the first.
We want errors to be reported, but there's no reason to stop flushing buffers
when one other file buffer has issues.
Obviously, functionales come before the flush and ret-logic comes after to
prevent early exits as well without reporting warnings if there are any.

One more advantage of fshut() is that it is even able to report errors
on obscure NFS-setups which the other coreutils are unable to detect,
because they only check the return-value of fflush() and fclose(),
not ferror() as well.
2015-04-05 09:13:56 +01:00
FRIGN 58098575e7 Audit cp() in libutil
1) Rename cp_HLPflag -> cp_follow for consistency.
2) Use function-pointers for stat to clear up the code.
3) BUGFIX: TERMINATE THE RESULT BUFFER OF READLINK !!!
   It's something I noticed earlier and it actually lead to some
   pretty insane behaviour on our side using glibc (musl somehow
   magically solves this).
   Basically, symlinks used to contain the data of the file they
   pointed to. I wondered for weeks where this came from and now
   this has finally been solved.
4) BUGFIX: Do not unconditionally unlink target-files. Even GNU
   coreutils do it wrong.
   The basic idea is this:
   If fflag == 0 --> don't touch target files if they exist.
   If fflag == 1 --> unlink all and don't error out when we try
                     to unlink a file which doesn't exist.
5) Use estrlcpy and estrlcat instead of snprintf for path building.
6) Make it clearer what happens in preserve.
2015-03-19 17:57:12 +01:00
FRIGN 8dc92fbd6c Refactor enmasse() and recurse() to reflect depth
The HLP-changes to sbase have been a great addition of functionality,
but they kind of "polluted" the enmasse() and recurse() prototypes.
As this will come in handy in the future, knowing at which "depth"
you are inside a recursing function is an important functionality.

Instead of having a special HLP-flag passed to enmasse, each sub-
function needs to provide it on its own and can calculate results
based on the current depth (for instance, 'H' implies 'P' at
depth > 0).
A special case is recurse(), because it actually depends on the
follow-type. A new flag "recurse_follow" brings consistency into
what used to be spread across different naming conventions (fflag,
HLP_flag, ...).

This also fixes numerous bugs with the behaviour of HLP in the
tools using it.
2015-03-02 22:50:38 +01:00
FRIGN 274e86e1aa Audit cp(1)
1) Refactor the manpage, which has been a bloody mess, documenting
   fantasy-flags (-d for example) and add a STANDARDS section
2) fix usage()
3) sort ARG-block
4) Check return-value of stat() separately, so a lack of permissions
   doesn't tell the user "the directory doesn't exist", which could
   be a bit confusing.
5) Add empty line before return.
2015-03-02 19:15:19 +01:00
sin 9d2b94dbb0 cp: Remove unnecessary comment
Not to mention that -d doesn't exist.
2015-02-18 17:08:52 +00:00
sin 16719ea6e1 cp: Update program usage and manpages
Do not document the non-standard -r flag as it is highly discouraged.
It is still silently accepted and treated the same as -R.
2015-02-17 16:14:42 +00:00
FRIGN 31572c8b0e Clean up #includes 2015-02-14 21:12:23 +01:00
Tai Chi Minh Ralph Eastwood af8be7f92c cp: add symlink deref flags -H and -L for cp and mv 2015-02-09 22:54:52 +00:00
Michael Forney e14e0becce cp: Rename -d option to -P
The -d option is a GNU extension and is equivalent to its "-P
--preserve=links" options.

Since we don't implement the --preserve=links functionality anyway (it
means preserve hard links between files), just call it -P, which is
specified by POSIX.

Additionally, there is no need to check for cp_Pflag again before
copying the symlink itself because the only way the mode in the stat
will indicate a symlink is if we used lstat (which we only do if -P is
specified).
2014-12-08 10:02:56 +00:00
FRIGN ec8246bbc6 Un-boolify sbase
It actually makes the binaries smaller, the code easier to read
(gems like "val == true", "val == false" are gone) and actually
predictable in the sense of that we actually know what we're
working with (one bitwise operator was quite adventurous and
should now be fixed).

This is also more consistent with the other suckless projects
around which don't use boolean types.
2014-11-14 10:54:20 +00:00
FRIGN eee98ed3a4 Fix coding style
It was about damn time. Consistency is very important in such a
big codebase.
2014-11-13 18:08:43 +00:00
Hiltjo Posthuma 323c45edb7 cp: improvements
- improve copying block, char devices, fifo and sockets with -a.
- improve exit status code.
2014-07-21 16:44:26 +01:00
Hiltjo Posthuma f67320ce93 cp: add -v, fix manpage info
Signed-off-by: Hiltjo Posthuma <hiltjo@codemadness.org>
2014-07-21 16:43:31 +01:00
Hiltjo Posthuma 8b3a9c1971 cp: add -a, -d, -p 2014-07-10 11:23:21 +01:00
sin 02918a46e8 Implement cp -f 2014-05-05 15:02:03 +01:00
sin 1851c02a95 Show usage instead of exiting silently on an invalid option 2013-12-12 13:30:25 +00:00
sin aff51008ea Add -R as a synonym to -r for cp(1)
List the available options in the usage line as well.
2013-12-12 13:30:17 +00:00
sin 428cd4fe84 None of these work without the proper # of arguments so print usage 2013-10-05 13:51:45 +01:00
David Galos 9f8deb4b23 Tar compiles on BSD, thanks Roberto E. Vargas Caballero. Also remove tons of trailing whitespace. 2013-07-20 01:27:42 -04:00
Federico G. Benavento e509d56bae s/getopt/ARGBEGIN/ and -r bug fix cp 2013-03-10 21:59:22 -03:00
William Haddon cec53d14b1 implement cp and mv and improve rm 2012-01-30 22:41:33 +00:00