1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-02-15 04:32:24 +00:00
Commit graph

689 commits

Author SHA1 Message Date
Martijn Dekker
7a0934a8d6 libast: remove antiquated macOS bug workaround
That Mac OS X bug workaround is now 23 days shy of the age of
majority, and that bug (symlinks testing as regular files) is
pretty basic, so I'm betting it's fixed by now.

src/lib/libast/include/ast_dir.h:
- Do not disable D_TYPE on macOS.
2021-03-04 23:46:20 +00:00
Martijn Dekker
b48e5b3365 Fix arbitrary command execution vuln in array subscripts in arith
This commit fixes an arbitrary command execution vulnerability in
array subscripts used within the arithmetic subsystem.

One of the possible reproducers is:
	var='1$(echo INJECTION >&2)' ksh -c \
		'typeset -A a; ((a[$var]++)); typeset -p a'

Output before this commit:
	INJECTION
	typeset -A a=([1]=1)
The 'echo' command has been surreptitiously executed from an
external environment variable.

Output after this commit:
	typeset -A a=(['1$(echo INJECTION >&2)']=1)
The value is correctly used as an array subscript and nothing in it
is parsed or executed. This is as it should be, as ksh93 supports
arbitrary subscripts for associative arrays.

If we think about it logically, the C-style arithmetic subsystem
simply has no business messing around with shell expansions or
quoting at all, because those don't belong to it. Shell expansions
and quotes are properly resolved by the main shell language before
the arithmetic subsystem is even invoked. It is particularly
important to maintain that separation because the shell expansion
mechanism also executes command substitutions.

Yet, the arithmetic subsystem subjected array subscripts that
contain `$` (and only array subscripts -- how oddly specific) to
an additional level of expansion and quote resolution. For some
unfathomable reason, there are two lines of code doing specifically
this. The vulnerability is fixed by simply removing those.

Incredibly, variants of this vulnerability are shared by bash, mksh
and zsh. Instead of fixing it, it got listed in Bash Pitfalls!
http://mywiki.wooledge.org/BashPitfalls#y.3D.24.28.28_array.5B.24x.5D_.29.29

src/cmd/ksh93/sh/arith.c:
- scope(): Remove these two lines that implement the vulnerability.
			if(strchr(sub,'$'))
				sub = sh_mactrim(shp,sub,0);
- scope(), arith(): Remove the NV_SUBQUOTE flag from two
  nv_endsubscript() calls. That flag causes the array subscript to
  retain the current level of shell quoting. The shell quotes
  everything as in "double quotes" before invoking the arithmetic
  subsystem, and the bad sh_mactrim() call removed one level of
  quoting. Since we're no longer doing that, this flag should no
  longer be passed, or subscripts may get extra backslash escapes.

src/cmd/ksh93/include/name.h,
src/cmd/ksh93/sh/array.c:
- nv_endsubscript(): The NV_SUBQUOTE flag was only passed from
  arith.c. Since it is now unused, remove it.

src/cmd/ksh93/tests/arith.sh:
- Tweak some tests: fix typos, report wrong values.
- Add 21 tests. Most are based on reproducers contributed by
  @stephane-chazelas and @hyenias. They verify that this
  vulnerability is gone and that no quoting bugs were introduced.

Resolves: https://github.com/ksh93/ksh/issues/152
2021-03-04 13:37:13 +00:00
hyenias
a61430f1b5
Readonly attribute size fix (#201)
Corrected the size of attribute(s) being overwritten with 0 when
'readonly' or 'typeset -r' was applied to an existing variable. Since
one cannot set any attributes with the 'readonly' command, its function
call to setall() needs to be adjusted to acquire the current size from
the old size or existing size of the variable. A plain 'typeset -r' is
the same as 'readonly' in that it needs to load the old size as its
current size for use in the subsequent to call to nv_newattr().

src/cmd/ksh93/bltins/typeset.c: setall():
- Both 'readonly' and 'typeset -r' end up calling setall(). setall()
  has full visibility into all user supplied values and existing
  values that are needed to differentiate whereas name.c newattr()
  acquires combined state flags.
- Added a conditional check if the readonly flag was requested by
  user then meets the criteria of having present size of 0, cannot
  be a numeric nor binary string, and is void of presence of any of
  the justified string attributes.
- -L/R/Z justified string attributes if not given a value default
  to a size of 0 which means to autosize. A binary string can have
  a fixed field size, e.g. -bZ. The present of any of the -L/R/Z
  attribules means that current size is valid and should be used
  even if it is zero.

src/cmd/ksh93/tests/attributes.sh:
- Added various tests to capture and reiterate that 'readonly' should
  be equivalent to 'typeset -r' and applying them should not alter the
  previous existing size unless additional attributes are set along
  with typeset command.
2021-03-03 03:26:39 +00:00
Martijn Dekker
6146848693 Fix compiling with SHOPT_REGRESS and SHOPT_P_SUID
src/cmd/ksh93/Mamfile:
- regress.c: add missing SH_DICT define for getopt self-doc string,
  needed after USAGE_LICENSE macros were removed. (re: ede47996)

src/cmd/ksh93/init.c: sh_init():
- Do not set error_info.exit early in init. This is the function
  that is called when an error exits the shell. It defaults to
  exit(3). Setting it to sh_exit() early on can cause a crash if an
  error is thrown before shell initialisation is fully finished.
  So set it at the end of sh_init() instead.
- __regress__: Remove error_info.exit workaround. (re: 506bd2b2)
- Fix SHOPT_P_SUID directive. This is not actually a 0/1 value, so
  we should use #ifdef and not #if. If SHOPT_REGRESS is on, it it
  set to a function call. (re: 2182ecfa)

src/cmd/ksh93/SHOPT.sh:
- Document that SHOPT_P_SUID cannot be set to 0 to be turned off.
2021-02-28 23:24:58 +00:00
Martijn Dekker
5d82004426 Misc regression test fixes
src/cmd/ksh93/tests/basic.sh:
- Fix syntax error (unbalanced single quote) in two -c script
  invocations. It only failed to throw a syntax error due to a
  problematic hack in ksh that may be removed soon.
  See: https://github.com/ksh93/ksh/issues/199

src/cmd/ksh93/tests/builtins.sh,
src/cmd/ksh93/tests/io.sh:
- Redirect standard error on two ksh -i invocations to /dev/null
  to work around the test hanging on AIX.

src/cmd/ksh93/tests/comvario.sh:
- Remove duplicate copyright header.
- Fix warning format.

src/cmd/ksh93/tests/functions.sh:
- Fix the 'TERM signal sent to last process of function kills the
  script' test so that it works on AIX. We cannot rely on grepping
  'ps' output as the external 'sleep' command does not show the
  command name on AIX. Instead, find it by its parent PID.

src/cmd/ksh93/tests/locale.sh,
src/cmd/ksh93/tests/substring.sh:
- Rewrite the very broken multibyte locale tests (two outright
  syntax errors due to unbalanced quotes, and none of the tests
  actually worked).
- Since they set LC_ALL, move them to locale.sh.

src/cmd/ksh93/tests/variables.sh:
- Redirect stderr on some 'ulimit -t unlimited' invocations (which
  fork subshells as the intended side effect) to /dev/null in case
  that exceeds a system-defined limit.
2021-02-28 21:57:38 +00:00
Johnothan King
7ad274f8b6
Add more out of memory checks (re: 18529b88) (#192)
The referenced commit neglected to add checks for strdup() calls.
That calls malloc() as well, and is used a lot.

This commit switches to another strategy: it adds wrapper functions
for all the allocation macros that check if the allocation
succeeded, so those checks don't need to be done manually.

src/cmd/ksh93/include/defs.h,
src/cmd/ksh93/sh/init.c:
- Add sh_malloc(), sh_realloc(), sh_calloc(), sh_strdup(),
  sh_memdup() wrapper functions with success checks. Call nospace()
  to error out if allocation fails.
- Update new_of() macro to use sh_malloc().
- Define new sh_newof() macro to replace newof(); it uses
  sh_realloc().

All other changed files:
- Replace the relevant calls with the wrappers.
- Remove now-redundant success checks from 18529b88.
- The ERROR_PANIC error message calls are updated to inclusive-or
  ERROR_SYSTEM into the exit code argument, so libast's error()
  appends the human-readable version of errno in square brackets.
  See src/lib/libast/man/error.3

src/cmd/ksh93/edit/history.c:
- Include "defs.h" to get access to the wrappers even if KSHELL is
  not defined.
- Since we're here, fix a compile error that occurred with KSHELL
  undefined by updating the type definition of hist_fname[] to
  match that of history.h.

src/cmd/ksh93/bltins/enum.c:
- To get access to sh_newof(), include "defs.h" instead of
  <shell.h> (note that "defs.h" includes <shell.h> itself).

src/cmd/ksh93/Mamfile:
- enum.c: depend on defs.h instead of shell.h.
- enum.o: add an -I. flag in the compiler invocation so that defs.h
  can find its subsequent includes.

src/cmd/builtin/pty.c:
- Define one outofmemory() function and call that instead of
  repeating the error message call.
- outofmemory() never returns, so remove superfluous exit handling.

Co-authored-by: Martijn Dekker <martijn@inlv.org>
2021-02-27 21:21:58 +00:00
Martijn Dekker
c928046aa9 Fix ${.sh.fun} leaking out of DEBUG trap
The value of the ${.sh.fun} variable, which is supposed to contain
the name of the function currently being executed, leaks out of the
DEBUG trap if it executes a function. Reproducer:

$ fn() { echo "executing the function"; }
$ trap fn DEBUG
$ trap - DEBUG
executing the function
$ echo ${.sh.fun}
fn

${.sh.fun} should be empty outside the function.

Annalysis:

The sh_debug() function in xec.c, which executes the DEBUG trap
action, contains these lines, which are part of restoring the state
after running the trap action with sh_trap():

	nv_putval(SH_PATHNAMENOD,shp->st.filename,NV_NOFREE);
	nv_putval(SH_FUNNAMENOD,shp->st.funname,NV_NOFREE);
 	shp->st = savst;

First the SH_PATHNAMENOD (${.sh.file}) and SH_FUNNAMENOD
(${.sh.fun}) variables get restored from the values in the shell's
scoped information struct (shp->st), but that is done *before*
restoring the parent scope with 'shp->st = savst;'. It should be
done after. Fixing the order is sufficient to fix the bug.

However, I am not convinced that these nv_putval() calls are good
for anything at all. Setting, unsetting, restoring, etc. the
${.sh.fun} and ${.sh.file} variables is already being handled
perfectly well elsewhere in the code for executing functions and
sourcing dot scripts. The DEBUG trap is neither here nor there.
There's no reason for it to get involved with these variables.

I was unable to break anything after simply removing those two
lines. So I strongly suspect this is another case, out of many now,
where a bug in ksh93 is properly fixed by removing some code.

I couldn't get ${.sh.file} to leak similarly -- I think this is
because SH_PATHNAMENOD (and not SH_FUNNOD) is set explicitly in
exfile() in main.c, masking this incorrect restore. It is the only
place where SH_PATHNAMENOD and SH_FUNNOD are not both set.

src/cmd/ksh93/sh/xec.c:
- Remove these two spurious nv_putval() calls.

src/cmd/ksh93/tests/variables.sh:
- Add regression test for leaking ${.sh.fun}.
2021-02-27 01:25:59 +00:00
Martijn Dekker
ef8b80cfd7 edit.c: make tput invocation work in restricted mode (re: 7ff6b73b)
At init, and then whenever the TERM variable changes, ed_setup()
uses sh_trap() to run the external 'tput' command to get the
current terminal escape sequence for moving up the cursor one line.

A sh_trap() call executes a shell command as if a shell script's
trap action had executed it, so is subject to modes like the
restricted mode. As of 7ff6b73b, we execute tput using its absolute
path (found and hardcoded at compile time) for better
robustness/security. This fails in restricted mode as it does not
allow executing commands by absolute path. But in C, nothing stops
us from turning that off.

src/cmd/ksh93/edit/edit.c: ed_setup():

- Block SIGINT while doing all of the following, so the user can't
  interrupt it and escape from restricted mode. Even without that,
  it's probably a good idea to do this, so an interrupt doesn't
  cause an inconsistent state.
      Note that sigblock() and sigrelease() are macros defined in
  features/sigfeatures. To get those, we need to include <fault.h>.

- Temporarily turn off SH_RESTRICTED before sh_trap()ping tput to
  get the terminal command to move the cursor up one position.

- Avoid potentially using a sequence that was cut off. Only use the
  resulting string if its length does not exceed the space reserved
  for CURSOR_UP. Otherwise, empty it.

src/cmd/ksh93/Mamfile:
- Add fault.h dependency to edit.c.

src/cmd/ksh93/edit/history.c:
- Fix typos in introductory comment.
2021-02-26 12:58:40 +00:00
Martijn Dekker
d9865ceae1 emacs: Fix three tab completion bugs
1. The editor accepted literal tabs without escaping in certain
   cases, causing buggy and inconsistent completion behaviour.
   https://github.com/ksh93/ksh/issues/71#issuecomment-656970959
   https://github.com/ksh93/ksh/issues/71#issuecomment-657216472

2. After completing a filename by choosing from a file completion
   menu, the terminal cursor was placed one position too far to the
   right, corrupting command line display. This happened with
   multiline active.
   https://github.com/ksh93/ksh/issues/71#issue-655093805

3. A completion menu was displayed if the file name to be completed
   was at the point where the rest of it started with a number,
   even if that part uniquely identified it so the menu had 1 item.
   https://www.mail-archive.com/ast-users@lists.research.att.com/msg00436.html

src/cmd/ksh93/edit/emacs.c:

- Cosmetic consistency: change two instances of cntl('[') to ESC.

- ed_emacsread(): Fix number 1 by refusing to continue into default
  processing if a tab character was not used for tab completion.
  Instead, beep and continue to the next read loop iteration. This
  behaviour is consistent with most other shells, so I doubt there
  will be objections. To enter a literal tab it's simple enough to
  escape it with ^V (the 'stty lnext' character) or \.

- draw(): Fix number 2 by correcting an off-by-one error in the
  ed_setcursor() call that updates the terminal's cursor display
  in multiline mode. The 'old' and 'new' parameters need to have
  identical values in this particular call to avoid the cursor
  position being off by one to the right. This change makes it
  match the corresponding ed_setcursor() call in vi.c. See below*
  for details. Thanks to Lev Kujawski for the help in analysing.

src/cmd/ksh93/edit/completion.c: ed_expand():

- Fix number 3 by changing from '=' mode (menu-based completion) to
  '\' mode (ordinary filename completion) if the menu would only
  show one option, which was pointless and annoying. This never
  happened in vi mode, so possibly the ed_expand() call in emacs.c
  could have been improved instead. But I'm comfortable with fixing
  it here and not in emacs.c, because this fixes it at a more
  fundamental level, plus it's straightforward and obvious here.

Resolves: https://github.com/ksh93/ksh/issues/71
____
* Further details on bug number 2:

At https://github.com/ksh93/ksh/issues/71#issuecomment-786391565
Martijn Dekker wrote:
> I'm back to my original hypothesis that there is somehow an
> off-by-one error related to the ed_setcursor() call that gets
> executed when in multiline mode. I cannot confirm whether that
> off-by-one error is actually in the call itself, or occurs
> sometime earlier on one of the many possible occasions where
> ep->cursor is changed. But everything else appears to work
> correctly, so it's not unlikely that the problem is in the call
> itself.
>
> For reference, this is the original version of that call in
> emacs.c:
>
> ksh/src/cmd/ksh93/edit/emacs.c
> Lines 1556 to 1557 in df2b9bf
>  if(ep->ed->e_multiline && option == REFRESH)
>  	ed_setcursor(ep->ed, ep->screen, ep->cursor-ep->screen, ep->ed->e_peol, -1);
>
> There is a corresponding call in the vi.c refresh() function
> (which does the same thing as draw() in emacs.c), where the third
> (old) and fourth (new) arguments are actually identical:
>
> ksh/src/cmd/ksh93/edit/vi.c
>
> Lines 2086 to 2087 in df2b9bf
>  if(vp->ed->e_multiline && vp->ofirst_wind==INVALID)
>  	ed_setcursor(vp->ed, physical, last_phys+1, last_phys+1, -1);
>
> The expectation for this particular call is in fact that they
> should be identical, so that a delta of zero is calculated in
> that function. Delta not being zero is what causes the cursor to
> be positioned wrong.
>
> In vi.c, last_phys is a macro that is defined as editb.e_peol,
> and editb is a macro that is defined as (*vp->ed). Which means
> last_phys means vp->ed->e_peol, which is the same as
> ep->ed->e_peol in emacs.c. (These editors were originally
> separate programs by different authors, and I suppose this is how
> it shows. Korn didn't want to change all the variable names to
> integrate them, so made macros instead.)
>
> That leaves the question of why vi.c adds 1 to both last_phys
> a.k.a. e_peol arguments, and emacs.c uses e_peol for new without
> adding anything. Analysing the ed_setcursor() code could answer
> that question.
>
> So, this patch makes emacs.c do it the same way vi.c does. Let's
> make the third argument identical to the fourth. My brief testing
> shows the bug is fixed, and the regression tests yield no
> failures. This fix is also the most specific change possible, so
> there are few opportunities for side effects (I hope).

At https://github.com/ksh93/ksh/issues/71#issuecomment-786466652
Lev Kujawski wrote:
> I did a bit of research on this, and I think the fix to have the
> Emacs editing mode do the same as Vi is correct.
>
> From RELEASE:
> 08-05-01 In multiline edit mode, the refresh operation will now clear
> the remaining portion of the last line.
>
> Here's a fragment from the completion.c of the venerable but
> dated CDE DtKsh:
>
>                 else
>                         while (*com)
>                         {
>                                 *out++  = ' ';
>                                 out = strcopy(out,*com++);
>                         }
>                 *cur = (out-outbuff);
>                 /* restore rest of buffer */
>                 out = strcopy(out,stakptr(0));
>                 *eol = (out-outbuff);
>
> Noticeably missing is the code to add a space after file name
> completions. So, it seems plausible that if multiline editing
> mode was added beforehand,the ep->ed->p_eol !=
> ep->cursor-ep->screen case might never have occurred during
> testing.
>
> Setting the 'first' parameter to -1 seems to be a pretty explicit
> indicator that the author(s) intended the line clearing code to
> run, hence the entry in RELASE.
>
> The real issue is that if we update the cursor by calling
> ed_setcursor on line 1554 with old != new, the later call to
> setcursor on line 1583, here:
>
> 	I = (ncursor-nscreen) - ep->offset;
> 	setcursor(ep,i,0);
>
> will use outdated screen information to call setcursor, which,
> coincidentally, calls ed_setcursor.
2021-02-26 11:20:58 +00:00
Martijn Dekker
df2b9bf67f vi: fix buffer corruption after filename completion (re: 4cecde1d)
This bug was backported along with a fix from 93v-. An inconsistent
state occurred if you caused a file name completion menu to appear
with two TABs (which also puts you in command mode) but then
re-enter insert mode (e.g. with 'a') instead of entering a number.

    $ set -o vi
    $ cd /
    $ bin/p    [press TAB twice]
    1) pax
    2) ps
    3) pwd     [now type 'a', 'wd', return]
    $ bin/pwd
    >          [PS2 prompt wrongly appears; press return]
    /
    $

