The following issue has been SUBMITTED. 
====================================================================== 
http://austingroupbugs.net/view.php?id=1157 
====================================================================== 
Reported By:                geoffclare
Assigned To:                
====================================================================== 
Project:                    1003.1(2016)/Issue7+TC2
Issue ID:                   1157
Category:                   Shell and Utilities
Type:                       Clarification Requested
Severity:                   Objection
Priority:                   normal
Status:                     New
Name:                       Geoff Clare 
Organization:               The Open Group 
User Reference:              
Section:                    2.14 exec 
Page Number:                2397-2398 
Line Number:                76683-76745 
Interp Status:              --- 
Final Accepted Text:         
====================================================================== 
Date Submitted:             2017-07-26 15:40 UTC
Last Modified:              2017-07-26 15:40 UTC
====================================================================== 
Summary:                    major overhaul of exec special built-in
Description: 
Discussion on the mailing list identified some problems with the
description of the exec special built-in utility; it is in need of a
major overhaul.

The discussion was triggered by a question about whether exec can
execute functions.  Although it is known that the original intent was
that exec can only execute non-built-in utilities (because the POSIX
description was based on ksh88), and it is clear from the EXIT STATUS
section that the standard requires this (because it refers to a program
which overlays the shell process), and all of the widely used shells
conform to this, there are some lesser used shells (notably mksh and
zsh) which allow execution of functions and built-in utilities via
exec, and there appear to be pros and cons for both approaches. 
Therefore, the proposed changes have two options: one which clarifies
the current requirement and one which allows both behaviours.

Desired Action: 


On page 2367 line 75579-75599 section 2.9.1 replace item b
with:<blockquote>Otherwise, the shell shall execute a non-built-in utility
as described in [xref to 2.9.1.2].</blockquote>
On page 2367 line 75608-75621 section 2.9.1 replace item 2
with:<blockquote>If the command name contains at least one <slash>, the
shell shall execute a non-built-in utility as described in [xref to
2.9.1.2].</blockquote>
On page 2368 line 75627 section 2.9.1 add a new section:<blockquote>2.9.1.2
Non-built-in Utility Execution

When the shell executes a non-built-in utility, if the execution is not
being made via the <i>exec</i> special built-in utility, the shell shall
execute the utility in a separate utility environment (see [xref to
2.12]).

If the execution is being made via the <i>exec</i> special built-in
utility, the shell shall not create a separate utility environment for this
execution; the new process image shall replace the current shell execution
environment.  If the current shell environment is a subshell environment,
the new process image shall replace the subshell environment and the shell
shall continue in the environment from which that subshell environment was
invoked.

In either case, execution of the utility in the specified environment shall
be performed as follows:

1.<blockquote>If the command name does not contain any <slash> characters,
the command name shall be searched for using the PATH environment variable
as described in [xref to XBD Chapter 8]:

a.<blockquote>If the search is successful, the shell shall execute the
utility with actions equivalent to calling the <i>execl</i>() function as
defined in the System Interfaces volume of POSIX.1-2008 with the
<i>path</i> argument set to the pathname resulting from the search,
<i>arg0</i> set to the command name, and the remaining <i>execl</i>()
arguments set to the command arguments (if any) and the null terminator.

If the <i>execl</i>() function fails due to an error equivalent to the
[ENOEXEC] error defined in the System Interfaces volume of POSIX.1-2008,
the shell shall execute a command equivalent to having a shell invoked with
the pathname resulting from the search as its first operand, with any
remaining arguments passed to the new shell, except that the value of "$0"
in the new shell may be set to the command name. If the executable file is
not a text file, the shell may bypass this command execution. In this case,
it shall write an error message, and the <i>exec</i> command shall fail
with an exit status of 126.

It is unspecified whether environment variables that were passed to the
shell when it was invoked, but were not used to initialize shell variables
(see [xref to 2.5.3]) because they had invalid names, are included in the
environment passed to <i>execl</i>() and (if <i>execl</i>() fails as
described above) to the new shell.</blockquote>
b.<blockquote>If the search is unsuccessful, the command shall fail with an
exit status of 127 and the shell shall write an error
message.</blockquote></blockquote>
2.<blockquote>If the command name contains at least one <slash>:

a.<blockquote>If the named utility exists, the shell shall execute the
utility with actions equivalent to calling the <i>execl</i>() function as
defined in the System Interfaces volume of POSIX.1-2008 with the
<i>path</i> and <i>arg0</i> arguments set to the command name, and the
remaining <i>execl</i>() arguments set to the command arguments (if any)
and the null terminator.

If the <i>execl</i>() function fails due to an error equivalent to the
[ENOEXEC] error, the shell shall execute a command equivalent to having a
shell invoked with the command name as its first operand, with any
remaining arguments passed to the new shell. If the executable file is not
a text file, the shell may bypass this command execution. In this case, it
shall write an error message, and the <i>exec</i> command shall fail with
an exit status of 126.

