Bug 243023 - typeset does not make variable local in function
Summary: typeset does not make variable local in function
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Fedora
Classification: Fedora
Component: ksh
Version: 6
Hardware: All
OS: Linux
low
medium
Target Milestone: ---
Assignee: Tomas Smetana
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2007-06-06 22:09 UTC by Clay Harris
Modified: 2007-11-30 22:12 UTC (History)
0 users

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2007-06-18 08:22:10 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)

Description Clay Harris 2007-06-06 22:09:41 UTC
Description of problem:
When used in a function, typeset should always create a local instance
of its variables.  It is failing to do this.

Version-Release number of selected component (if applicable):
fc6 package ksh-20060214-1.1

How reproducible:
typeset a variable in a function and display that variable on return
from the function.  The variable should not contain the value set in
the function.

Steps to Reproduce:

----------------------------------------------------------------
x1:

#!/bin/ksh

F1 () {
        typeset T1

        T1="Wrong!"
}

echo "Before=$T1"
F1
echo "After=$T1"
----------------------------------------------------------------
  
Actual results:
/bin/ksh ./x1
Before=
After=Wrong!


Expected results:
/bin/ksh ./x1
Before=
After=


Additional info:

Comment 1 Tomas Smetana 2007-06-07 07:57:14 UTC
From the ksh man page:

For historical reasons, there are two ways to define functions, the name()
syntax  and the function name syntax, ...
(...)
Functions defined with the name() syntax and functions defined with the function
name syntax that are invoked with the . special built-in are executed in the
caller’s environment and share all variables and traps with the caller.

So if you try the following, you'll see the difference:

#!/bin/ksh

F1 () {
        typeset T1
        T1="Wrong!"
}

function F2 {
        typeset T2
        T2="Right"
}

echo "Before=$T1"
F1
echo "After=$T1"
echo "Before=$T2"
F2
echo "After=$T2"

This is a documented and expected behaviour. Do you agree?

Comment 2 Clay Harris 2007-06-07 19:43:08 UTC
First off, I find the man page description that you have quoted to be
confusing.  It appears to say that functions defined either way are handled
the same.  If there is a difference between the definition forms, making
the man page clearer would be a good thing.

But, in any case, I disagree that this is the documented or expected
behavior.  The man page also states:

"However, the typeset special built-in command used within a function defines
local variables whose scope includes the current function."

In my mind, this is the primary use of typeset.  In any case, typeset should
certainly not act differently depending on how the function was declared.

Think for a moment about a function containing a statement like:
typeset -r IFS=':'
Under this ksh, this function could only be called once (subsequent
calls would error on redefinition of a readonly variable) and worse yet,
you've now permenantly defined IFS for the entire script.  Even without
the -r, the whole point is to make that instance of IFS local to the
function.

typeset correctly makes the variable local in *all other* versions of ksh
I work with, regardless of which syntax is used to define the function. 
This includes the ones packaged with:  aix, tru64, solaris, and hpux.
It also has the correct behavior in pdksh (packaged with many linux distros
including RHEL4) and with all versions of bash.

Comment 3 Tomas Smetana 2007-06-11 10:37:43 UTC
The manpage part you cite is about functions defined with function keyword...
You may also want to read 'typeset --man'. I really don't see anything "wrong"
on the behaviour.

The "all other versions" you mentioned are all ksh88 implementations -- FC6
comes with ksh93.

Comment 4 Clay Harris 2007-06-11 18:46:53 UTC
I'm still not sure I'm totally on-board here.
It is not clear that the System V Release 2 semantics of 'name ()'
would prohibit typeset from making a variable local.

I agree that the description of typeset in the Functions section of the
man93 page is contained within the paragraph dealing with the 'function name'
definition.  However, both ways to define a function share all variables
(by default) and the paragraph describing 'name ()' does not specify the
behavior of typeset.

Furthermore, the man93 definition of the typeset builtin says:
"When invoked inside a function, a new instance of the variable vname is created.
The variable's value and type are restored when the function completes."
There is no qualification here for typeset to work differently, based on
which syntax was used to define the function or anything else.

If Posix really intended to disable the functionality of typeset for 'name ()'
functions, that would be a really stupid thing for them to have done!
If they didn't, then ksh should be fixed.  If they did, then the man page
describing the typeset builtin is wrong.  Either way, something needs to
be fixed here.  I'm hoping it's the former.

Comment 5 Tomas Smetana 2007-06-12 13:07:53 UTC
POSIX doesn't say anything about typeset. It only says that function is defined:
    fname() compound-command[io-redirect ...]
where compound-command is 
    (compound-list) => the compound-list is executed in subshell environment
or
    {compound-list} => the compound-list is executed in current environment
The later is our case and that's why any variable (no matter how defined) is
visible in the caller's environment. And ksh93 works exactly according to the
specification (unlike ksh88).

Man page in ksh-20060214-1.1 says "When invoked inside a function defined with
the function name syntax, a new instance of the variable vname is created...".

I'm sorry -- I still don't see anything that should be fixed.

Comment 6 Clay Harris 2007-06-12 17:28:33 UTC
It looks like POSIX really was just stupid here.  Considering a "typeset name"
to be a NO-OP in "fname ()" functions is a very bad decision.  The only reason
a script writer would put "typeset name" into a function is to make name a
local variable.  To disregard the script writer's explicit command for no good
reason is at best extremely irritating.

In any case, I now consider this bug to be a documentation bug.
As quoted above, the typeset builtin claims it always creates a local
variable (without exception).  The documentation should be amended to
state that while it always does this in "function fname" functions, that
it never does this in "fname ()" functions.

Comment 7 Tomas Smetana 2007-06-18 08:22:10 UTC
I went through the documentation and it's quite clear (I have quoted the
disputable part of 'man ksh' in the comment #5). I don't consider this to be
even a documentation issue.


Note You need to log in before you can comment on or make changes to this bug.