Commit Graph

91 Commits

Author SHA1 Message Date
Michael Forney 39f92650d3 ls, tar: Guard inclusion of sys/sysmacros.h by absence of `major` definition
Since musl 1.1.23, it too does not provide `major` and `minor` through
sys/types.h, so instead include sys/sysmacros.h based on the absence of
`major` rather than only on glibc.

Thanks to Rich Felker for the suggestion.
2019-08-05 14:38:32 -07:00
David Phillips 99c7876310 On glibc, include sysmacros.h directly
On glibc, major, minor, and makedev are all defined in
sys/sysmacros.h with types.h only including this for historical
reasons. A future release of glibc will remove this behaviour,
meaning that major, minor, and makedev will no longer be defined
for us without including sysmacros.h.
2018-09-25 19:31:01 -07:00
David Phillips 46495ea902 ls: abort a directory if we cannot opendir it
We should not try and perform operations on an invalid DIR* stream.
Instead, we shall let the error message be printed, and the return
code set (existing behaviour) and abort afterwards.
2017-08-22 13:33:40 +02:00
Quentin Rameau 441f73a518 ls: print filenames on the fly rather than in a buffer 2016-12-28 12:23:03 -08:00
Evan Gates d24ef864cb ls: respect -q when printing directory names with -R
break out the non printable character to ? code into a makeprint()
function so it can be used both in output() and lsdir()
2016-10-06 10:21:12 +02:00
Evan Gates 071dcc4d6b ls: fix ls -lq to respect -q flag 2016-10-06 10:21:12 +02:00
Michael Forney d827fcace2 ls: Simplify some logic
- After first iteration, set first to 0 instead of !first.
- If Hflag || Lflag, then mkent used stat instead of lstat, so the
  entity cannot be a symlink.
- Print path prefix along with directory name.
- In the 'if (Rflag)' block, just use 1 instead of Rflag.
2016-07-09 10:09:50 +01:00
Michael Forney ea03da0bda ls: Don't show directory name with single directory operand
This fixes the issue b107489bf2 tried
to fix, but doesn't break -R (which
bb83eade39 tried to fix).
2016-07-09 10:09:50 +01:00
Michael Forney e8e9b97baf Revert "ls: only display directory headers when more than one directory is specified"
This reverts commit b107489bf2.
2016-07-09 10:09:50 +01:00
Michael Forney b91b9e79ec Revert "Fix showing directories when -R flag is set in ls(1)"
This reverts commit bb83eade39.

This commit causes the loop through dents at the end of main to
continue past the end of the dents array, causing a crash when
called with multiple directory arguments.
2016-07-09 10:09:50 +01:00
Mattias Andrée dfc94e0221 ls: fix segfault when timestamp is out of range for struct tm
Signed-off-by: Mattias Andrée <>
2016-04-20 22:57:40 +01:00
FRIGN 2d7d2261a0 Really force 1 entry per line with -1 in ls(1)
if a filename contains a \n, it would not be limited to one line.
We use the qflag to replace the control characters with '?'s.
2016-03-02 18:44:32 +00:00
Quentin Rameau ee8701d501 ls: check for the index size before using it in visit()
Thanks to k0ga for noticing it!
2016-02-18 14:18:49 +00:00
Quentin Rameau 1024369f2d ls: make the opendir() warning message more consistent
Print the total file path in the warning message.
2016-02-18 14:17:21 +00:00
Quentin Rameau ac05587385 ls: set a return error code when skipping an already visited path. 2016-02-18 14:17:21 +00:00
Quentin Rameau 340b163563 ls: do not exit when a directory isn't accessible
Just print a warning and process next item instead,
and return 1 to report this error.
2016-02-18 11:31:58 +00:00 bb83eade39 Fix showing directories when -R flag is set in ls(1)
Here's a better version of the patch.
When the R flag is used with a single directory, the given directory name is
omitted. With multiple directories each directory name is listed.
Directories that start with './' and '../' are now also printed.
2016-02-17 19:49:07 +00:00
tty0 b107489bf2 ls: only display directory headers when more than one directory is specified 2016-02-15 09:59:09 +00:00
Quentin Rameau 4859f4c825 ls: fix time handling by augmenting time resolution
ls was using (old) UNIX spec (struct stat).st_[acm]time.
It now uses POSIX (struct stat).(struct timespec st_[acm]tim) which
gives time resolution in seconds and nanoseconds.
If two files have the same time in seconds, we extend the comparision to
2015-11-01 17:29:39 +00:00
Quentin Rameau 57d220b3dc ls: fix entities arrays handling in main()
Entities arrays in main() were arrays of pointer to entities and were
not compatible with entcmp().
They have been changed to being arrays of entities.
Thanks to Michael Forney <> for having seen that.
2015-11-01 17:29:39 +00:00
sin aa8112a408 Revert "ls: Fix sorting of named entries"
This reverts commit ff78d03791cc7c24dfc407c39dd2158451c9ad12.
2015-11-01 17:29:39 +00: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
Michael Forney 674d1636f8 ls: Fix sorting of named entries
Previously, entcmp was being passed struct entry **, when it expected
struct entry *.

