partial merge and full RCS ID sync with oksh

merged:
• new regression tests
• check.pl (tests/th) better tmpfile handling
• exec.c 1.50: POSIX specifies that for an AND/OR list,
  only the last command's exit status matters for "set -e"
• ksh.1 1.147: document the above
• eval.c 1.39: “Make $(< /nonexistent) have the same behaviour
  as $(cat /nonexistent) wrt. errors (do not unwind and do not
  treat this as fatal if set -e is used).”
  ‣ additionally make shf_open() return errno and actually show
    the error message from the system
• regression-39 test: remove the “maybe” marker
  ‣ but decide on correct POSIX behaviour

already been fixed in mksh:
• check.pl (tests/th) exit 1 if tests fail

not merged:
• main.c 1.52: run traps in unwind() before exiting;
  I’m pretty sure this is already working as-should in mksh
• eval.c 1.38: “Commands executed via `foo` or $( bar ) should
  not inherit "set -e" status.” As discussed in IRC, this is
  just plainly WRONG.
This commit is contained in:
tg 2013-07-21 18:36:03 +00:00
parent 80a83f4f0b
commit bd795a83ae
7 changed files with 210 additions and 46 deletions

View File

@ -1,7 +1,8 @@
# $MirOS: src/bin/mksh/check.pl,v 1.31 2012/04/06 12:22:14 tg Exp $
# $OpenBSD: th,v 1.13 2006/05/18 21:27:23 miod Exp $
# $MirOS: src/bin/mksh/check.pl,v 1.32 2013/07/21 18:35:56 tg Exp $
# $OpenBSD: th,v 1.16 2013/06/14 20:52:08 millert Exp $
#-
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011,
# 2012, 2013
# Thorsten Glaser <tg@mirbsd.org>
#
# Provided that these terms and disclaimer and all copyright notices
@ -171,13 +172,15 @@ BEGIN {
use Getopt::Std;
use Config;
use File::Temp qw/ :mktemp /;
$os = defined $^O ? $^O : 'unknown';
($prog = $0) =~ s#.*/##;
$Usage = <<EOF ;
Usage: $prog [-Pv] [-C cat] [-e e=v] [-p prog] [-s fn] [-t tmo] name ...
Usage: $prog [-Pv] [-C cat] [-e e=v] [-p prog] [-s fn] [-T dir] \
[-t tmo] name ...
-C c Specify the comma separated list of categories the program
belongs to (see category field).
-e e=v Set the environment variable e to v for all tests
@ -188,6 +191,7 @@ Usage: $prog [-Pv] [-C cat] [-e e=v] [-p prog] [-s fn] [-t tmo] name ...
-p p Use p as the program to test
-s s Read tests from file s; if s is a directory, it is recursively
scaned for test files (which end in .t).
-T dir Use dir instead of /tmp to hold temporary files
-t t Use t as default time limit for tests (default is unlimited)
-v Verbose mode: print reason test failed.
name specifies the name of the test(s) to run; if none are
@ -229,12 +233,6 @@ EOF
"os:$os", '1'
);
$temps = "/tmp/rts$$";
$tempi = "/tmp/rti$$";
$tempo = "/tmp/rto$$";
$tempe = "/tmp/rte$$";
$tempdir = "/tmp/rtd$$";
$nfailed = 0;
$nifailed = 0;
$nxfailed = 0;
@ -243,7 +241,7 @@ $nxpassed = 0;
%known_tests = ();
if (!getopts('C:e:Pp:s:t:v')) {
if (!getopts('C:e:Pp:s:T:t:v')) {
print STDERR $Usage;
exit 1;
}
@ -253,6 +251,7 @@ die "$prog: no test set specified (use -s)\n" if !defined $opt_s;
$test_prog = $opt_p;
$verbose = defined $opt_v && $opt_v;
$test_set = $opt_s;
$temp_dir = $opt_T || "/tmp";
if (defined $opt_t) {
die "$prog: bad -t argument (should be number > 0): $opt_t\n"
if $opt_t !~ /^\d+$/ || $opt_t <= 0;
@ -297,8 +296,6 @@ if (defined $opt_e) {
}
%old_env = %ENV;
die "$prog: couldn't make directory $tempdir - $!\n" if !mkdir($tempdir, 0777);
chop($pwd = `pwd 2>/dev/null`);
die "$prog: couldn't get current working directory\n" if $pwd eq '';
die "$prog: couldn't cd to $pwd - $!\n" if !chdir($pwd);
@ -316,6 +313,17 @@ $SIG{'ALRM'} = 'catch_sigalrm';
$| = 1;
# Create temp files
($fh, $temps) = mkstemp("${temp_dir}/rts.XXXXXXXX");
close($fh);
($fh, $tempi) = mkstemp("${temp_dir}/rti.XXXXXXXX");
close($fh);
($fh, $tempo) = mkstemp("${temp_dir}/rto.XXXXXXXX");
close($fh);
($fh, $tempe) = mkstemp("${temp_dir}/rte.XXXXXXXX");
close($fh);
$tempdir = mkdtemp("${temp_dir}/rtd.XXXXXXXX");
if (-d $test_set) {
$file_prefix_skip = length($test_set) + 1;
$ret = &process_test_dir($test_set);
@ -433,6 +441,8 @@ run_test
local(*test) = @_;
local($name) = $test{':full-name'};
return undef if !&scrub_dir($tempdir);
if (defined $test{'stdin'}) {
return undef if !&write_file($tempi, $test{'stdin'});
$ifile = $tempi;
@ -444,8 +454,6 @@ run_test
return undef if !&write_file($temps, $test{'script'});
}
return undef if !&scrub_dir($tempdir);
if (!chdir($tempdir)) {
print STDERR "$prog: couldn't cd to $tempdir - $!\n";
return undef;

162
check.t
View File

@ -1,7 +1,9 @@
# $MirOS: src/bin/mksh/check.t,v 1.616 2013/06/03 22:28:28 tg Exp $
# $MirOS: src/bin/mksh/check.t,v 1.617 2013/07/21 18:35:57 tg Exp $
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
# $OpenBSD: regress.t,v 1.15 2013/07/01 17:25:27 jca Exp $
# $OpenBSD: obsd-regress.t,v 1.5 2013/07/01 17:25:27 jca Exp $
#-
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012, 2013
@ -4783,18 +4785,16 @@ expected-stdout:
---
name: regression-39
description:
set -e: errors in command substitutions aren't ignored
Not clear if they should be or not... bash passes here
this may actually be required for make, so changed the
test to make this an mksh feature, not a bug
arguments: !-e!
Only posh and oksh(2013-07) say hi below; FreeBSD sh,
GNU bash in POSIX mode, dash, ksh93, mksh dont. All of
them exit 0. The POSIX behaviour is needed by BSD make.
stdin:
set -e
echo `false; echo hi`
#expected-fail: yes
#expected-stdout:
# hi
echo $?
expected-stdout:
0
---
name: regression-40
description:
@ -8711,10 +8711,57 @@ expected-stdout:
bar
baz
---
name: oksh-shcrash
name: oksh-eval
description:
src/regress/bin/ksh/shcrash.sh,v 1.1
$OpenBSD: eval.sh,v 1.1 2010/03/24 08:29:44 fgsch Exp $
stdin:
a=
for n in ${a#*=}; do echo 1hu ${n} .; done
for n in "${a#*=}"; do echo 1hq ${n} .; done
for n in ${a##*=}; do echo 2hu ${n} .; done
for n in "${a##*=}"; do echo 2hq ${n} .; done
for n in ${a%=*}; do echo 1pu ${n} .; done
for n in "${a%=*}"; do echo 1pq ${n} .; done
for n in ${a%%=*}; do echo 2pu ${n} .; done
for n in "${a%%=*}"; do echo 2pq ${n} .; done
expected-stdout:
1hq .
2hq .
1pq .
2pq .
---
name: oksh-and-list-error-1
description:
Test exit status of rightmost element in 2 element && list in -e mode
stdin:
true && false
echo "should not print"
arguments: !-e!
expected-exit: e != 0
---
name: oksh-and-list-error-2
description:
Test exit status of rightmost element in 3 element && list in -e mode
stdin:
true && true && false
echo "should not print"
arguments: !-e!
expected-exit: e != 0
---
name: oksh-or-list-error-1
description:
Test exit status of || list in -e mode
stdin:
false || false
echo "should not print"
arguments: !-e!
expected-exit: e != 0
---
name: oksh-longline-crash
description:
This used to cause a core dump
stdin:
ulimit -c 0
deplibs="-lz -lpng /usr/local/lib/libjpeg.la -ltiff -lm -lX11 -lXext /usr/local/lib/libiconv.la -L/usr/local/lib -L/usr/ports/devel/gettext/w-gettext-0.10.40/gettext-0.10.40/intl/.libs /usr/local/lib/libintl.la /usr/local/lib/libglib.la /usr/local/lib/libgmodule.la -lintl -lm -lX11 -lXext -L/usr/X11R6/lib -lglib -lgmodule -L/usr/local/lib /usr/local/lib/libgdk.la -lintl -lm -lX11 -lXext -L/usr/X11R6/lib -lglib -lgmodule -L/usr/local/lib /usr/local/lib/libgtk.la -ltiff -ljpeg -lz -lpng -lm -lX11 -lXext -lintl -lglib -lgmodule -lgdk -lgtk -L/usr/X11R6/lib -lglib -lgmodule -L/usr/local/lib /usr/local/lib/libgdk_pixbuf.la -lz -lpng /usr/local/lib/libiconv.la -L/usr/local/lib -L/usr/ports/devel/gettext/w-gettext-0.10.40/gettext-0.10.40/intl/.libs /usr/local/lib/libintl.la /usr/local/lib/libglib.la -lm -lm /usr/local/lib/libaudiofile.la -lm -lm -laudiofile -L/usr/local/lib /usr/local/lib/libesd.la -lm -lz -L/usr/local/lib /usr/local/lib/libgnomesupport.la -lm -lz -lm -lglib -L/usr/local/lib /usr/local/lib/libgnome.la -lX11 -lXext /usr/local/lib/libiconv.la -L/usr/local/lib -L/usr/ports/devel/gettext/w-gettext-0.10.40/gettext-0.10.40/intl/.libs /usr/local/lib/libintl.la /usr/local/lib/libgmodule.la -lintl -lm -lX11 -lXext -L/usr/X11R6/lib -lglib -lgmodule -L/usr/local/lib /usr/local/lib/libgdk.la -lintl -lm -lX11 -lXext -L/usr/X11R6/lib -lglib -lgmodule -L/usr/local/lib /usr/local/lib/libgtk.la -lICE -lSM -lz -lpng /usr/local/lib/libungif.la /usr/local/lib/libjpeg.la -ltiff -lm -lz -lpng /usr/local/lib/libungif.la -lz /usr/local/lib/libjpeg.la -ltiff -L/usr/local/lib -L/usr/X11R6/lib /usr/local/lib/libgdk_imlib.la -lm -L/usr/local/lib /usr/local/lib/libart_lgpl.la -lm -lz -lm -lX11 -lXext -lintl -lglib -lgmodule -lgdk -lgtk -lICE -lSM -lm -lX11 -lXext -lintl -lglib -lgmodule -lgdk -lgtk -L/usr/X11R6/lib -lm -lz -lpng -lungif -lz -ljpeg -ltiff -ljpeg -lgdk_imlib -lglib -lm -laudiofile -lm -laudiofile -lesd -L/usr/local/lib /usr/local/lib/libgnomeui.la -lz -lz /usr/local/lib/libxml.la -lz -lz -lz /usr/local/lib/libxml.la -lm -lX11 -lXext /usr/local/lib/libiconv.la -L/usr/ports/devel/gettext/w-gettext-0.10.40/gettext-0.10.40/intl/.libs /usr/local/lib/libintl.la /usr/local/lib/libglib.la /usr/local/lib/libgmodule.la -lintl -lglib -lgmodule /usr/local/lib/libgdk.la /usr/local/lib/libgtk.la -L/usr/X11R6/lib -L/usr/local/lib /usr/local/lib/libglade.la -lz -lz -lz /usr/local/lib/libxml.la /usr/local/lib/libglib.la -lm -lm /usr/local/lib/libaudiofile.la -lm -lm -laudiofile /usr/local/lib/libesd.la -lm -lz /usr/local/lib/libgnomesupport.la -lm -lz -lm -lglib /usr/local/lib/libgnome.la -lX11 -lXext /usr/local/lib/libiconv.la -L/usr/ports/devel/gettext/w-gettext-0.10.40/gettext-0.10.40/intl/.libs /usr/local/lib/libintl.la /usr/local/lib/libgmodule.la -lintl -lm -lX11 -lXext -lglib -lgmodule /usr/local/lib/libgdk.la -lintl -lm -lX11 -lXext -lglib -lgmodule /usr/local/lib/libgtk.la -lICE -lSM -lz -lpng /usr/local/lib/libungif.la /usr/local/lib/libjpeg.la -ltiff -lm -lz -lz /usr/local/lib/libgdk_imlib.la /usr/local/lib/libart_lgpl.la -lm -lz -lm -lX11 -lXext -lintl -lglib -lgmodule -lgdk -lgtk -lm -lX11 -lXext -lintl -lglib -lgmodule -lgdk -lgtk -lm -lz -lungif -lz -ljpeg -ljpeg -lgdk_imlib -lglib -lm -laudiofile -lm -laudiofile -lesd /usr/local/lib/libgnomeui.la -L/usr/X11R6/lib -L/usr/local/lib /usr/local/lib/libglade-gnome.la /usr/local/lib/libglib.la -lm -lm /usr/local/lib/libaudiofile.la -lm -lm -laudiofile -L/usr/local/lib /usr/local/lib/libesd.la -lm -lz -L/usr/local/lib /usr/local/lib/libgnomesupport.la -lm -lz -lm -lglib -L/usr/local/lib /usr/local/lib/libgnome.la -lX11 -lXext /usr/local/lib/libiconv.la -L/usr/local/lib -L/usr/ports/devel/gettext/w-gettext-0.10.40/gettext-0.10.40/intl/.libs /usr/local/lib/libintl.la /usr/local/lib/libgmodule.la -lintl -lm -lX11 -lXext -L/usr/X11R6/lib -lglib -lgmodule -L/usr/local/lib /usr/local/lib/libgdk.la -lintl -lm -lX11 -lXext -L/usr/X11R6/lib -lglib -lgmodule -L/usr/local/lib /usr/local/lib/libgtk.la -lICE -lSM -lz -lpng /usr/local/lib/libungif.la /usr/local/lib/libjpeg.la -ltiff -lm -lz -lpng /usr/local/lib/libungif.la -lz /usr/local/lib/libjpeg.la -ltiff -L/usr/local/lib -L/usr/X11R6/lib /usr/local/lib/libgdk_imlib.la -lm -L/usr/local/lib /usr/local/lib/libart_lgpl.la -lm -lz -lm -lX11 -lXext -lintl -lglib -lgmodule -lgdk -lgtk -lICE -lSM -lm -lX11 -lXext -lintl -lglib -lgmodule -lgdk -lgtk -L/usr/X11R6/lib -lm -lz -lpng -lungif -lz -ljpeg -ltiff -ljpeg -lgdk_imlib -lglib -lm -laudiofile -lm -laudiofile -lesd -L/usr/local/lib /usr/local/lib/libgnomeui.la -L/usr/X11R6/lib -L/usr/local/lib"
specialdeplibs="-lgnomeui -lart_lgpl -lgdk_imlib -ltiff -ljpeg -lungif -lpng -lz -lSM -lICE -lgtk -lgdk -lgmodule -lintl -lXext -lX11 -lgnome -lgnomesupport -lesd -laudiofile -lm -lglib"
for deplib in $deplibs; do
@ -8731,6 +8778,99 @@ stdin:
esac
done
---
name: oksh-seterror-1
description:
The -e flag should be ignored when executing a compound list
followed by an if statement.
stdin:
if true; then false && false; fi
true
arguments: !-e!
expected-exit: e == 0
---
name: oksh-seterror-2
description:
The -e flag should be ignored when executing a compound list
followed by an if statement.
stdin:
if true; then if true; then false && false; fi; fi
true
arguments: !-e!
expected-exit: e == 0
---
name: oksh-seterror-3
description:
The -e flag should be ignored when executing a compound list
followed by an elif statement.
stdin:
if true; then :; elif true; then false && false; fi
arguments: !-e!
expected-exit: e == 0
---
name: oksh-seterror-4
description:
The -e flag should be ignored when executing a pipeline
beginning with '!'
stdin:
for i in 1 2 3
do
false && false
true || false
done
arguments: !-e!
expected-exit: e == 0
---
name: oksh-seterror-5
description:
The -e flag should be ignored when executing a pipeline
beginning with '!'
stdin:
! true | false
true
arguments: !-e!
expected-exit: e == 0
---
name: oksh-seterror-6
description:
When trapping ERR and EXIT, both traps should run in -e mode
when an error occurs.
stdin:
trap 'echo EXIT' EXIT
trap 'echo ERR' ERR
set -e
false
echo DONE
exit 0
arguments: !-e!
expected-exit: e != 0
expected-stdout:
ERR
EXIT
---
name: oksh-seterror-7
description:
The -e flag within a command substitution should be honored
stdin:
echo $( set -e; false; echo foo )
arguments: !-e!
expected-stdout:
---
name: oksh-input-comsub
description:
A command substitution using input redirection should exit with
failure if the input file does not exist.
stdin:
var=$(< non-existent)
expected-exit: e != 0
expected-stderr-pattern: /non-existent/
---
name: oksh-empty-for-list
description:
A for list which expands to zero items should not execute the body.
stdin:
set foo bar baz ; for out in ; do echo $out ; done
---
name: oksh-varfunction-mod1
description:
$OpenBSD: varfunction.sh,v 1.1 2003/12/15 05:28:40 otto Exp $

17
eval.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: eval.c,v 1.37 2011/10/11 14:32:43 otto Exp $ */
/* $OpenBSD: eval.c,v 1.39 2013/07/01 17:25:27 jca Exp $ */
/*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
@ -23,7 +23,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.139 2013/05/02 21:59:49 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.140 2013/07/21 18:36:00 tg Exp $");
/*
* string expansion
@ -870,7 +870,12 @@ expand(
break;
case XCOM:
if (newlines) {
if (x.u.shf == NULL) {
/* $(<...) failed */
subst_exstat = 1;
/* fake EOF */
c = EOF;
} else if (newlines) {
/* spit out saved NLs */
c = '\n';
--newlines;
@ -887,7 +892,8 @@ expand(
}
if (c == EOF) {
newlines = 0;
shf_close(x.u.shf);
if (x.u.shf)
shf_close(x.u.shf);
if (x.split)
subst_exstat = waitlast();
type = XBASE;
@ -1336,7 +1342,8 @@ comsub(Expand *xp, const char *cp, int fn MKSH_A_UNUSED)
shf = shf_open(name = evalstr(io->name, DOTILDE), O_RDONLY, 0,
SHF_MAPHI|SHF_CLEXEC);
if (shf == NULL)
errorf("%s: %s %s", name, "can't open", "$() input");
warningf(!Flag(FTALKING), "%s: %s %s: %s", name,
"can't open", "$(<...) input", cstrerror(errno));
} else if (fn == FUNSUB) {
int ofd1;
struct temp *tf = NULL;

14
exec.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: exec.c,v 1.49 2009/01/29 23:27:26 jaredy Exp $ */
/* $OpenBSD: exec.c,v 1.50 2013/06/10 21:09:27 millert Exp $ */
/*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
@ -23,7 +23,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.122 2013/06/03 22:28:31 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.123 2013/07/21 18:36:00 tg Exp $");
#ifndef MKSH_DEFAULT_EXECSHELL
#define MKSH_DEFAULT_EXECSHELL "/bin/sh"
@ -302,10 +302,12 @@ execute(struct op * volatile t,
case TAND:
rv = execute(t->left, XERROK, xerrok);
if ((rv == 0) == (t->type == TAND))
rv = execute(t->right, XERROK, xerrok);
flags |= XERROK;
if (xerrok)
*xerrok = 1;
rv = execute(t->right, flags & XERROK, xerrok);
else {
flags |= XERROK;
if (xerrok)
*xerrok = 1;
}
break;
case TBANG:

4
main.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: main.c,v 1.51 2012/09/10 01:25:30 tedu Exp $ */
/* $OpenBSD: main.c,v 1.52 2013/06/15 17:25:19 millert Exp $ */
/* $OpenBSD: tty.c,v 1.9 2006/03/14 22:08:01 deraadt Exp $ */
/* $OpenBSD: io.c,v 1.22 2006/03/17 16:30:13 millert Exp $ */
/* $OpenBSD: table.c,v 1.15 2012/02/19 07:52:30 otto Exp $ */
@ -34,7 +34,7 @@
#include <locale.h>
#endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.266 2013/06/03 22:28:04 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.267 2013/07/21 18:36:01 tg Exp $");
extern char **environ;

13
mksh.1
View File

@ -1,5 +1,5 @@
.\" $MirOS: src/bin/mksh/mksh.1,v 1.316 2013/06/03 22:28:06 tg Exp $
.\" $OpenBSD: ksh.1,v 1.146 2013/03/18 11:10:52 mpi Exp $
.\" $MirOS: src/bin/mksh/mksh.1,v 1.317 2013/07/21 18:36:02 tg Exp $
.\" $OpenBSD: ksh.1,v 1.147 2013/06/13 19:43:09 millert Exp $
.\"-
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
.\" 2010, 2011, 2012, 2013
@ -74,7 +74,7 @@
.\" with -mandoc, it might implement .Mx itself, but we want to
.\" use our own definition. And .Dd must come *first*, always.
.\"
.Dd $Mdocdate: June 3 2013 $
.Dd $Mdocdate: July 21 2013 $
.\"
.\" Check which macro package we use, and do other -mdoc setup.
.\"
@ -4046,11 +4046,14 @@ explicitly tested by a shell construct such as
.Ic if ,
.Ic until ,
.Ic while ,
.Ic && ,
.Ic \*(Ba\*(Ba ,
or
.Ic !\&
statements.
For
.Ic &&
or
.Ic \*(Ba\*(Ba ,
only the status of the last command is tested.
.It Fl f \*(Ba Fl o Ic noglob
Do not expand file name patterns.
.It Fl h \*(Ba Fl o Ic trackall

8
shf.c
View File

@ -25,7 +25,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.60 2013/06/01 20:34:01 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.61 2013/07/21 18:36:03 tg Exp $");
/* flags to shf_emptybuf() */
#define EB_READSW 0x01 /* about to switch to reading */
@ -52,7 +52,7 @@ shf_open(const char *name, int oflags, int mode, int sflags)
ssize_t bsize =
/* at most 512 */
sflags & SHF_UNBUF ? (sflags & SHF_RD ? 1 : 0) : SHF_BSIZE;
int fd;
int fd, eno;
/* Done before open so if alloca fails, fd won't be lost. */
shf = alloc(sizeof(struct shf) + bsize, ATEMP);
@ -64,16 +64,20 @@ shf_open(const char *name, int oflags, int mode, int sflags)
fd = open(name, oflags, mode);
if (fd < 0) {
eno = errno;
afree(shf, shf->areap);
errno = eno;
return (NULL);
}
if ((sflags & SHF_MAPHI) && fd < FDBASE) {
int nfd;
nfd = fcntl(fd, F_DUPFD, FDBASE);
eno = errno;
close(fd);
if (nfd < 0) {
afree(shf, shf->areap);
errno = eno;
return (NULL);
}
fd = nfd;