(text referenced from OpenBSD wait(2) man page)
While there, remove duplicated information and add more refernces in SEE ALSO
Also, the NOTES section refers to intro(2), while siginterrupt(3) is a better
suited reference, so fix that too.
Ok by wiz
cannot alias with an extern. While this is clearly bogus, avoid yet
another alias handling bug and use strong aliases. It's actually
slightly simpler, too.
If 06:00 or 18:00 are wanted, just say "06:00" (etc). If these
are ever added back, they really should determine location, and
calculate actual sunrise/sunset times for the location and date.
That's not likely to happen...
GNU libiconv is no longer incompatible with POSIX since 2007.
Solaris 11 moved to POSIX.
Illumos moved to POSIX http://illumos.org/man/3c/iconv
New software is aligned to POSIX not to the old mistake in the standard.
As such, reorganize the start/end references to use a weak reference
only, if we use it to remove size knowledge. Otherwise use weak
external declarations.
directory first for paths that don't contain "/", first try the
/dev paths to avoid confusion with files in the working directory
that happen to match disk names.
In libedit, the only way how H_ENTER can fail is memory exhaustion,
too, and of course it is handled gracefully, returning -1 from
history(). So of course, we will continue to handle it gracefully
in add_history() as well, but we are free to decide what to do with
the library state in this case because GNU just dies...
I think the most reasonable course of action is to simply not change
the library state in any way when add_history() fails due to memory
exhaustion, but just return.
If H_ENTER does not fail, we know that the history now contains at
least one entry, so there is no need any longer to check the H_GETSIZE
return value. And we can of course always set current_history_valid.
While testing these changes, i noticed three problems so closely
related that i'd like to fix them in the same diff.
1. libedit has the wrong prototype for add_history().
GNU readline-6.3 defines it as void add_history(const char *).
Of course, that is very stupid - no way to report problems to
the caller! But the whole point of a compatibility mode is
being compatible, so we should ultimately change this.
Of course, changing the prototype of a public symbol requires
a libedit major bump. I don't want to do that casually.
Rather, i will take a note and change the prototype the next
time we need a libedit major bump for more important reasons.
For now, let's just always return 0.
2. While *implicitely* pushing an old entry off the history
increments history_base in GNU readline, testing reveals that
*explicitly* deleting one does not. Again, this is not
documented, but it applies to both remove_history() and
stifle_history(). So delete history_base manipulation
from stifle_history(), which also allows to simplify the
code and delete two automatic variables.
3. GNU readline add_history(NULL) crashes with a segfault.
There is nothing wrong with having a public interface
behave that way. Many standard interfaces do, including
strlen(3). Such crashes can even be useful to catch
buggy application programs.
In libedit/readline.c rev. 1.104, Christos made add_history()
silently ignore this coding error, according to the commit
message to hide a bug in nslookup(1). That change was never
merged to OpenBSD. I strongly disagree with this change.
If nslookup(1) is still broken, that program needs to be
fixed instead. In any case, delete the bogus check; hiding
bugs is dangerous.
__CTOR_LIST__ and __CTOR_LIST_END__ are logically the same object, but
due to the start marker, the former has to be declared as array of fixed
size. Newer GCC versions take the liberty of exploiting the UB of
accessing global objects past the end to unconditionally load zero
values in that case. Two fixes are possible:
(1) Pruning via inline assembler as done by GCC's own CRT copy.
(2) Pruning via weak references as done for linker sets.
Since the second part is known and required to work anyway, prefer this
approach. In theory, the labels could be replaced completely, except
that GNU as doesn't provide start/end symbols for sections containing
dots.
This is actually unnecessary as the call in question uses only fields
that have been set explicitly, but good practice regardless and it's
not like it's on a performance-critical path.
Reduce obfuscation of errno handling. There is only one purpose
non-local errno handling is needed for: Inside el_wgets(), several
functions call down indirectly to el_wgetc(), many of them via the
dispatch table. When el_wgetc() fails, it does properly report
failure, but then various cleanup is done which may clobber errno.
But when returning due to failure, el_wgets() wants to have errno
set to the reason of the original read failure, not to the reason
of some subsequent failure of some cleanup operation. So el_wgetc()
needs to save errno, and if it's non-zero, el_wgets() needs to
restore it on failure.
This core logic is currently obscured by the fact that el_errno
is set and inspected at some additional places where it isn't needed.
Besides, since el_wgetc() and and el_wgets() are both in read.c,
el_errno does not need to be in struct editline, it can and should
be local to read.c in struct el_read_t.
Let's look at what can be simplified.
1. keymacro_get() abuses el_errno instead of having a proper
error return code. Adding that error return code is easy
because node_trav() already detects the condition and an
adequate code is already defined. Returning it, testing
for it in read_getcmd(), and returning with error from there
removes the need to inspect el_errno from el_wgets() after
calling read_getcmd().
Note that resetting lastchar and cursor and clearing buffer[0]
is irrelevant. The code returns from el_wgets() right afterwards.
Outside el_wgets(), these variables are no longer relevant.
When el_wgets() is called the next time, it will call ch_reset()
anyway, resetting the two pointers. And as long as lastchar
points to the beginning of the buffer, the contents of the
buffer won't be used for anything.
2. read_getcmd() doesn't need to set el_errno again after el_wgetc()
failure since el_wgetc() already did so. While here, remove
the silly "if EOF or error" comments from the el_wgetc()
return value tests. It's a public interface documented in a
manual, so people working on the implementation can obviously
be expected to know how it works. It's a case of
count++; /* Increment count. */
3. In the two code paths of el_wgets() that lead up to "goto noedit",
there is no need to save the errno because nothing that might
change it happens before returning.
For clarity, since el_wgets() is the function restoring the errno,
also move initializing it to the same function.
Finally, note that restoring errno when the saved value is zero is
wrong. No library code is ever allowed to clear a previously set
value of errno. Only application programs are allowed to do that,
and even they usually don't need to do so, except when using certain
ill-designed interfaces like strtol(3).
I tested that the behaviour remains sane in the following cases,
all during execution of el_wgets(3) and with a signal handler
for USR1 installed without SA_RESTART.
* Enter some text and maybe move around a bit.
Then send a USR1 signal.
The signal gets processed, then read_char() resumes reading.
Send another USR1 signal.
Now el_wgets() sets errno=EINTR and returns -1.
* Press Ctrl-V to activate ed-quoted-insert.
Then send a USR1 signal.
The signal gets processed, then read_char() resumes reading.
Send another USR1 signal.
ed_quoted_insert() returns ed_end_of_file(), i.e. CC_EOF,
and el_wgets() returns 0.
* Press a key starting a keyboard macro.
Then send a USR1 signal.
The signal gets processed, then read_char() resumes reading.
Send another USR1 signal.
Now el_wgets() sets errno=EINTR and returns -1.
* Press : to enter builtin command mode.
Start typing a command.
Then send a USR1 signal.
The signal gets processed, then read_char() resumes reading.
Send another USR1 signal.
Now c_gets() returns -1, ed_command() beeps and returns CC_REFRESH,
and el_wgets() resumes operation as it should.
I also tested with "el_set(el, EL_EDITMODE, 0)", and it returns
the right value and sets errno correctly.