Many autoconf-generated configure scripts use `ls -t` to determine whether or
not the system clock is behaving correctly. If they are sorted in the wrong
order, it produces an error.

  checking whether build environment is sane... configure: error: newly created file is older than distributed files!
  Check your system clock
2015-11-01 09:36:41 +00:00
Quentin Rameau 0e2f509883 ls: handle character/block files in long format
Although major() and minor() are not POSIX, we don't want to have macros
there so we rely on their implementation by the target system.
2015-10-04 16:45:51 +01:00
Hiltjo Posthuma 521c3734af ls: fix usage line, add f, n and p flag 2015-09-30 19:44:10 +01:00
Hiltjo Posthuma aba450fd1a ls: printf("%s", s) -> fputs(s, stdout) 2015-09-30 19:44:10 +01:00
Hiltjo Posthuma 874d131728 ls: LEN(pw|grname) -> sizeof() 2015-09-30 19:44:10 +01:00
Hiltjo Posthuma 53be158979 code-style: whitespace fixes 2015-09-30 19:44:10 +01:00
FRIGN 93f1fc4614 Remove trailing whitespace inside of ls(1) 2015-08-31 18:10:25 +01:00
Quentin Rameau 365e1a324a ls: group sorting options
tflag and Sflag are now grouped under 'sort' var, as suggested by cls.
r-flag handling has been moved inside entcmp().
2015-08-31 18:10:25 +01:00
Quentin Rameau f1bbe6529a ls: detect infinite loop with recursivity
populate an history of visited directories inodes and search it before
2015-08-31 18:10:25 +01:00
Quentin Rameau 74b5aa151c ls: correctly handle recursivity
the path is now carried through ls() and lsdir(), directory entries are
listed before recursing.
2015-08-31 18:10:25 +01:00
Quentin Rameau 1905b83cc9 ls: list operands in correct order
sort operands by name, list files first then directory entries
2015-08-31 18:10:25 +01:00
Quentin Rameau b88ed2ab2d ls: fix -q
Move qflag handling to output() instead of modifying the actual entity
name which broke recursivity.
2015-08-31 18:10:25 +01:00
Alexandre Niveau 6be7eaff1b ls: fix option -S for it to work without -lnpFi 2015-05-15 12:07:43 +01:00
FRIGN 5595af5742 Convert humansize() to accept a size_t instead of a double
General convention is to use size_t to store sizes of all kinds.
Internally, the function uses double anyway, but at least this
doesn't clobber up the API any more and there's a chance in the
future to make this function a bit cleaner and not use this dirty
static buffer hack any more.
2015-04-25 11:43:14 +01: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
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-

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
Quentin Rameau 9fdef90feb ls: add -f and -S options 2015-03-19 10:12:12 +00:00
FRIGN a68c2a9e6e Remove apathmax() and implicitly agetcwd()
pathconf() is just an insane interface to use. All sane operating-
systems set sane values for PATH_MAX. Due to the by-runtime-nature of
pathconf(), it actually weakens the programs depending on its values.