It is unspecified whether environment variables that were passed to the
shell when it was invoked, but were not used to initialize shell variables
(see [xref to 2.5.3]) because they had invalid names, are included in the
environment passed to <i>execl</i>() and (if <i>execl</i>() fails as
described above) to the new shell.</blockquote>
b.<blockquote>If the named utility does not exist, the command shall fail
with an exit status of 127 and the shell shall write an error
message.</blockquote></blockquote></blockquote>
On page 2397 line 76683 section 2.14 exec, change NAME
from:<blockquote>exec - execute commands and open, close, or copy file
descriptors</blockquote>to:<blockquote>exec - perform redirections in the
current shell or execute a utility</blockquote>
On page 2397 line 76685 section 2.14 exec, change SYNOPSIS
from:<blockquote>exec [command
[argument...]]</blockquote>to:<blockquote>exec [utility
[argument...]]</blockquote>
On page 2397 line 76687-76689 section 2.14 exec, change:<blockquote>The
<i>exec</i> utility shall open, close, and/or copy file descriptors as
specified by any redirections as part of the command.

If <i>exec</i> is specified without <i>command</i> or <i>arguments</i>, and
any file descriptors with numbers greater than 2 are opened with associated
redirection statements, ...</blockquote>to:<blockquote>If <i>exec</i> is
specified with no operands, any redirections associated with the
<i>exec</i> command shall be made in the current shell execution
environment.  If any file descriptors with numbers greater than 2 are
opened by those redirections, ...</blockquote>
On page 2397 line 76693 section 2.14 exec,  append to the
paragraph:<blockquote>If the result of the redirections would be that file
descriptor 0, 1, or 2 is closed, implementations may open the file
descriptor to an unspecified file.</blockquote>
On page 2397 line 76694-76696 section 2.14 exec, change:<blockquote>If
<i>exec</i> is specified with <i>command</i>, it shall replace the shell
with <i>command</i> without creating a new process. If <i>arguments</i> are
specified, they shall be arguments to <i>command</i>. Redirection affects
the current shell execution environment.</blockquote>
to one of the following options:

OPTION 1<blockquote>If <i>exec</i> is specified with a <i>utility</i>
operand, the shell shall execute a non-built-in utility as described in
[xref to 2.9.1.2] with <i>utility</i> as the command name and the
<i>argument</i> operands (if any) as the command arguments.

If the <i>exec</i> command fails, a non-interactive shell shall exit from
the current shell execution environment; [UP]an interactive shell may exit
from a subshell environment but shall not exit if the current shell
environment is not a subshell environment[/UP].

[UP]If the <i>exec</i> command fails and the shell does not exit, any
redirections associated with the <i>exec</i> command that were successfully
made shall take effect in the current shell execution environment.
[/UP]</blockquote>
OPTION 2<blockquote>If <i>exec</i> is specified with a <i>utility</i>
operand:

1.<blockquote>If the <i>utility</i> does not contain any <slash> characters
and either the named utility is implemented as a shell built-in or a
function of the same name exists, it is unspecified whether or not the
shell executes the built-in utility or function.  If it does, the execution
shall be performed as described in [xref to 2.9.1.1] and the shell shall
then exit from the current shell execution environment as if by executing
the <i>exit</i> special built-in utility with no arguments.  If the shell
does not execute the built-in utility or function, it shall execute a
non-built-in utility as described below.</blockquote>
2.<blockquote>The shell shall execute a non-built-in utility as described
in [xref to 2.9.1.2] with <i>utility</i> as the command name and the
<i>argument</i> operands (if any) as the command arguments.

If the <i>exec</i> command fails, a non-interactive shell shall exit from
the current shell execution environment; [UP]an interactive shell may exit
from a subshell environment but shall not exit if the current shell
environment is not a subshell environment[/UP].

[UP]If the <i>exec</i> command fails and the shell does not exit, any
redirections associated with the <i>exec</i> command that were successfully
made shall take effect in the current shell execution environment.
[/UP]</blockquote></blockquote>
On page 2397 line 76718-76722 section 2.14 exec, change EXIT STATUS
from:<blockquote>If <i>command</i> is specified, <i>exec</i> shall not
return to the shell; rather, the exit status of the process shall be the
exit status of the program implementing <i>command</i>, which overlaid the
shell. If <i>command</i> is not found, the exit status shall be 127. If
<i>command</i> is found, but it is not an executable utility, the exit
status shall be 126. If a redirection error occurs (see [xref to 2.8.1]),
the shell shall exit with a value in the range 1-125. Otherwise,
<i>exec</i> shall return a zero exit status.</blockquote>to:<blockquote>If
<i>utility</i> is specified and is executed, <i>exec</i> shall not return
to the shell; rather, the exit status of the current shell execution
environment shall be the exit status of <i>utility</i>. If <i>utility</i>
is specified and an attempt to execute it as a non-built-in utility fails,
the exit status shall be as described in [xref to 2.9.1.2].  If a
redirection error occurs (see [xref to 2.8.1]), the exit status shall be a
value in the range 1-125. Otherwise, <i>exec</i> shall return a zero exit
status.</blockquote>
If OPTION 1 is chosen above, then also make the following two changes.

