Austin Group Defect Tracker

Aardvark Mark IV


Viewing Issue Simple Details Jump to Notes ] Issue History ] Print ]
ID Category Severity Type Date Submitted Last Update
0001157 [1003.1(2016/18)/Issue7+TC2] Shell and Utilities Objection Clarification Requested 2017-07-26 15:40 2019-11-07 09:38
Reporter geoffclare View Status public  
Assigned To
Priority normal Resolution Accepted  
Status Applied  
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 See Note: 0004204
Summary 0001157: 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:
Otherwise, the shell shall execute a non-built-in utility as described in [xref to 2.9.1.2].

On page 2367 line 75608-75621 section 2.9.1 replace item 2 with:
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].

On page 2368 line 75627 section 2.9.1 add a new section:
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 exec 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 exec 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.
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.
If the search is successful, the shell shall execute the utility with actions equivalent to calling the execl() function as defined in the System Interfaces volume of POSIX.1-2008 with the path argument set to the pathname resulting from the search, arg0 set to the command name, and the remaining execl() arguments set to the command arguments (if any) and the null terminator.

If the execl() 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 exec 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 execl() and (if execl() fails as described above) to the new shell.

b.
If the search is unsuccessful, the command shall fail with an exit status of 127 and the shell shall write an error message.

2.
If the command name contains at least one <slash>:

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

If the execl() 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 exec 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 execl() and (if execl() fails as described above) to the new shell.

b.
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.

On page 2397 line 76683 section 2.14 exec, change NAME from:
exec - execute commands and open, close, or copy file descriptors
to:
exec - perform redirections in the current shell or execute a utility

On page 2397 line 76685 section 2.14 exec, change SYNOPSIS from:
exec [command [argument...]]
to:
exec [utility [argument...]]

On page 2397 line 76687-76689 section 2.14 exec, change:
The exec utility shall open, close, and/or copy file descriptors as specified by any redirections as part of the command.

If exec is specified without command or arguments, and any file descriptors with numbers greater than 2 are opened with associated redirection statements, ...
to:
If exec is specified with no operands, any redirections associated with the exec command shall be made in the current shell execution environment. If any file descriptors with numbers greater than 2 are opened by those redirections, ...

On page 2397 line 76693 section 2.14 exec, append to the paragraph:
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.

On page 2397 line 76694-76696 section 2.14 exec, change:
If exec is specified with command, it shall replace the shell with command without creating a new process. If arguments are specified, they shall be arguments to command. Redirection affects the current shell execution environment.

to one of the following options:

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

If the exec 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 exec command fails and the shell does not exit, any redirections associated with the exec command that were successfully made shall take effect in the current shell execution environment. [/UP]

OPTION 2
If exec is specified with a utility operand:

1.
If the utility 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 exit 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.

2.
The shell shall execute a non-built-in utility as described in [xref to 2.9.1.2] with utility as the command name and the argument operands (if any) as the command arguments.

If the exec 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 exec command fails and the shell does not exit, any redirections associated with the exec command that were successfully made shall take effect in the current shell execution environment. [/UP]

On page 2397 line 76718-76722 section 2.14 exec, change EXIT STATUS from:
If command is specified, exec shall not return to the shell; rather, the exit status of the process shall be the exit status of the program implementing command, which overlaid the shell. If command is not found, the exit status shall be 127. If command 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, exec shall return a zero exit status.
to:
If utility is specified and is executed, exec shall not return to the shell; rather, the exit status of the current shell execution environment shall be the exit status of utility. If utility 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, exec shall return a zero exit status.

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:
An application that is not concerned with strict conformance can make use of optional %g support known to be present in the implementation's printf 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>

On page 2694 line 87961 section env, change:
Therefore, shell functions, special built-ins, and built-ins that are only provided by the shell are not found.
to:
Therefore, shell functions, special built-ins, and built-ins that are only provided by the shell are not found by this type of env implementation. However, env 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 exec in a subshell for this purpose.

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:
None.
to:
Since it is unspecified whether exec executes built-in utilities and functions, portable applications cannot rely on the use of exec 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. Include at least one <slash> in the command name.

2. Execute it via the env utility, while ensuring that a non-built-in version of env is used.

For example, the following function employs method 1 to execute a non-built-in version of any utility:
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
)
Method 2 reduces to method 1 applied to the env utility, but the search for the non-built-in implementation of env 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 exec() call when it uses env to execute a utility.

On page 2398 line 76745 section 2.14 exec, add env to SEE ALSO.

On page 2694 line 87961 section env, change:
Therefore, shell functions, special built-ins, and built-ins that are only provided by the shell are not found.
to:
Therefore, shell functions, special built-ins, and built-ins that are only provided by the shell are not found by this type of env implementation. However, env 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].

Tags tc3-2008
Attached Files

- Relationships
related to 0000252Appliedajosey 1003.1(2008)/Issue 7 dot should follow Utility Syntax Guidelines 

-  Notes
(0003822)
kre (reporter)
2017-09-04 16:15
edited on: 2017-09-04 17:28

In the case that option 2 is chosen, the wording

   If the utility does not contain any <slash> characters

should be changed to

   If the utility operand does not contain any <slash> characters

(or alternatively, delete "the" ... "If utility does not contain...")

just so it is clear what is intended (and I do not intend to remove the
italics from "utility" - just beyond my ability to include in this note.)

(0004204)
nick (manager)
2019-01-10 17:32

Use option 1 in the desired action.
(0004205)
shware_systems (reporter)
2019-01-10 17:59
edited on: 2019-01-10 18:00

It was noted in discussions that the behavior of Option 2 was enabled by the shells mentioned in their non-conforming mode of operation, and used Option 1 in their conforming mode. While the behavior of Option 2 is seen as useful, the discussion leaned more towards this should be something scripts explicitly request somehow for it to be considered portable and backwards compatible; either by the utility implementing an enabling switch, e.g. -b or -f, or as another possibility adding an option to the set command that might have a similar effect on other utilities, such as command, that take utility names as arguments.


- 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 => ---
2017-07-26 15:49 geoffclare Desired Action Updated
2017-09-04 16:15 kre Note Added: 0003822
2017-09-04 17:28 kre Note Edited: 0003822
2019-01-10 17:26 eblake Relationship added related to 0000252
2019-01-10 17:32 nick Note Added: 0004204
2019-01-10 17:33 nick Final Accepted Text => See Note: 0004204
2019-01-10 17:33 nick Resolution Open => Accepted
2019-01-10 17:33 nick Tag Attached: issue8
2019-01-10 17:34 nick Tag Detached: issue8
2019-01-10 17:34 nick Tag Attached: tc3-2008
2019-01-10 17:34 nick Status New => Resolved
2019-01-10 17:59 shware_systems Note Added: 0004205
2019-01-10 18:00 shware_systems Note Edited: 0004205
2019-11-07 09:38 geoffclare Status Resolved => Applied


Mantis 1.1.6[^]
Copyright © 2000 - 2008 Mantis Group
Powered by Mantis Bugtracker