Given over 3 years it has still not been possible to implement a sane
and easy to use apathmax()-utility-function, and after discussing this
on IRC, we'll dump this garbage.

We are careful enough not to overflow PATH_MAX and even if, any user
is able to set another limit in if he so desires.
2015-03-18 15:20:35 +01:00
FRIGN 833c2aebb4 Remove mallocarray(...) and use reallocarray(NULL, ...)
After a short correspondence with Otto Moerbeek it turned out
mallocarray() is only in the OpenBSD-Kernel, because the kernel-
malloc doesn't have realloc.
Userspace applications should rather use reallocarray with an
explicit NULL-pointer.

Assuming reallocarray() will become available in c-stdlibs in the
next few years, we nip mallocarray() in the bud to allow an easy
transition to a system-provided version when the day comes.
2015-03-11 10:50:18 +01:00
FRIGN 3c33abc520 Implement mallocarray()
A function used only in the OpenBSD-Kernel as of now, but it surely
provides a helpful interface when you just don't want to make sure
the incoming pointer to erealloc() is really NULL so it behaves
like malloc, making it a bit more safer.

Talking about *allocarray(): It's definitely a major step in code-
hardening. Especially as a system administrator, you should be
able to trust your core tools without having to worry about segfaults
like this, which can easily lead to privilege escalation.

How do the GNU coreutils handle this?
$ strings -n 4611686018427387903
strings: invalid minimum string length -1
$ strings -n 4611686018427387904
strings: invalid minimum string length 0

They silently overflow...

In comparison, sbase:

$ strings -n 4611686018427387903
mallocarray: out of memory
$ strings -n 4611686018427387904
mallocarray: out of memory

The first out of memory is actually a true OOM returned by malloc,
whereas the second one is a detected overflow, which is not marked
in a special way.
Now tell me which diagnostic error-messages are easier to understand.
2015-03-10 22:19:19 +01:00
FRIGN 3b825735d8 Implement reallocarray()
Stateless and I stumbled upon this issue while discussing the
semantics of read, accepting a size_t but only being able to return
ssize_t, effectively lacking the ability to report successful
reads > SSIZE_MAX.
The discussion went along and we came to the topic of input-based
memory allocations. Basically, it was possible for the argument
to a memory-allocation-function to overflow, leading to a segfault
The OpenBSD-guys came up with the ingenious reallocarray-function,
and I implemented it as ereallocarray, which automatically returns
on error.
Read more about it here[0].

A simple testcase is this (courtesy to stateless):
$ sbase-strings -n (2^(32|64) / 4)

This will segfault before this patch and properly return an OOM-
situation afterwards (thanks to the overflow-check in reallocarray).

2015-03-10 21:23:36 +01:00
Quentin Rameau 7264acf7ed ls: add -n option 2015-02-22 12:30:47 +00:00
Tai Chi Minh Ralph Eastwood dacd523ec1 ls: add support for -R flag 2015-02-21 11:46:04 +00:00
sin 9c30fbf018 Add ls -A implementation
2015-02-21 09:31:01 +00:00
Quentin Rameau 51b707e91e ls: add support for -p 2015-02-19 18:52:13 +00:00
sin e635760742 Fix ls when -q is not set
Use strdup() unconditionally.
2015-02-18 16:48:07 +00:00
sin d40333e702 Fix ls -q UTF-8 parsing
Thanks FRIGN for the input.
2015-02-18 16:43:18 +00:00
sin 2a3f82a5cd Implement -u support for ls(1) 2015-02-18 16:29:46 +00:00
sin 9bd094193d Simplify ls -q implementation 2015-02-18 15:55:57 +00:00