On page 2398 line 76737 section 2.14 exec, add to EXAMPLES:<blockquote>An
application that is not concerned with strict conformance can make use of
optional %g support known to be present in the implementation's
<i>printf</i> utility by ensuring that any shell built-in version is not
executed instead, and using a subshell so that the shell continues
afterwards:

<tt>(exec printf '%g\n' "$float_value")</tt></blockquote>
On page 2694 line 87961 section env, change:<blockquote>Therefore, shell
functions, special built-ins, and built-ins that are only provided by the
shell are not found.</blockquote>to:<blockquote>Therefore, shell functions,
special built-ins, and built-ins that are only provided by the shell are
not found by this type of <i>env</i> implementation.  However, <i>env</i>
can be implemented as a shell built-in, in which case it may be able to
execute shell functions and built-ins.  An application wishing to ensure
execution of a non-built-in utility can use <i>exec</i> in a subshell for
this purpose.</blockquote>
If OPTION 2 is chosen above, then also make the following three changes.

On page 2398 line 76726 section 2.14 exec, change APPLICATION USAGE
from:<blockquote>None.</blockquote>to:<blockquote>Since it is unspecified
whether <i>exec</i> executes built-in utilities and functions, portable
applications cannot rely on the use of <i>exec</i> in a subshell to bypass
these and ensure the execution of a non-built-in utility.  The only
portable ways to ensure execution of a non-built-in utility are:

1.<blockquote>Include at least one <slash> in the command
name.</blockquote>
2.<blockquote>Execute it via the <i>env</i> utility, while ensuring that a
non-built-in version of <i>env</i> is used.</blockquote>For example, the
following function employs method 1 to execute a non-built-in version of
any utility:<pre>
exec_non_built_in() (
    safe_exec() {
        case "$1" in
        (-*) exec ./"$@" ;;
        (*)  exec "$@" ;;
        esac
        exit # can only be reached if shell is interactive
    }
    case "$1" in
    (*/*)
        safe_exec "$@"
        ;;
    (*)
        case "$PATH" in
        (*[!:]:) dirs="${PATH}:" ;;
        (*) dirs="$PATH" ;;
        esac
        IFS=":"
        set -f
        for dir in $dirs
        do
            case "$dir" in
            ("") dir="." ;;
            (*/) dir="${dir%/}" ;;
            esac
            if test -x "$dir/$1" && test -f "$dir/$1"
            then
                unset IFS
                safe_exec "$dir"/"$@"
            fi
        done
        printf >&2 "%s not found\n" "$1"
        exit 127
        ;;
    esac
)
</pre>Method 2 reduces to method 1 applied to the <i>env</i> utility, but
the search for the non-built-in implementation of <i>env</i> can be done at
the time the application is configured and installed. This reduces
complexity in the application itself, but at the expense of an extra
<i>exec</i>() call when it uses <i>env</i> to execute a
utility.</blockquote>
On page 2398 line 76745 section 2.14 exec, add <i>env</i> to SEE ALSO.

On page 2694 line 87961 section env, change:<blockquote>Therefore, shell
functions, special built-ins, and built-ins that are only provided by the
shell are not found.</blockquote>to:<blockquote>Therefore, shell functions,
special built-ins, and built-ins that are only provided by the shell are
not found by this type of <i>env</i> implementation.  However, <i>env</i>
can be implemented as a shell built-in, in which case it may be able to
execute shell functions and built-ins.  For methods of ensuring execution
of a non-built-in utility, see the APPLICATION USAGE section of [xref to
exec].</blockquote>

====================================================================== 

Issue History 
Date Modified    Username       Field                    Change               
====================================================================== 
2017-07-26 15:40 geoffclare     New Issue                                    
2017-07-26 15:40 geoffclare     Name                      => Geoff Clare     
2017-07-26 15:40 geoffclare     Organization              => The Open Group  
2017-07-26 15:40 geoffclare     Section                   => 2.14 exec       
2017-07-26 15:40 geoffclare     Page Number               => 2397-2398       
2017-07-26 15:40 geoffclare     Line Number               => 76683-76745     
2017-07-26 15:40 geoffclare     Interp Status             => ---             
======================================================================


Reply via email to