Here's another reproducer, suggesting the problem is a write past
the end of the screen buffer:

    $ set -o vi
    $ cd /
    $ bin/p    [press TAB twice]
    1) pax
    2) ps
    3) pwd     [press '0', then '$']
    $ bin/p    [cursor is one too far to the right, past the 'p'!]
    [Further operations show random evidence of memory corruption]

Harald van Dijk found the cause (thanks!):
> In vi.c's textmod there is
>
> case '=':               /** list file name expansions **/
> ...
>         ++last_virt;
> ...
>         if(ed_expand(vp->ed,(char*)virtual, &cur_virt, &last_virt, ch, vp->repeat_set?vp->repeat:-1)<0)
>         {
> ...
>                 last_virt = i;
> ...
>         }
>         else if((c=='=' || (c=='\\'&&virtual[last_virt]=='/')) && !vp->repeat_set)
>         {
> ...
>         }
>         else
>         {
> ...
>                 --last_virt;
> ...
>         }
>         break;
>
> That middle block does not restore last_virt, and everything goes
> wrong after that. That function used to restore last_virt until
> commit 4cecde1 (#41). The commit message says it was taken from
> ksh93v- and indeed this bug is also present in that version too.
> If I restore the last_virt = i; that was there originally, like
> below, then this bug seems to be fixed. I do not know why it was
> taken out, taking it out does not seem to be necessary to fix the
> original bug.

src/cmd/ksh93/edit/vi.c: textmod():
- Restore the missing restore of last_virt.

src/cmd/ksh93/tests/pty.sh:
- Add test that checks basic completion menu functionality works
  and runs modified versions of the two reproducers above.

Resolves: https://github.com/ksh93/ksh/issues/195
2021-02-26 02:01:09 +00:00
Martijn Dekker
82d6272733 manual: invocation options: edits for clarity
src/cmd/ksh93/data/builtins.c:
- sh_optksh[]: Edit descriptions of -c and -s options for clarity.
- sh_set[]: The --rc long name equivalent for -E was documented
  wrong, but in any case it does not belong in sh_set[], because
  that also shows up in 'set --man' and this invocation-only option
  cannot be used with 'set'. Remove it. (Note that all other
  invocation options already don't have inline documentation of
  their long equivalents. This may or may not be fixed at some
  point. It is problematic because they should not be documented in
  sh_set[] but there is no other good place for them.)

src/cmd/ksh93/sh.1:
- Generally edit the Invocation section for clarity.
- Document the long invocation option equivalents.
- Remove some nonsense from the -s description: "Shell output,
  except for the output of the Special Commands listed above, is
  written to file descriptor 2" (which is standard error).
  In fact, this option has no influence at all on what is written
  to standard error or standard output.
2021-02-25 17:22:53 +00:00
Martijn Dekker
caf7ab6c71 Make PATH properly survive a shared-state ${ comsub; }
Reproducer:

$ ksh -c 'v=${ PATH=/dev/null; }; echo $PATH; whence ls'
/dev/null
/bin/ls

The PATH=/dev/null assignment should survive the shared-state
command substitution, and does, yet 'ls' is still found.
The variable became inconsistent with the internal pathlist.

This bugfix is from the 93v- beta.

src/cmd/ksh93/sh/subshell.c: sh_subshell():
- Do not save and restore pathlist for a subshare.
- A few other subshell tweaks from 93v- that made sense:
  . reset shp->subdup (bitmask for dups of 1) after saving it
  . use e_dot instead of "." for consistency
  . retry close(1) if it was interrupted

src/cmd/ksh93/tests/path.sh:
- Add test for this bug.
2021-02-23 22:16:06 +00:00
Martijn Dekker
e3882fe71b Only run pty tests on systems where pty is known to be good
On some systems (AIX, HP-UX, OpenBSD) the pty tests may hang.

On all systems except Darwin/macOS, FreeBSD and Linux, the pty
tests show one or more regressions. But when I try out the failing
tests manually in a real session, it seems to work fine. So I
suspect pty is broken and not ksh.

src/cmd/ksh93/tests/pty.sh:
- For now, only run the pty tests on Darwin, FreeBSD and Linux.

src/lib/libast/Mamfile:
- tvsleep.c: Add missing error.h dependency (re: 2f7918de).
  (unrelated, but just wasn't worth its own commit)
2021-02-23 10:54:56 +00:00
Johnothan King
733f70e94b
Fix many compiler warnings and remove unused variables (#191)
Most of these changes remove unused variables, functions and labels
to fix -Wunused compiler warnings. Somewhat notable changes:

src/cmd/ksh93/bltins/print.c:
- Removed the unused 'neg' variable.
  Patch from ksh2020: https://github.com/att/ast/pull/725

src/cmd/ksh93/bltins/sleep.c:
- Initialized ns to fix three -Wsometimes-uninitialized warnings.

src/cmd/ksh93/edit/{emacs,vi}.c:
- Adjust strncpy size to fix two -Wstringop-truncation warnings.

src/cmd/ksh93/include/shell.h:
- The NOT_USED macro caused many -Wunused-value warnings,
  so it has been replaced with ksh2020's macro:
  https://github.com/att/ast/commit/19d0620a

src/cmd/ksh93/sh/expand.c:
- Removed an unnecessary 'ap = ' since 'ap' is never read
  between stakseek and stakfreeze.

src/cmd/ksh93/edit/vi.c: refresh():
- Undef this function's 'w' macro at the end of it to stop it
  potentially interfering with future code changes.

src/cmd/ksh93/sh/nvdisc.c,
src/lib/libast/misc/magic.c,
src/lib/libast/regex/regsubexec.c,
src/lib/libast/sfio/sfpool.c,
src/lib/libast/vmalloc/vmbest.c:
- Fixed some indentation to silence -Wmisleading-indentation
  warnings.

src/lib/libast/include/ast.h:
- For clang, now only suppress hundreds of -Wparentheses warnings
  as well as a few -Wstring-plus-int warnings.
  Clang's -Wparentheses warns about things like
  	if(foo = bar())
  which assigns to foo and checks the assigned value.
  Clang wants us to change this into
  	if((foo = bar()))
  Clang's -Wstring-plus-int warns about things like
  	"string"+x
  where x is an integer, e.g. "string"+3 represents the string
  "ing". Clang wants us to change that to
  	"string"[3]
  The original versions represent a perfectly valid coding style
  that was common in the 1980s and 1990s and is not going to change
  in this historic code base. (gcc does not complain about these.)

Co-authored-by: Martijn Dekker <martijn@inlv.org>
2021-02-22 22:16:32 +00:00
Martijn Dekker
83630f9d1c editors: fix broken SIGWINCH handling
In the emacs editor:
 1.  press ESC
 2.  change the size of your terminal window
and your screen is mysteriously cleared. (Until recent fixes, the
shell probably also crashed somewhere in the job control code.)

The cause is the way SIGWINCH is handled by ed_read() in edit.c.
For the emacs editor, it sends a Ctrl+L character to the input
buffer. The Ctrl+L command refreshes the command line. And it so
happens that ESC plus Ctrl+L is a command to clear the screen in
the emacs editor.

With the exeption of vi insert/command mode for which it uses a
shared flag, edit.c does not know the state of the editor, because
their data are internal to emacs.c and vi.c. So it doesn't know
whether you're in some mode that treats keyboard input specially.
Which means this way of dealing with SIGWINCH is fundamentally
misdesigned and is not worth fixing.

It gets sillier: in addition to sending keyboard commands, edit.c
was also communicating directly with emacs.c and vi.c via a flag,
e_nocrnl, which means 'please don't make Ctrl+L emit a linefeed'
(it normally refreshes on a new line but that is undesirable for
SIGWINCH). So there is already a hack that breaks the barrier
between edit.c and emacs.c/vi.c. Let's do that properly instead.

As of this commit, ed_read() does not send any fake keystrokes.
Instead, two extern functions, emacs_redraw() and vi_redraw(), are
defined for redrawing the command line. These are put in emacs.c
and vi.c so they have access to relevant static data and functions.
Then, instead of sending keyboard commands to the editor and
returning, ed_read() simply calls the redraw function for the
active editor, then continues and waits for input. Much cleaner.

src/cmd/ksh93/include/edit.h:
- Remove e_nocrnl flag from Edit_t struct.
- Define externs emacs_redraw() and vi_redraw(). Since Emacs_t and
  Vi_t types are not known here, we have to declare void* pointers
  and the functions will have to use typecasts.

src/cmd/ksh93/edit/edit.c:
- ed_read(): Call emacs_redraw() or vi_redraw() as per above.
- ed_getchar(): Remove comment about a nonexistent while loop.

src/cmd/ksh93/edit/emacs.c:
- Updates corresponding to removal of e_nocrnl flag.
- Add emacs_redraw(). This one is pretty simple. Refresh the
  command line, then ed_flush() to update the cursor display.

src/cmd/ksh93/edit/vi.c:
- Updates corresponding to removal of e_nocrnl flag. Also remove a
  similar internal 'nonewline' flag which is now equally redundant.
- Move the Ctrl+L handling code (minus writing the newline) into
  the vi_redraw() function.
- Change two cases where vi set nonewline and sent Ctrl+L to itself
  into simple vi_redraw() calls.
- Add vi_redraw(). This is more complicated as it incorporates the
  previous Ctrl+L code. It needs an added refresh() call with a
  check whether we're currently in command or insert mode, as those
  use different refresh methods. Luckily edit.c already maintains
  an *e_vi_insert flag in ed_getchar() that we can use. Since vi's
  refresh() already calls ed_flush(), we don't need to add that.
2021-02-22 00:11:59 +00:00
Martijn Dekker
18529b88c6 Add lots of checks for out of memory (re: 0ce0b671)
Huge typeset -L/-R adjustment length values were still causing
crashses on sytems with not enough memory. They should error out
gracefully instead of crashing.

This commit adds out of memory checks to all malloc/calloc/realloc
calls that didn't have them (which is all but two or three).

The stkalloc/stakalloc calls don't need the checks; it has
automatic checking, which is done by passing a pointer to the
outofspace() function to the stakinstall() call in init.c.

src/lib/libast/include/error.h:
- Change the ERROR_PANIC exit status value from ERROR_LEVEL (255)
  to 77, which is what it is supposed to be according to the libast
  error.3 manual page. Exit statuses > 128 for anything else than
  signals are not POSIX compliant and may cause misbehaviour.

src/cmd/ksh93/include/defs.h,
src/cmd/ksh93/sh/init.c:
- To facilitate consistency, add a simple extern sh_outofmemory()
  function that throws an ERROR_PANIC "out of memory".

src/cmd/ksh93/include/shell.h,
src/cmd/ksh93/data/builtins.c:
- Remove now-redundant e_nospace[] extern message; it is now only
  used in one place so it might as well be a string literal in
  sh_outofmemory().

All other changed files:
- Verify the result of all malloc/calloc/realloc calls and call
  sh_outofmemory() if they fail.
2021-02-21 22:27:28 +00:00
hyenias
0ce0b67149
Fix segmentation fault for justified strings (re: bdb99741) (#190)
Additional adjustments to previous commit bdb9974 to correct
crashes when the max size of a justified string is requested.
This commit corrects the following:

Before (Ubuntu 64bit):
$ typeset -L $(((1<<31)-1)) s=h; typeset +p s
Segmentation fault (core dumped)

After:
$ typeset -L $(((1<<31)-1)) s=h; typeset +p s
typeset -L 2147483647 s

src/cmd/ksh93/sh/name.c: nv_putval():
- Alter the variables size, dot, and append from int to unsigned
  int to prevent unwanted negative values from being expressed.
- By creating size, dot, and append as unsigned ints; (unsigned)
  type casting is avoided.
2021-02-21 09:34:18 +00:00
Martijn Dekker
51b2e360fa job_reap(): fix use of unitialised pointer
This solves another intermittent crash that happened upon
processing SIGWINCH in the emacs editor. See also: 7ff6b73b

I found this bug while testing ksh 93u+m on OpenBSD. Due to its
pervasive security hardening, this system crashes a program
reliably where others crash it intermittently, which is invaluable.

src/cmd/ksh93/sh/jobs.c: job_reap():
- The pw pointer is not ever given a value if the loop breaks on
  line 318-319, but it is used unconditionally on lines 464-470,
  Initialise the pointer to null on function entry and do not call
  job_list() and job_unpost() if the pointer is still null.
2021-02-20 23:40:00 +00:00
Martijn Dekker
f57f7b7a19 emacs: more correct fix (re: 9ccb9572)
sptr is set to drawbuff, but may change; drawbuff itself will not
change and reading before the start of that was the actual cause of
the crash.
2021-02-20 22:12:23 +00:00
Martijn Dekker
9ccb9572f3 emacs: fix crash due to read before start of buffer
It's amazing what can happen when you compile ksh using standard
malloc (i.e. with AST vmalloc disabled) on OpenBSD. Its security
hardening provokes crashes that reveal decades-old unsolved bugs.
This one is an attempt to access one byte before the beginning of
the command line buffer when the cursor is at the beginning of it.
On this system configuration, it provoked an instant crash whenever
you moved the cursor back to the beginning of the command line,
e.g. with ^A or the cursor keys.

src/cmd/ksh93/edit/emacs.c: draw():
- Check that the cursor is actually past the first position of the
  command line buffer before trying to read the position
  immediately before it. If not, zero the value.
2021-02-20 21:09:01 +00:00
Martijn Dekker
500757d78b Error out on 'redirect >foo' inside ${ shared-state comsub; }
The following caused an infinite loop:

        v=${ exec >/dev/tty; }
        v=${ redirect >/dev/tty; }

Even the original authors didn't figure out how to 'exec >foo' or
'redirect >foo' inside a non-forking command substitution, so they
fork it by calling sh_subfork(). If we delete that call, even
normal command substitutions enter into that infinite loop. But of
course a shared-state comsub can never fork as it would no longer
share its state. Without a solution to make this work without
forking, an error message is the only sensible thing left to do.

src/cmd/ksh93/sh/io.c: sh_redirect():
- If we're redirecting standard output (1), the redirection is
  permanent as in 'exec'/'redirect' (flag==2), and we're in a
  subshare, then error out.

Resolves: https://github.com/ksh93/ksh/issues/128
2021-02-20 19:52:08 +00:00
sterlingjensen
e1690f61ff
package: Fix unspecified behavior after "unset PWD" (#176)
POSIX warns about "unset PWD" leading to unspecified behavior from
the pwd util, which we then use.

bin/package, src/cmd/INIT/package.sh:
- Determine if the shell has $PWD with a feature test. Only unset
  PWD if it does not (the old Bourne shell).
- Clean up 'case' flow.

Co-authored-by: Martijn Dekker <martijn@inlv.org>
2021-02-20 13:58:52 +00:00
Martijn Dekker
bdb997415d Fix multiple buffer overflows with justified strings (-L/-R/-Z)
ksh crashed in various different and operating system-dependent
ways when attempting to create or apply justification strings
using typeset -L/-R/-Z, especially if large sizes are used.

The crashes had two immediate causes:
- In nv_newattr(), when applying justification attributes, a buffer
  was allocated for the justified string that was exactly 8 bytes
  longer than the original string. Any larger justification string
  caused a buffer overflow (!!!).
- In nv_putval(), when applying existing attributes to a new value,
  the corresponding memmove() either did not zero-terminate the
  justified string (if the original string was longer than the
  justified string) or could read memory past the original string
  (if the original string was shorter than the justified string).
  Both scenarios can cause a crash.

This commit fixes other minor issues as well, such as a mysterious
8 extra bytes allocated by several malloc/realloc calls. This may
have been some naive attempt to paper over the above bugs. It seems
no one can make any other kind of sense of it.

A readjustment bug with zero-filling was also fixed.

src/cmd/ksh93/sh/name.c:
- nv_putval():
  . Get rid of the magical +8 bytes for malloc and realloc. Just
    allocate one extra byte for the terminating zero.
  . Fix the memmove operation to use strncpy instead, so that
    buffer overflows are avoided in both scenarios described above.
    Also make it conditional upon a size adjustment actually
    happening (i.e. if 'dot' is nonzero).
  . Mild refactoring: combine two 'if(sp)' blocks into one;
    declare variables only used there locally for legibility.
- nv_newattr():
  * Replace the fatally broken "let's allocate string length + 8
    bytes no matter the size of the adjustment" routine with a new
    one based on work by @hyenias (see comments in #142). It is
    efficient with memory, taking into account numeric types,
    growing strings, and shrinking strings.
  * Fix zero-filling in readjustment after changing the initial
    size of a -Z attribute. If the number was zero, all zeros were
    still skipped, leaving an empty string.

Thanks to @hyenias for originally identifying this breakage and
laying the groundwork for fixing nv_newattr(), and to @lijog for
the crash analysis that revealed the key to the nv_putval() fix.

Resolves: https://github.com/ksh93/ksh/issues/142
Resolves: https://github.com/ksh93/ksh/issues/181
2021-02-20 13:05:38 +00:00
Martijn Dekker
a959a35291 DEBUG trap: restore status 2 trigger to skip command (re: d00b4b39)
So now we know what that faulty check for shp->indebug in sh_trap()
was meant to do: it was meant to pass down the trap handler's exit
status, via sh_debug(), down to sh_exec() (xec.c) so that it could
then skip the execution of the next command if the trap's exit
status is 2, as documented in the manual page. As of d00b4b39, exit
status 2 was not passed down, so this stopped working.

This commit reinstates that functionality, but without the exit
status bug in command substitutions caused by the old way.

src/cmd/ksh93/sh/fault.c: sh_trap():
- Save the trap's exit status before restoring the parent
  envionment's exit status. Make this saved exit status the return
  value of the function. (This does not break anything, AFAICT; the
  majority of sh_trap() calls ignore the return value, and the few
  that don't ignore it seem to expect it to return exactly this.)

src/cmd/ksh93/sh/xec.c: sh_exec():
- The sh_trap() fix has one side effect: whereas the exit status of
  a skipped command was always 2 (as per the trap handler), now it
  is always 0, because it gets reset in sh_exec() but no command is
  executed. That is probably not a desirable change in behaviour,
  so let's fix that here instead: set sh.exitval to 2 when skipping
  commands.

src/cmd/ksh93/sh.1:
- Document that ${.sh.command} shell-quotes its arguments for use
  by 'eval' and such. This fact was not documented anywhere, AFAIK.

src/cmd/ksh93/shell.3:
- Document that $? (exit status) is made local to trap handlers.
- Document that sh_trap() returns the trap handler's exit status.

src/cmd/ksh93/tests/basic.sh:
- Add test for this bug.
- Add a missing test for the exit status 255 functionality (if a
  DEBUG trap handler yields this exit status and we're executing a
  function or dot script, a return is triggered).

Fixes: https://github.com/ksh93/ksh/issues/187
2021-02-20 05:13:51 +00:00
Johnothan King
2b805f7f1c
Fix many spelling errors and word repetitions (#188)
Many of the errors fixed in this commit are word repetitions
such as 'the the' and minor spelling errors. One formatting
error in the ksh man page has also been fixed.
2021-02-20 03:22:24 +00:00
Lev Kujawski
4e47f89b06
libast: Improve and harden tvsleep (re: 72968eae) (#186)
On SVR4 platforms, select is a sometimes erroneous wrapper around
the poll system call, so call poll directly for efficiency purposes if
it implies no loss in precision.

See, e.g., http://bugs.motifzone.net/long_list.cgi?buglist=129 .

src/lib/libast/features/tvlib:
- For systems lacking nanosleep, test whether select is truly more
  precise than poll.

src/lib/libast/tm/tvsleep.c:
- Verify that tv argument is not null.
- Immediately return if asked to sleep for a duration of zero.
- Immediately initialize timespec in the nanosleep case.
- Revise variable names to use Apps Hungarian.
- Use poll instead of select when there is no loss in precision.
- Check for overflow in the poll case.
- Improve comments.
- Revise arithmetic to work with unsigned types, rather than
  casting to long.
- Do not return non-zero if we have slept for a sufficient
  time.
2021-02-19 22:58:04 +00:00
Martijn Dekker
350b52ea4e Update comsub-with-alias anti-leak hack (re: fe20311f)
In the 93v- beta, they add a newline instead of a space.
This has fewer side effects as final newlines get stripped.
It's still a hack and it would still be nice to have a real fix,
but it seems even the AT&T guys couldn't come up with one.

src/cmd/ksh93/sh/macro.c:
- To somehow avoid a memory leak involving alias substitution,
  append a linefeed instead of a space to the comsub buffer.

src/cmd/ksh93/tests/subshell.sh:
- Add test for minor regression caused by the RedHat version.
2021-02-18 23:35:20 +00:00
Lev Kujawski
72968eaed6
Revise the pow(1,inf) IEEE feature test to defeat clever compilers (#184)
Compilers like GCC are capable of optimizing away calls like
pow(1,inf), which caused the IEEE compliance feature test within
libast to incorrectly succeed on platforms with non-IEEE behavior.

This is arguably a bug within GCC, as floating point optimizations
should never alter the behavior of code unless IEEE compliance is
explicitly disabled via a flag like -ffast-math. Programs in which
only some calls to pow are optimized away are liable to severely
malfunction.

Thanks to Martijn Dekker for pointing this issue out and the kind
operators of polarhome.com for permitting me gratis use of their
Unix systems.

src/lib/libast/comp/omitted.c:
- Add IEEE compliant functions that wrap powf, pow, and powl.

src/lib/libast/features/float:
- Look for powf, pow, and powl in the C library.
- For compilers that do the right thing, like the native toolchains
  of Solaris and UnixWare, use lightweight macros to wrap the pow
  functions.
- Use a volatile function pointer through which to access the C
  library's pow function in an attempt to defeat code optimization.
- For these overzealous compilers, define pow to _ast_pow so that
  the same technique can be used within the above functions.
2021-02-18 18:45:27 +00:00
Martijn Dekker
c2cb0eae19 Make 'read' compatible with Shift-JIS
This commit fixes a bug in the 'read' built-in: it did not properly
skip over multibyte characters. The bug never affects UTF-8 locales
because all UTF-8 bytes have the high-order bit set. But Shift-JIS
characters may include a byte corresponding to the ASCII backslash
character, which cauased buggy behaviour when using 'read' without
the '-r' option that disables backslash escape processing.

It also makes the regression tests compatible with Shift-JIS
locales. They failed with syntax errors.

src/cmd/ksh93/bltins/read.c:
- Use the multibyte macros when skipping over word characters.
  Based on a patch from the old ast-developers mailing list:
  https://www.mail-archive.com/ast-developers@lists.research.att.com/msg01848.html

src/cmd/ksh93/include/defs.h:
- Be a bit smarter about causing the compiler to optimise out
  multibyte code when SHOPT_MULTIBYTE is disabled. See the updated
  comment for details.

src/cmd/ksh93/tests/locale.sh:
- Put all the supported locales in an array for future tests.
- Add test for the 'read' bug. Include it in a loop that tests
  64 SHIFT-JIS character combinations. Only one fails on old ksh:
  the one where the final byte corresponds to the ASCII backslash.
  It doesn't hurt to test all the others anyway.

src/cmd/ksh93/tests/basic.sh,
src/cmd/ksh93/tests/builtins.sh,
src/cmd/ksh93/tests/quoting2.sh:
- Fix syntax errors that occurred in SHIFT-JIS locales as the
  parser was processing literal UTF-8 characters. Not executing
  that code is not enough; we need to make sure it never gets
  parsed as well. This is done by wrapping the commands containing
  literal UTF-8 strings in an 'eval' command as a single-quoted
  operand.

.github/workflows/ci.yml:
- Run the tests in the ja_JP.SJIS locale instead of ja_JP.UTF-8.
  UTF-8 is already covered by the nl_NL.UTF-8 test run; that should
  be good enough.
2021-02-18 16:07:12 +00:00
Martijn Dekker
8c2d8e5f46 Revert 096f46ee ("Fix for memory mgmt in variable expansion")
This reverts a Solaris patch (105-CR7032068) with no documentation
on what it fixes or how or why. There are reports about it causing
a crash and/or a regression:

https://github.com/ksh93/ksh/issues/180#issuecomment-780980442
2021-02-18 02:05:39 +00:00
Martijn Dekker
50b665b1ed Revert 0e4c4d61 ("Fix minor typeset attribute regressions")
This commit introduced the following bug, which is worse than the
one that commit fixed: it became impossible to alter the size of an
existing justified string attribute.

Thanks to @hyenias for catching this bug:
https://github.com/ksh93/ksh/issues/142#issuecomment-780931533

$ unset s; typeset -L 100 s=h; typeset +p s; typeset -L 5 s; typeset +p s
typeset -L 100 s
typeset -L 100 s

Expected output:
typeset -L 100 s
typeset -L 5 s

src/cmd/ksh93/sh/name.c:
- Revert.

src/cmd/ksh93/tests/attributes.sh:
- Revert: re-disable tests for minor attribute output regressions.
- Add a test for this bug and potential similar bugs.
2021-02-18 01:11:53 +00:00
Martijn Dekker
241b5a4af5 tests/variables.sh: now also test PATH (re: 222515bf) 2021-02-17 18:06:15 +00:00
Martijn Dekker
911d6b066f Fix subshell scoping of changes in shared command substitution
A ${ shared-state command substitution; } (internally called
subshare) is documented to share its state with the parent shell
environment, so all changes made within the command substitution
survive outside of it. However, when it is run within a
virtual/non-forked subshell, variables that are not already local
to that subshell will leak out of it into the grandparent state.
Reproducer:

	$ ksh -c '( v=${ bug=BAD; } ); echo "$bug"'
	BAD

If the variable pre-exists in the subshell, the bug does not occur:

	$ ksh -c '( bug=BAD1; v=${ bug=BAD2; } ); echo "$bug"'
	(empty line, as expected)

The problem is that the sh_assignok() function, which is
responsible for variable scoping in virtual subshells, does not
ever bother to create a virtual subshell scope for a subshare.
That is an error if a subshare's parent (or higher-up ancestor)
environment is a virtual subshell, because a scope needs to be
created in that parent environment if none exists.

To make this bugfix possible, first we need to get something out of
the way. nv_restore() temporarily sets the subshell's pointer to
the preesnt working directory, shpwd, to null. This causes
sh_assignok() to assume that the subshell is a subshare (because
subshares don't store their own PWD) and refuse to create a scope.
However, nv_restore() sets it to null for a different purpose: to
temporarily disable scoping for *all* virtual subshells, making
restoring possible. This is a good illustration of why it's often
not a good idea to use the same variable for unrelated purposes.

src/cmd/ksh93/sh/subshell.c:
- Add a global static subshell_noscope flag variable to replace the
  misuse of sh.shpwd described above.
- sh_assignok():
  . Check subshell_noscope instead of shpwd to see if scope
    creation is disabled. This makes it possible to distinguish
    between restoring scope and handling subshares.
  . If the current environment is a subshare that is in a virtual
    subshell, create a scope in the parent subshell. This is done
    by temporarily making the parent virtual subshell the current
    subshell (by setting the global subshell_data pointer to it)
    and calling sh_assignok() again, recursively.
- nv_restore(): To disable subshell scope creation while restoring,
  set subshell_noscope instead of saving and unsetting sh.shpwd.

src/cmd/ksh93/tests/subshell.sh:
- Add tests. I like tests. Tests are good.

Fixes: https://github.com/ksh93/ksh/issues/143
2021-02-17 15:33:48 +00:00
Johnothan King
a282ebc8fe
Fix emacs backslash escaping behavior (#179)
This commit fixes the following:

1. Emacs mode ignores --nobackslashctrl (re: 24598fed) when in
   reverse search.

2. When entering more than one backslash, emacs reverse search mode
   deletes multiple backslashes after pressing backspace once.
   Reproducer:
   $ set --emacs --nobackslashctrl
   $ <Ctrl+R> \\\\<Backspace>

3. Except when in reverse search, the backslash fails to escape a
   subsequent interrupt character (^C). Reproducer:
   $ set --emacs --backslashctrl
   $ teststring \<Ctrl+C>

src/cmd/ksh93/edit/emacs.c:
- Disable escaping backslashes in emacs reverse search if
  'nobackslashctrl' is enabled.
- Fix the buggy behavior of backslashes in emacs reverse
  search by processing backslashes in a loop.

src/cmd/ksh93/tests/pty.sh:
- Add regression tests.

src/cmd/ksh93/sh.1:
- Fix a minor documentation error (^C is the usual interrupt
  character, not ^?).

Co-authored-by: Martijn Dekker <martijn@inlv.org>
2021-02-17 14:29:12 +00:00
Martijn Dekker
fe74702766 Fix miscellaneous typos 2021-02-16 16:45:06 +00:00
Martijn Dekker
3a315f58f6 More 'case' regression tests (re: e37aa358)
Ref.: https://github.com/ksh93/ksh/issues/177
2021-02-16 13:36:50 +00:00
Martijn Dekker
e37aa358bf Fix BUG_CASEEMPT: empty 'case' list was syntax error
'case x in esac' should be syntactically correct, but was an error:

	$ ksh -c 'case x in esac'
	ksh: syntax error at line 1: `case' unmatched

Inserting a newline was a workaround:

	$ ksh -c $'case x in\nesac'
	(no output)

The problem was that the 'esac' reserved word was not being
recognised if it immediately followed the 'in' reserved word.

src/cmd/ksh93/sh/lex.c: sh_lex():
- Do not turn off recognition of reserved words after 'in' if we're
  in a 'case' construct; only do this for 'for' and 'select'.

src/cmd/ksh93/tests/case.sh:
- Add seven regression test for correct recognition of 'esac'.
  Only two failed on ksh93. The rest is to catch future bugs.

Fixes: https://github.com/ksh93/ksh/issues/177
2021-02-16 06:50:12 +00:00
Johnothan King
29b11bba3a
Fix the Alt+D and Alt+H keyboard shortcuts in emacs mode (#178)
This commit fixes the functionality of Alt+D and Alt+H in emacs mode.
These keyboard shortcuts are intended to work on whole words, but
after commit 13c3fb21 their functionality was reduced to deleting only
singular letters:

$ Test word <Alt+H>    # This should delete 'word', not just 'd'.
$ Foo <Alt+B> <Alt+D>  # This should delete 'Foo', not just 'F'.

Man page entries for reference:
  M-d       Delete current word.
  M-^H      (Meta-backspace) Delete previous word.
  M-h       Delete previous word.

src/cmd/ksh93/edit/emacs.c:
- 'count' cannot be overridden when handling Alt+D or Alt+H,
  so add the total number of repetitions to count (the number of
  repetitions can't be negative).
- If 'count' is a negative number, set it to one before adding the
  number of repetitions.
2021-02-16 01:47:15 +00:00
Martijn Dekker
24598fed7c Add new 'nobackslashctrl' shell option; other minor editor tweaks
The following emacs editor 'feature' kept making me want to go back
to bash. I forget a backslash escape in a command somewhere. So I
go back to insert it. I type the \, then want to go forward. My
right arrow key, instead of moving the cursor, then replaces my
backslash with garbage. Why? The backslash escapes the following
control character at the editor level and inserts it literally.

The vi editor has a variant of this which is much less harmful. It
only works in insert mode and the backslash only escapes the next
kill or erase character.

In both editors, this feature is completely redundant with the
'stty lnext' character which is ^V by default -- and works better
as well because it also escapes ^C, ^J (linefeed) and ^M (Return).

 [In fact, you could even issue 'stty lnext \\' and get a much more
 consistent version of this feature on any shell. You have to type
 two backslashes to enter one, but it won't kill your cursor keys.]

If it were up to me alone, I'd simply remove this misfeature from
both editors. However, it is long-standing documented behaviour.
It's in the 1995 book. Plus, POSIX specifies the vi variant of it.

So, this adds a shell option instead. It was quite trivial to do.
Now I can 'set --nobackslashctrl' in my ~/.kshrc. What a relief!

Note: To keep .kshrc compatibile with older ksh versions, use:
    command set --nobackslashctrl 2>/dev/null

src/cmd/ksh93/include/shell.h,
src/cmd/ksh93/data/options.c:
- Add new SH_NOBACKSLCTRL/"nobackslashctrl" long-form option. The
  "no" prefix shows it to the user as "backslashctrl" which is on
  by default. This avoids unexpectedly changing historic behaviour.

src/cmd/ksh93/edit/emacs.c: ed_emacsread(),
src/cmd/ksh93/edit/vi.c: getline():
- Only set the flag for special backslash handling if
  SH_NOBACKSLCTRL is off.

src/cmd/ksh93/sh.1,
src/cmd/ksh93/data/builtins.c:
- Document the new option (as "backslashctrl", on by default).

Other minor tweaks:

src/cmd/ksh93/edit/edit.c:
- ed_setup(): Add fallback #error if no tput method is set. This
  should never be triggered; it's to catch future editing mistakes.
- escape(): cntl('\t') is nonsense as '\t' is already a control
  character, so change this to just '\t'.
- xcommands(): Let's enable the ^X^D command for debugging
  information on non-release builds.

src/cmd/ksh93/features/cmds:
- The tput feature tests assumed a functioning terminal in $TERM.
  However, for all we know we might be compiling with no tty and
  TERM=dumb. The tput commands won't work then. So set TERM=ansi
  to use a standard default.
2021-02-16 01:29:00 +00:00
Martijn Dekker
786a549e49 test/jobs.sh: use slightly more widely supported ps -o format 2021-02-15 15:41:31 +00:00
Martijn Dekker
5be585f45b tests/options.sh: add forgotten SHOPT_BRACEPAT check (re: af5f7acf) 2021-02-15 01:57:17 +00:00
Martijn Dekker
af5f7acf99 Fix bugs related to --posix shell option (re: 921bbcae, f45a0f16)
This fixes the following:
1. 'set --posix' now works as an equivalent of 'set -o posix'.
2. The posix option turns off braceexpand and turns on letoctal.
   Any attempt to override that in a single command such as 'set -o
   posix +o letoctal' was quietly ignored. This now works as long
   as the overriding option follows the posix option in the command.
3. The --default option to 'set' now stops the 'posix' option, if
   set or unset in the same 'set' command, from changing other
   options. This allows the command output by 'set +o' to correctly
   restore the current options.

src/cmd/ksh93/data/builtins.c:
- To make 'set --posix' work, we must explicitly list it in
  sh_set[] as a supported option so that AST optget(3) recognises
  it and won't override it with its own default --posix option,
  which converts the optget(3) string to at POSIX getopt(3) string.
    This means it will appear as a separate entry in --man output,
  whether we want it to or not. So we might as well use it as an
  example to document how --optionname == -o optionname, replacing
  the original documentation that was part of the '-o' description.

src/cmd/ksh93/sh/args.c: sh_argopts():
- Add handling for explitit --posix option in data/builtins.c.
- Move SH_POSIX syncing SH_BRACEEXPAND and SH_LETOCTAL from
  sh_applyopts() into the option parsing loop here. This fixes
  the bug that letoctal was ignored in 'set -o posix +o letoctal'.
- Remember if --default was used in a flag, and do not sync options
  with SH_POSIX if the flag is set. This makes 'set +o' work.

src/cmd/ksh93/include/argnod.h,
src/cmd/ksh93/data/msg.c,
src/cmd/ksh93/sh/args.c: sh_printopts():
- Do not potentially translate the 'on' and 'off' labels in 'set
  -o' output. No other shell does, and some scripts parse these.

src/cmd/ksh93/sh/init.c: sh_init():
- Turn on SH_LETOCTAL early along with SH_POSIX if the shell was
  invoked as sh; this makes 'sh -o' and 'sh +o' show expected
  options (not that anyone does this, but correctness is good).

src/cmd/ksh93/include/defs.h,
src/cmd/ksh93/include/shell.h:
- The state flags were in defs.h and most (but not all) of the
  shell options were in shell.h. Gather all the shell state and
  option flag definitions into one place in shell.h for clarity.
- Remove unused SH_NOPROFILE and SH_XARGS option flags.

src/cmd/ksh93/tests/options.sh:
- Add tests for these bugs.

src/lib/libast/misc/optget.c: styles[]:
- Edit default optget(3) option self-documentation for clarity.

Several changed files:
- Some SHOPT_PFSH fixes to avoid compiling dead code.
2021-02-14 23:51:19 +00:00
Lev Kujawski
e2d54b7169
sleep: guarantee sleeping specified time at minimum (#174)
With this patch, the Korn shell can now guarantee that calls to
sleep on systems using the select or poll method always result in
the system clock advancing by that much time, assuming no
interruptions. This compensates for deficiencies in certain
systems, including SCO UnixWare.

Discussion: https://github.com/ksh93/ksh/pull/174

src/lib/libast/tm/tvsleep.c:
- Ensure that at least the time requested to sleep has elapsed
  for the select and poll methods.
- Simplify the logic of calculating the time remaining to
  sleep and handle the case of an argument of greater than
  10e9 nanoseconds being passed to tvsleep.

src/cmd/ksh93/bltins/sleep.c:
- Eliminate the check for EINTR to handle other cases wherein
  we have not slept enough.

src/cmd/ksh93/tests/variables.sh:
- Improve the diagnostic message when the sleep test fails.
- Revise the SECONDS function test to expect that we always
  sleep for at least the time specified.

src/cmd/ksh93/tests/functions.h:
- Redirect ps stderr to /dev/null. UnixWare ps prints an error
  message about not being able to find the controlling terminal
  when shtests output is piped, but we are only using ps to find
  the PID.
2021-02-14 07:27:04 +00:00
Martijn Dekker
0e9aaf1635 move exit/return tests from basic.sh to return.sh (re: 092b90da) 2021-02-14 06:32:57 +00:00
Martijn Dekker
21d00ffb6c Fix build on QNX
This makes ksh 93u+m build on the following system:

	$ uname -a
	QNX qnx 6.5.0 2010/07/09-14:44:03EDT x86pc x86

Thanks to polarhome.com for providing the QNX shell account.

There are a number of regressions left to work out:

arrays.sh[636]: copying a large array fails
bracket.sh[129]: /tmp/ksh93.shtests.1753215026.6923/bracket.C/original should be older than /tmp/ksh93.shtests.1753215026.6923/bracket.C/newer
bracket.sh[132]: /tmp/ksh93.shtests.1753215026.6923/bracket.C/newer should be newer than /tmp/ksh93.shtests.1753215026.6923/bracket.C/original
builtins.sh[683]: real_t1 not found after parent directory renamed in subshell
functions.sh[1023]: cannot handle comsub depth > 256 in function
io.sh[252]: <# not working for pipes
io.sh[337]: read -n3 from pipe not working
io.sh[346]: read -n3 from fifo failed -- expected 'a', got 'abc'
io.sh[349]: read -n1 from fifo failed -- expected 'b', got 'd'
io.sh[379]: should have timed out
io.sh[380]: line1 should be 'prompt1: '
io.sh[381]: line2 should be line2
io.sh[382]: line3 should be 'prompt2: '
io.sh[406]: LC_ALL=C read -n2 from pipe 'a bcd' failed -- expected 'a bcd', got 'ab cd'
io.sh[406]: LC_ALL=C.UTF-8 read -n2 from pipe 'a bcd' failed -- expected 'a bcd', got 'ab cd'
jobs.sh[86]: warning: skipping subshell job control test due to non-compliant 'ps'
pty.sh[105]: POSIX sh 026(C): line 120: expected "(Stopped|Suspended)", got EOF
pty.sh[128]: POSIX sh 028(C): line 143: expected "(Stopped|Suspended) \(SIGTTIN\)", got EOF
pty.sh[151]: POSIX sh 029(C): line 166: expected "(Stopped|Suspended) \(SIGTTOU\)", got EOF
signal.sh[310]: kill -TERM $$ failed, required termination by signal 'EXIT'
signal.sh[310]: kill -VTALRM $$ failed, required termination by signal 'EXIT'
signal.sh[310]: kill -PIPE $$ failed, required termination by signal 'EXIT'

(The io.sh failures mean libast sfpkrd() is not working.)

src/lib/libast/obsolete/spawn.c:
- Removed. Didn't compile due to wrong number of arguments to
  spawnve(2), but is obsolete and unused.

src/lib/libast/comp/localeconv.c:
- The initialisation of two static 'struct lconv' variables was
  done in a way that depended on OS headers declaring the struct
  members in a certain order. This holds on most systems, but not
  on QNX, and POSIX does not actually specify the order at all:
	https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/locale.h.html
  So each member must be initialised by name. But C89 does not
  support initialising struct members by name, so we have to do it
  using an initialiser function that simply assigns the values.

src/lib/libast/comp/spawnveg.c:
- Fix for systems without either P_DETACH or _P_DETACH.

src/lib/libast/features/vmalloc,
src/lib/libast/vmalloc/vmmopen.c,
src/lib/libast/Mamfile:
- Add test for sys/shm.h header. If it doesn't exist, as it doesn't
  on QNX, use the stub vmmapopen() as the real one won't compile.
  (Mamfile: Add dependency on FEATURE/vmalloc to vmmopen.c.)

src/lib/libast/vmalloc/malloc.c:
- Remove superfluous externs that are already provided by either
  AST or system headers. The 'void cfree' extern caused a build
  failure on QNX because cfree() is of type int on QNX.

src/lib/libast/comp/conf.tab:
- Remove check for _map_spawnve; src/lib/libast/RELEASE says it was
  removed.
2021-02-14 01:28:35 +00:00
Martijn Dekker
cd35ec6048 tests/builtins.sh: fix fail due to translated system messages
(re: f7ffaaba, d1483150)
2021-02-13 23:27:43 +00:00
Martijn Dekker
fb7551634a Fix exec/redirect (fd != 1) in shared-state comsub (re: db72f41f)
That OpenSUSE patch introduced a bug: file descriptors other than 1
that were globally redirected using 'exec' or 'redirect' no longer
survived a ${ shared-state; } command substitution.

Related: https://github.com/ksh93/ksh/issues/128

src/cmd/ksh93/sh/io.c:
- Add check for shp->subshare to the OpenSUSE patch.

src/cmd/ksh93/tests/io.sh:
- Add test.
2021-02-13 16:01:42 +00:00
Martijn Dekker
5529d13d28 tests/pty.sh: avoid typeahead: add 10ms delay (re: 5c389035)
We can't actually check for the typeahead effects as they are
timing-dependent and do not work on the slower GitHub runners.
2021-02-13 14:30:40 +00:00
Martijn Dekker
d790731a80 github: Revert failed experiment (re: 2e6c56df, 9ad9a1de, 5c389035)
.github/workflows/ci.yml:
- Go back to wrapping the regression tests in script(1).

src/cmd/ksh93/data/builtins.c:
- Never mind about the stty builtin.

src/cmd/ksh93/tests/pty.sh:
- Refuse to run if there isn't a functioning tty.
- Make sure stty(1) works on /dev/tty by redirecting stdin.
2021-02-13 13:52:14 +00:00
Martijn Dekker
2e6c56df82 github: Try to make the tests pass (re: 9ad9a1de, 5c389035)
So, the pty regression tests on the Linux GitHub runner all failed.

Let's test an assumption: the reason is that we need the stty
builtin to properly set the pty state, because the OS-provided stty
command does not work if there is no real tty.

src/cmd/ksh93/data/builtins.c:
- Compile in the stty built-in. This adds about 20k to the binary
  for a command that most users rarely need and even more rarely
  need to be built in, so only compile it in on non-release builds.

src/cmd/ksh93/tests/pty.sh:
- Skip the tests if we cannot either use the stty builtin or change
  the state of the real terminal to be compatible with the tests.
2021-02-13 13:15:46 +00:00
Martijn Dekker
9ad9a1de44 github: Re-disable Mac CI runner (re: 5c389035)
The Mac runner is still broken: intermittent pipe- and
signal-related regressions that do not occur on any real Mac.
https://github.com/ksh93/ksh/runs/1892358749

.github/workflows/ci.yml:
- Remove the macOS runner.

src/cmd/ksh93/tests/pty.sh:
- Do not skip pty tests if there is no tty. (On FreeBSD with no
  tty, the tty builtin would need to be enabled in builtins.c.)

src/cmd/ksh93/tests/bracket.sh:
- Don't be noisy when skipping unavailable locales.
2021-02-13 06:58:30 +00:00
Martijn Dekker
5c389035d8 shtests: Stop requiring a tty
It is desirable to be able to run the tests on a system without
a functioning tty. Since this distribution comes with its own
pseudo-tty facility, pty, it should be possible to run the few
tests that require a tty on the pseudo-tty instead. I've verified
that they fail as expected on older ksh93.

Discussion: https://github.com/ksh93/ksh/pull/171

src/cmd/ksh93/tests/basic.sh,
src/cmd/ksh93/tests/bracket.sh:
- Remove tests that require a tty.

src/cmd/ksh93/tests/pty.sh:
- Put them here, adapted to work as interactive pty scripts.

src/cmd/ksh93/tests/shtests:
- No longer refuse to run if there is no functioning tty.

.github/workflows/ci.yml:
- Since the tests no longer require a tty, no longer use script(1)
  to get a pseudo-tty. Let's see if this works...
- Re-enable the Mac runner (re: 14632361). Maybe it has improved.
2021-02-13 05:55:27 +00:00
Lev Kujawski
a7121b6689
Implement leak detection on UnixWare (#172)
src/cmd/ksh93/tests/leaks.sh: Read vsz from UnixWare's ps

UnixWare's ps reports an accurate virtual size, so collecting that is
preferable to trying to parse the real resident size.
2021-02-13 00:52:54 +00:00
Martijn Dekker
2c04a88b37 shtests: actually test /dev/tty instead of checking for existence
The GitHub runners apparently provide a non-working /dev/tty. To
avoid failures and confusion, shtests shold refuse to run the tests
and tell people to use script(1) to simulate a tty. On Linux, it
goes like this:

	script -q -e -c 'bin/shtests --your-options-here'

On macOS and FreeBSD, the invocation is:

	script -q /dev/null bin/shtests --your-options-here

The NetBSD and OpenBSD variants of script(1) need different
invocations again. They also don't pass down the command's exit
status, so would need a workaround for that.

It would be nice if we could use pty for this as this comes with
the distribution, so would work the same on every OS, but it seems
to be broken for this use case.

src/cmd/ksh93/tests/shtest:
- Use 'test -t 1' with stdout (fd 1) redirected to /dev/tty to
  ensure the tty is actually on a terminal.

src/cmd/ksh93/tests/basic.sh:
- Remove superflous check for tty. All tests run through shtests.

Resolves: https://github.com/ksh93/ksh/pull/171
2021-02-13 00:50:46 +00:00
Martijn Dekker
6f6b22016a command -x: tweak args list size detection (re: 9ddb45b1)
src/cmd/ksh93/features/externs: ARG_EXTRA_BYTES detection:
- Improve detection of extra bytes per argument: on every loop
  iteration, recalculate the size of the environment while taking
  the amount extra bytes we're currently trying into account. Also
  count arguments (argv[]) as they are stored in the same buffer.
  On 64-bit Linux with glibc, this now detects 9 extra bytes per
  argument instead of 8. An odd number (literally and figuratively)
  but apparently it needs it; I do think my method is correct now.
  On 64-bit Solaris and macOS, this still detects 8 extra bytes.
  (On 64-bit Linux with musl C library, it detects 0 bytes. Nice.)

src/cmd/ksh93/sh/path.c: path_xargs():
- Remove the kludge subtracting twice the size of the environment.
  With the feature test fixed, this should no longer fail on Linux.
- Take into account the size of the final null element in the
  argument and environment lists.

src/cmd/ksh93/tests/path.sh:
- Do not use awk for the test due to breakage in the system awks
  on Solaris/Illumos (hangs) and AIX & UnixWare (drops arguments).
  Instead, use (wait for it...) ksh. It's a bit slower, but works.
2021-02-13 00:08:33 +00:00
Martijn Dekker
8c1e9971a7 tests/jobs.sh: suppress error msg on noncompliant 'ps' 2021-02-12 23:56:58 +00:00
Martijn Dekker
dec10fee6a package: compat: no $PWD on Bourne shell (re: 6cc2f6a0, f5eaf217) 2021-02-12 15:21:38 +00:00
Lev Kujawski
a9e7012dfd Fix a potential read of uninitialized memory through a pointer
src/lib/libast/misc/magic.c:
- Use strncpy instead of memcpy to avoid reading past the null
  terminator of the string pointed to by p.
2021-02-12 13:46:07 +00:00
Lev Kujawski
3224b79083 Forestall spurious test failures by skipping unavailable locales
src/cmd/ksh93/tests/bracket.sh:
- Read the list of installed locales to ensure the locale to be tested
  actually exists on the system under test.
- Produce a warning diagnostic for skipped locales.
- Additionally test the en_US.ISO8859-1 and en_US.UTF-8 locales.

Co-authored-by: Martijn Dekker <martijn@inlv.org>
2021-02-12 13:43:50 +00:00
Lev Kujawski
d5a94b3722 Produce IEEE compliant output from pow() despite platform deviations
src/cmd/ksh93/features/math.sh:
- Specify ast_float.h within iffehdrs instead of math.h, so that iffe
  will pick up on macro substitutions within libast. This should make
  any future efforts to remedy floating point behavior easier as well.
- Always include ast_float.h within the generated math header file,
  not just on IA64 platforms.

src/cmd/ksh93/tests/arith.sh:
- Test pow(1.0,-Inf) and pow(1.0,NaN) for IEEE compliance as well.
- Test the exponentiation operator (**) in addition, as streval.c,
  which processes the same, calls pow() separately.

src/lib/libast/features/float:
- Test the IEEE compliance of the underlying math library's pow()
  function and substitute macros producing compliant behavior if
  necessary.
2021-02-12 13:23:16 +00:00
Martijn Dekker
0f92d63823 tests/attributes.sh: fix spurious fail if any env var contains 'foo' 2021-02-12 12:45:47 +00:00
Martijn Dekker
41ebb55a3a Fix most of job control (-m/-o monitor) in scripts
If I haven't missed anything, this should make the non-interactive
aspects of job control in scripts work as expected, except for the
"<command unknown>" issue in the output of 'bg', 'fg' and 'jobs'
(which is not such a high priority as those commands are really
designed for interactive use).

Plus, I believe I now finally understand what these three are for:
* The job.jobcontrol variable is set to nonzero by job_init() in
  jobs.c if, and only if, the shell is interactive *and* managed to
  get control of the terminal. Therefore, any changing of terminal
  settings (tcsetpgrp(3), tty_set()) should only be done if
  job.jobcontrol is nonzero. This commit changes several checks for
  sh_isoption(SH_INTERACTIVE) to checks for job.jobcontrol for
  better consistency with this.
* The state flag, sh_isstate(SH_MONITOR), determines whether the
  bits of job control that are relevant for both scripts and
  interactive shells are active, which is mostly making sure that a
  background job gets its own process group (setpgid(3)).
* The shell option, sh_isoption(SH_MONITOR), is just that. When the
  user turns it on or off, the state flag is synched with it. It
  should usually not be directly checked for, as the state may be
  temporarily turned off without turning off the option.

Prior discussion:
https://www.mail-archive.com/austin-group-l@opengroup.org/msg06456.html

src/cmd/ksh93/bltins/typeset.c, src/cmd/ksh93/sh/args.c:
- Move synching the SH_MONITOR state flag with the SH_MONITOR
  shell option from b_set() (the 'set' builtin) to sh_applyopts()
  which is indirectly called from b_set() and is also used when
  parsing the shell invocation command line. This ensures -m is
  properly enabled in both scenarios.

src/cmd/ksh93/sh/jobs.c:
- job_init(): Do not refuse to initialise job control on
  non-interactive shells. Instead, skip everything that should only
  be done on interactive shells (i.e., everything to do with the
  terminal). This function is now even more of a mess than it was
  before, so refactoring may be desirabe at some point.
- job_close(), job_set(), job_reset(), job_wait(): Do not reset the
  terminal process group (tcsetpgrp()) if job.jobcontrol isn't on.

src/cmd/ksh93/sh/xec.c:
- sh_exec(): TFORK: For SIGINT handling, check the SH_MONITOR
  state flag, not the shell option.
- sh_exec(): TFORK: Do not turn off the SH_MONITOR state flag in
  forked children. The non-interactive part of job control should
  stay active. Instead, turn off the SH_INTERACTIVE state flag so
  we don't get interactive shell behaviour (i.e. job control noise
  on the terminal) in forked subshells.
- _sh_fork(), sh_ntfork(): Do not reset the terminal process group
  (tcsetpgrp()) if job.jobcontrol isn't on. Do not turn off the
  SH_MONITOR state flag in forked children.

src/cmd/ksh93/sh/subshell.c: sh_subfork():
- Do not turn off the monitor option and state in forked subshells.
  The non-interactive part of job control should stay active.

src/cmd/ksh93/bltins/misc.c: b_bg():
- Check isstate(SH_MONITOR) instead of sh_isoption(SH_MONITOR) &&
  job.jobcontrol before throwing a 'no job control' error.
  This fixes a minor bug: fg, bg and disown could quietly fail.

src/cmd/ksh93/tests/jobs.sh:
- Add tests for 'fg' with job control IDs (%%, %1) in scripts.
- Add test checking that a background job launched from a subsell
  with job control enabled correctly becomes the leader of its own
  process group.

Makes progress on: https://github.com/ksh93/ksh/issues/119
2021-02-12 06:51:27 +00:00
Martijn Dekker
37a18bab71 Fix ${ comsub; } killing job control
Another longstanding whopper of a bug in basic ksh93 functionality:
run a ${ shared-state; } command substitution twice and job control
promptly loses track of all your running jobs. New jobs are tracked
again until you run another two shared-state command substitutions.
This is in at least 93t+, 93u-, 93u+, 93v- and ksh2020.

$ sleep 300 &
[1]	56883
$ jobs						# OK
[1] +  Running                 sleep 300 &
$ v=${ echo hi1; }
$ jobs						# OK
[1] +  Running                 sleep 300 &
$ v=${ echo hi2; }
$ jobs						# Nothing!
$ fg
ksh: fg: no such job

src/cmd/ksh93/sh/subshell.c: sh_subshell():
- The current environment number shp->curenv (a.k.a. sh.curenv) was
  not being restored if the virtual subshell we're leaving is of
  the shared-state command substitution variety as it was wrongly
  considered to be part of the environment that didn't need
  restoring. This caused it to be out of sync with shp->jobenv
  (a.k.a. sh.jobenv) which did get restored from savedcurenv.
  Restore both from savedcurenv at the same time for any subshell.
  (How these numbers are used exactly remains to be discovered.)

src/cmd/ksh93/tests/jobs.sh:
- Added, with a test for this bug to start it off. There is no
  other test script where job control fits, and a lot more related
  fixes are anticipated: https://github.com/ksh93/ksh/issues/119
2021-02-11 13:41:40 +00:00
Martijn Dekker
2996d7ae7c Fix typos in <customtypecommand> --man self-documentation
src/cmd/ksh93/bltins/enum.c:
- enum_type[]: Fix typos; minor edit for style.
- enum_type[], enuminfo(): Make the list of supported values
  comma-separated, instead of using a comma at the start of each.

src/cmd/ksh93/sh/nvtype.c:
- sh_opttype[]: Fix typos.
2021-02-10 16:25:11 +00:00
Martijn Dekker
76ea18dcbd Fix disabling SHOPT_FIXEDARRAY (re: 2182ecfa)
It was easier than expected to fix this one. The many regression
test failures caused by disabling it were all due to one bug:
'typeset -p' output broke when building without this option.

src/cmd/ksh93/sh/nvtree.c: nv_attribute():
- In this function to print the attributes of a name-value pair,
  move four lines of code out of #if SHOPT_FIXEDARRAY...#endif that
  were inadvertently moved into the #if block in ksh93 2012-05-18.
  See the changes to nvtree.c in this multishell repo commit:
  https://github.com/multishell/ksh93/commit/aabab56a

src/cmd/ksh93/data/builtins.c:
- Update/rewrite 'typeset -a' documentation.
- Make it adapt to SHOPT_FIXEDARRAY.
- Fix a few typos.

src/cmd/ksh93/tests/arrays2.sh:
- Only one regression test needs a SHOPT_FIXEDARRAY check.

.github/workflows/ci.yml:
- Disable SHOPT_FIXEDARRAY when regression-testing without SHOPTs.
- Enable xtrace, add ':' commands for traced comments. This should
  make the CI runner output logs a little more readable.
2021-02-10 04:48:56 +00:00
Martijn Dekker
2182ecfa08 Fix compile/regress fails on compiling without SHOPT_* options
Many compile-time options were broken so that they could not be
turned off without causing compile errors and/or regression test
failures. This commit now allows the following to be disabled:

SHOPT_2DMATCH    # two dimensional ${.sh.match} for ${var//pat/str}
SHOPT_BGX        # one SIGCHLD trap per completed job
SHOPT_BRACEPAT   # C-shell {...,...} expansions (, required)
SHOPT_ESH        # emacs/gmacs edit mode
SHOPT_HISTEXPAND # csh-style history file expansions
SHOPT_MULTIBYTE  # multibyte character handling
SHOPT_NAMESPACE  # allow namespaces
SHOPT_STATS      # add .sh.stats variable
SHOPT_VSH        # vi edit mode

The following still break ksh when disabled:

SHOPT_FIXEDARRAY # fixed dimension indexed array
SHOPT_RAWONLY    # make viraw the only vi mode
SHOPT_TYPEDEF    # enable typeset type definitions

Compiling without SHOPT_RAWONLY just gives four regression test
failures in pty.sh, but turning off SHOPT_FIXEDARRAY and
SHOPT_TYPEDEF causes compilation to fail. I've managed to tweak the
code to make it compile without those two options, but then dozens
of regression test failures occur, often in things nothing directly
to do with those options. It looks like the separation between the
code for these options and the rest was never properly maintained.
Making it possible to disable SHOPT_FIXEDARRAY and SHOPT_TYPEDEF
may involve major refactoring and testing and may not be worth it.

This commit has far too many tweaks to list. Notables fixes are:

src/cmd/ksh93/data/builtins.c,
src/cmd/ksh93/data/options.c:
- Do not compile in the shell options and documentation for
  disabled features (braceexpand, emacs/gmacs, vi/viraw), so the
  shell is not left with no-op options and inaccurate self-doc.

src/cmd/ksh93/data/lexstates.c:
- Comment the state tables to associte them with their IDs.
- In the ST_MACRO table (sh_lexstate9[]), do not make the S_BRACE
  state for position 123 (ASCII for '{') conditional upon
  SHOPT_BRACEPAT (brace expansion), otherwise disabling this causes
  glob patterns of the form {3}(x) (matching 3 x'es) to stop
  working as well -- and that is ksh globbing, not brace expansion.

src/cmd/ksh93/edit/edit.c: ed_read():
- Fixed a bug: SIGWINCH was not handled by the gmacs edit mode.

src/cmd/ksh93/sh/name.c: nv_putval():
- The -L/-R left/right adjustment options to typeset do not count
  zero-width characters. This is the behaviour with SHOPT_MULTIBYTE
  enabled, regardless of locale. Of course, what a zero-width
  character is depends on the locale, but control characters are
  always considered zero-width. So, to avoid a regression, add some
  fallback code for non-SHOPT_MULTIBYTE builds that skips ASCII
  control characters (as per iscntrl(3)) so they are still
  considered to have zero width.

src/cmd/ksh93/tests/shtests:
- Export the SHOPT_* macros from SHOPT.sh to the tests as
  environment variables, so the tests can check for them and decide
  whether or how to run tests based on the compile-time options
  that the tested binary was presumably compiled with.
- Do not run the C.UTF-8 tests if SHOPT_MULTIBYTE is not enabled.

src/cmd/ksh93/tests/*.sh:
- Add a bunch of checks for SHOPT_* env vars. Since most should
  have a value 0 (off) or 1 (on), the form ((SHOPT_FOO)) is a
  convenient way to use them as arithmetic booleans.

.github/workflows/ci.yml:
- Make GitHub do more testing: run two locale tests (Dutch and
  Japanese UTF-8 locales), then disable all the SHOPTs that we can
  currently disable, recompile ksh, and run the tests again.
2021-02-08 22:02:45 +00:00
Martijn Dekker
a9d77bba40 libast: optget(): emphasis: add screen/tmux, dtterm (re: ec79563b)
src/lib/libast/misc/optget.c:
- Add screen* (which includes tmux) and dtterm* (CDE terminal) to
  the glob pattern deciding whether to use ANSI boldface sequences.
- Don't bother parsing the env var if stderr is not on a terminal.

src/cmd/ksh93/sh.1:
- Extend self-documentation documentation; document how optget(3)
  uses the ERROR_OPTIONS env var to control boldface output.
- Tweaks and minor edits.
2021-02-07 20:42:52 +00:00
Martijn Dekker
ec79563b8f libast: optget(): fix emphasis state initialisation
This fixes a bug in libast optget()'s use of emphasis in the
display of --man(uals) via standard error on a terminal.

Symptom:

$ printf --man 2>&1 | more
(ok; emphasis disabled, no escape codes shown)
$ printf --man
(ok; emphasis correctly displayed)
$ printf --man 2>&1 | more
(whoops; emphasis not disabled; escape codes garble 'more' output)

The problem was that the state.emphasis variable was not
initialised and, when set to one, was never reset again
(except through the use of the --api, --html or --nroff option).

The source code also reveals an undocumented feature: if the
environment variable $ERROR_OPTIONS contains 'noemphasi', emphasis
is forced off, else if it contains 'emphasi', it's forced on.
Other characters (such as the final 's' of emphasis) are ignored.
This was also broken (forcing off didn't work) and is now fixed.

src/lib/libast/misc/optget.c:
- Do not assume that enabling emphasis is forever; re-initialise
  the state on every relevant getopts invocation.
- Increase the number of terminals on which emphasis is displayed
  using ANSI escape codes. (This is a hack and we should ask the OS
  for the correct codes, but never mind -- ANSI is now universal.)
2021-02-07 05:53:48 +00:00
Martijn Dekker
403e864ac8 Disallow >;word and <>;word for 'redirect' (re: 7b59fb80, 7b82c338)
The >;word and <>;word redirection operators cannot be used with
the 'exec' builtin, but the 'redirect' builtin (which used to be
an alias of 'command exec') permitted them. However, they do not
have the documented effect of the added ';'. So this commit blocks
those operators for 'redirect' as they are blocked for 'exec'.

It also tweaks redirect's error message if a non-redirection
argument is encountered.

src/cmd/ksh93/sh/parse.c: simple():
- Set the lexp->inexec flag for SYSREDIR (redirect) as well as
  SYSEXEC (exec). This flag is checked for in sh_lex() (lex.c) to
  throw a syntax error if one of these two operators is used.

src/cmd/ksh93/sh.1, src/cmd/ksh93/data/builtins.c:
- Documentation tweaks.

src/cmd/ksh93/sh/xec.c, src/cmd/ksh93/bltins/misc.c:
- When 'redirect' gives an 'incorrect syntax' (e_badsyntax) error
  message, include the first word that was found not to be a valid
  redirection. This is simply the first argument, as redirections
  are removed from the arguments list.

src/cmd/ksh93/tests/io.sh:
- Update test to reflect new error message format.
2021-02-07 03:23:56 +00:00
Martijn Dekker
43dfe3c8fa build system: rm unused variable declarations from Mamfiles
Now that the Make Abstract Machine files are maintained manually
and not generated automatically, unused variables are an annoying
distraction -- and there are many.

But the language/format is very simple and very parseable using
shell, awk, etc. -- so this was easy to automate. All variables are
declared with 'setv' and they are used if an expansion of the form
${varname} exists (the braces are mandatory in Mamfiles).

bin/Mamfile_rm_unused_vars:
- Added for reference and future use.

src/*/*/Mamfile:
- Remove all unused 'setv' variable declarations.
2021-02-05 15:39:31 +00:00
Martijn Dekker
7b59fb805c Fix 'redirect {var}>file' in subshell (re: 7b82c338)
Permanent redirections of that form broke in subshells when used
with the 'redirect' command, because I had overlooked one instance
where the new 'redirect' builtin needs to match the behaviour of
the 'exec' builtin.

src/cmd/ksh93/tests/io.sh: sh_exec():
- Do not restore file descriptors in (virtual) subshells for
  'redirect' just as this isn't done for 'exec'.

src/cmd/ksh93/tests/io.sh:
- Add regression test for this bug.
- Complete the test for f9427909 which I committed prematurely.

Fixes: https://github.com/ksh93/ksh/issues/167
2021-02-05 05:38:38 +00:00
Martijn Dekker
f9427909dc Make redirections like {varname}>file work with brace expansion off
This is some nonsense: redirections that store a file descriptor
greater than 9 in a variable, like {var}<&2 and the like, stopped
working if brace expansion was turned off. '{var}' is not a brace
expansion as it doesn't contain ',' or '..'; something like 'echo
{var}' is always output unexpanded. And redirections and brace
expansion are two completely unrelated things. It wasn't documented
that these redirections require the -B/braceexpand option, either.

src/cmd/ksh93/sh/lex.c: sh_lex():
- Remove incorrect check for braceexpand option before processing
  redirections of this form.

src/cmd/ksh93/COMPATIBILITY:
- Insert a brief item mentioning this.

src/cmd/ksh93/sh.1:
- Correction: these redirections do not yield a file descriptor >
  10, but > 9, a.k.a. >= 10.
- Add a brief example showing how these redirections can be used.

src/cmd/ksh93/tests/io.sh:
- Add a quick regression test.
2021-02-05 05:08:39 +00:00
Martijn Dekker
c709868572 process substitution: improve fifo error handling (re: ab5dedde)
src/cmd/ksh93/sh/args.c: sh_argprocsub():
- Fix compiler warnings with SHOPT_DEVFD on by including "io.h".
- Without SHOPT_DEVFD, the FIFO code didn't consider that libast's
  pathtemp(3) may also fail and return null. Add a check for this.
2021-02-04 20:47:45 +00:00
Martijn Dekker
cea04c4a6f Add missing NEWS entries (re: a410bc48, 6f3b23e6); update README.md 2021-02-04 17:31:22 +00:00
Martijn Dekker
a410bc480f autoload: Add loop detection
It was trivial to crash ksh by making an autoloaded function
definition file autoload itself, causing a stack overflow due to
infinite recursion. This commit adds loop detection that stops a
function that is being autoloaded from autoloading itself either
directly or indirectly, without removing the ability of autoloaded
function definition files to autoload other functions.

src/cmd/ksh93/sh/path.c: funload():
- Detect loops by checking if the path of a function to be
  autoloaded was already added to a new internal static tree,
  and if not, adding it while the function is being loaded.

src/cmd/ksh93/tests/path.sh:
- Add regression test.
- Tweak a couple of others to be freeze- and crash-proof.

NEWS:
- Add this fix + a forgotten entry for the previous fix (6f3b23e6).

Fixes: https://github.com/ksh93/ksh/issues/136
2021-02-04 16:28:19 +00:00
Martijn Dekker
6f3b23e6f4 Fix crash on trying a very long nonexistent command
Reproducer from @Saikiran-m:
| ~# sh -c `perl -e 'print "a"x100000'`
|  genunix: NOTICE: core_log: sh[1221] core dumped: /var/cores/core.sh.0.1602153496
| Memory fault(coredump)

The crash was in trying to decide whether the name was suitable for
autoloading as a function on $FPATH. This calls strmatch() to check
the name against a regex for valid function name. But the libast
regex code is not designed optimally and uses too much recursion,
limiting the length of the strings it's able to cope with.

src/cmd/ksh93/sh/path.c: path_search():
- Before calling strmatch(), check that the name is shorter than
  256 bytes. The maximum length of file names on Linux and macOS is
  255 bytes, so an autoload function can't have a name longer than
  that anyway.

src/cmd/ksh93/tests/path.sh:
- Add test for this bug.
- Tweak 'command -x' test to not leave a hanging process on Ctrl+C.

Fixes: https://github.com/ksh93/ksh/issues/144
2021-02-04 05:03:40 +00:00
Martijn Dekker
32cff97b24 tests/*.sh: fix indentation of warnings 2021-02-04 02:22:46 +00:00
Martijn Dekker
e220445265 Re-allow disabling vmalloc for release builds (re: 399886da)
Well, that commit was based on a silly oversight: of course it's
necessary to pass ${KSH_RELFLAGS} to the feature tests too as they
use this flag to determine whether to enable or disable vmalloc.

On further analysis I think the annoying warnings can be solved in
a different way. Quotes (single or double) in 'exec -' commands
don't seem to be special to mamake at all; it looks like they are
passed on to the shell as is. So Mamfile variables are expanded and
the expansions backslash-escaped the same way regardless of quotes.
Which means we can make the shell remove the unwanted level of
backslashes by using double instead of single quotes.

src/*/*/Mamfile:
- On iffe commands, restore ${KSH_RELFLAGS}, using double quotes to
  group the compiler command as one argument to iffe.
2021-02-04 01:40:53 +00:00
Martijn Dekker
824a85e38e ksh93/README: Void Linux (musl) successfully tested 2021-02-03 23:08:34 +00:00
Martijn Dekker
7dbcbce407 Revert 7a6980a3, restoring build on Alpine Linux
This reverts an OpenSUSE patch ("libast/comp/conf.sh: apply limits
detection fixes for Linux"). It broke the build on Alpine Linux
with the musl C library (see also e245856f).
2021-02-03 21:44:55 +00:00
Martijn Dekker
9ddb45b12d command -x: fix 'args list too long' on Linux, again (re: 8f5235a5)
This time it was failing on a 64-bit Debian Linux system with very
few and short environment variables. Sigh.

src/cmd/ksh93/sh/path.c:
- Combine the strategy from 63979488 with that of 8f5235a5.
2021-02-03 20:07:47 +00:00
Martijn Dekker
8f5235a53f fix 'args list too long' on Linux, again (re: 63979488)
That fix turned out to be insufficient as NixOS has huge
environment variable lists because (due to each software package
being installed in its own directory tree) it has to keep dozens
of directories in variables like XDG_CONFIG_DIRS and others.
The 'command -x' regression test was failing on NixOS.

src/cmd/ksh93/sh/path.c:
- Different strategy. Leave twice the size of the existing
  environment free.
2021-02-03 19:22:35 +00:00
Martijn Dekker
7ff6b73bdb emacs.c: fix 2 causes of crash
Hopefully this will deal with ksh crashing in macOS Terminal.app
once and for all. Trigger: press Command-F to open the find bar,
then press Esc to close it, then press Esc again. Result: crash
somewhere random in the job control code.

Turns out macOS Terminal.app apparently (and wrongly) sends <Esc>
followed by <Ctrl+L> to the terminal, which ksh takes as a sequence
for clearing the screen. The related crash ultimately traced back
to the code for that in emacs.c. The other crash was in the code
for double-ESC file name completion.

This commit also fixes a non-robust invocation of the 'tput'
command by using the direct path found in $(getconf PATH).

src/cmd/ksh93/features/cmds:
- Remove unused tests for the presence of commands
  (newgrp,test,id,wc,cut,logname,pfexec).
- Replace 'cmd tput' test by 'pth tput' which will find its path
  in $(getconf PATH) and store that path as the macro value.
- Add two tests to determine if 'tput' supports terminfo and/or
  termcap codes. (FreeBSD still requires old termcap codes.)

src/cmd/ksh93/edit/emacs.c: escape():
- Fix a crash in the code for double-ESC completion. Check if the
  cursor is on a non-zero position; this caused a bus error
  (invalid address access) in the subsequent ed_expand call.
- For <Esc><Ctrl+L> (clear screen), fix the strange crash in macOS
  Terminal by not using sh_trap() to invoke "tput clear", which
  causes ksh itself to invoke that command. ksh apparently doesn't
  cope with doing this while SIGWINCH (window size change signal)
  is sent by Terminal. The fix is to just use the C standard
  system(3) function to invoke tput. This invokes tput via /bin/sh,
  but what the hey. (Note that ksh also ran any function or alias
  called 'tput' instead of the real command, and that is now also
  fixed.)
- Use the new _pth_tput test result to invoke tput with the
  hardcoded default system path, increasing robustness.

src/cmd/ksh93/edit/edit.c: ed_setup():
- Use the new _pth_tput test result to invoke tput with the
  hardcoded default system path, increasing robustness.
- When getting the escape code for "cursor up", use the new
  _tput_terminfo and _tput_termcap test results to determine which
  kind of command code to send. This fixes it on FreeBSD.
2021-02-03 17:55:03 +00:00
Martijn Dekker
f5eaf217ed build system: fix detection of default system directories
src/cmd/INIT/iffe.sh:
- Fix "standard system directories" for the cmd test, which were
  hardcoded as bin, /etc, /usr/bin, /usr/etc, /usr/ucb. That's both
  unportable and antiquated. Replace this with the path output by
  'getconf PATH'.
- Add fixes from modernish for 'getconf PATH' output to compensate
  for bugs/shortcomigns in NixOS and AIX. Source:
  https://github.com/modernish/modernish/blob/9e4bf5eb/lib/modernish/aux/defpath.sh
  Ref.: https://github.com/NixOS/nixpkgs/issues/65512

src/lib/libast/comp/conf.tab: PATH:
- Add the NixOS and AIX default path fixes here too; this fixes
  'command -p' and the builtin 'getconf PATH' on these systems.

bin/package, src/cmd/INIT/package.sh:
- Re-support being launched with just the command name 'package' in
  the command line (if the 'package' command is in $PATH). At least
  one other script in the build system does this. (re: 6cc2f6a0)
- Go back three levels (../../..) if we were invoked from
  arch/*/bin/package, otherwise we won't find src/cmd/ksh93/SHOPT.sh.
2021-02-03 17:49:00 +00:00
Martijn Dekker
be33942415 Some more build fixes from OpenSUSE
These update some outdated library path searches as well as
a couple of gcc-specific improvements.

Original patch:
https://build.opensuse.org/package/view_file/shells/ksh/ksh93-compat.dif
2021-02-02 21:03:01 +00:00
Martijn Dekker
52067c3d37 Backport atomic job locking from ksh 93v- beta
Something similar was previously done in 07cc71b8 from a Debian
patch, and eventually reverted; it redefined the ast atomic
functions asoincint() and asodecint() to be gcc-specific. This
imports the upstream version from the ksh 93v- beta instead.

This commit is based on an OpenSUSE patch:
https://build.opensuse.org/package/view_file/shells/ksh/ksh93-joblock.dif

src/cmd/ksh93/include/jobs.h:
- Replace job locking mechanism with the 93v- version which uses
  the atomic libast functions asoincint(), asogetint() and
  asodecint(). See: src/lib/libast/man/aso.3

src/cmd/ksh93/sh/jobs.c: job_subsave():
- Revert gcc optimiser bug workaround from c258a04f.
  It should now be unnecessary.
2021-02-02 17:38:19 +00:00
Martijn Dekker
1bd0620708 libast: sfio(3) fixes from ksh 93v- beta
These fixes were backported by OpenSUSE. Original patch:
https://build.opensuse.org/package/view_file/shells/ksh/ksh93-sfio.dif
2021-02-02 16:20:59 +00:00
Martijn Dekker
63979488e6 command -x: fix 'arg list too long' on Linux (re: 66e1d446)
I got one intermittent regression test failure due to 'argument
list too long' on a Debian x86_64 system.

src/cmd/ksh93/sh/path.c: path_xargs():
- Leave extra argument space for systems that need extra bytes:
  1KiB per extra byte, with a minimum of 2KiB (the old value).
2021-02-02 15:23:21 +00:00
Martijn Dekker
db71b3ad43 libast: robustness fixes for temporary files and streams
From an OpenSUSE patch:
https://build.opensuse.org/package/view_file/shells/ksh/ksh93-pathtemp.dif

See src/lib/libast/man/path.3 for pathtemp()
and src/lib/libast/man/sfio.3 for sftmp()

src/lib/libast/path/pathtemp.c:
- Error check fix: add an access check wrapper function that checks
  if a path was given and if there is enough free space on the
  device, setting errno appropriately in case of trouble.

src/lib/libast/sfio/sftmp.c:
- On Linux, use the /dev/shm shared memory objects for the new
  temporary file descriptor -- that is, do not access HD or SSD but
  only the memory based tmpfs of the POSIX SHM.
2021-02-02 14:44:34 +00:00
Martijn Dekker
b12be093d7 typeset: print_value(): save/restore last_table
This fix comes via an OpenSUSE patch but also exists in 93v- beta.
https://build.opensuse.org/package/view_file/shells/ksh/ksh93-typedef.dif
(only the printvalue() diff was still applicable to 93u+m;
the setall() fix was done differently and better in a2f13c19)
2021-02-02 14:31:35 +00:00
Martijn Dekker
4645e6ad33 job_reset(): fix for resetting foreground process group
Patch from OpenSUSE:
https://build.opensuse.org/package/view_file/shells/ksh/ksh93-foreground-prgrp.dif

src/cmd/ksh93/sh/jobs.c: job_reset():
- Only reset the foreground process group associated with the
  current job if the current job's process ID is different from the
  terminal's foreground process group ID.
2021-02-02 12:49:00 +00:00
Martijn Dekker
9f980ba65a sh_setmatch(): fix node size calculation
This fixes the function that sets ${.sh.match}. Patch from OpenSUSE:
https://build.opensuse.org/package/view_file/shells/ksh/ksh93-limit-name-len.dif

src/cmd/ksh93/sh/init.c: sh_setmatch():
- Fix node size calculation, possibly preventing data corruption.

src/cmd/ksh93/include/ulimit.h: Limit_t:
- Defining the 'name' struct member as 'char name[16]' makes
  no sense as the name is being initialised statically in
  data/limits.c; just make it a 'char *name' pointer.
2021-02-02 11:52:54 +00:00
Martijn Dekker
3002c4113e vmalloc: better detect default region size on Linux
This is a Linux-specific fix for vmalloc from OpenSUSE, for what
that's still worth; we're not going to keep using vmalloc long term.
https://build.opensuse.org/package/view_file/shells/ksh/ksh93-vm.dif
2021-02-02 11:32:37 +00:00
Martijn Dekker
e2c2753ee8 libast: Fix detection of GCC 4.1+ 64/32-bit atomic operations model
This fix to the atomic scalar operations feature tests is from OpenSUSE:
https://build.opensuse.org/package/view_file/shells/ksh/ksh93-aso.dif
2021-02-02 05:27:08 +00:00
Martijn Dekker
69e18de58f edit.c: Fix history generation if there are zero arguments
This applies a fix from OpenSUSE:
https://build.opensuse.org/package/view_file/shells/ksh/ksh93-reg.dif
2021-02-02 05:24:11 +00:00
Martijn Dekker
627df2b19a libast: optget(3): fix some uninitialised variables
This is a part of this OpenSUSE patch:
https://build.opensuse.org/package/view_file/shells/ksh/ksh93-gcc.dif
2021-02-02 05:17:52 +00:00
Martijn Dekker
0684806d47 feature tests: signbit detection fix for ia64
An Intel Itanium fix from OpenSUSE:
https://build.opensuse.org/package/view_file/shells/ksh/ksh93-ia64.dif
2021-02-02 04:40:09 +00:00
Martijn Dekker
7a6980a380 libast/comp/conf.sh: apply limits detection fixes for Linux
This is another patch from OpenSUSE:
https://build.opensuse.org/package/view_file/shells/ksh/ksh93-limits.dif
2021-02-02 04:35:54 +00:00
Martijn Dekker
fa3a3d7955 sh_ntfork(): handle SIGTSTP along with SIGTTIN and SIGTTOU
This applies a patch from OpenSUSE that makes SIGTSTP handling
consistent with that of SIGTTIN and SIGTTOU.
https://build.opensuse.org/package/view_file/shells/ksh/ksh93-signals.dif
2021-02-02 04:25:46 +00:00
Martijn Dekker
8a58166bc4 Add OpenSUSE fixes for the uname builtin on Linux
Original patches:
https://build.opensuse.org/package/view_file/shells/ksh/ksh93-uname.dif
https://build.opensuse.org/package/view_file/shells/ksh/ksh93-no-sysctl.dif
2021-02-02 03:31:21 +00:00