zsh-workers
 help / color / mirror / code / Atom feed
* Somewhat unexpected results of {myfd}>&1 when noclobber set
@ 2013-03-09 10:33 Mikael Magnusson
  2013-03-09 15:12 ` Bart Schaefer
  0 siblings, 1 reply; 6+ messages in thread
From: Mikael Magnusson @ 2013-03-09 10:33 UTC (permalink / raw)
  To: zsh workers

(You can skip this most of this part, just included some variations for fun)
% setopt noclobber
% : {foo}>&1
% echo $foo
15
% bar=7+8
% : {bar}>&1
zsh: can't clobber parameter bar containing file descriptor 15
% bar=foo
% : {bar}>&1
zsh: can't clobber parameter bar containing file descriptor 15
% bar=( 14 15 )
% : {bar}>&1
zsh: bad math expression: operator expected at `15'
% echo $bar
16
% bar=foo
% : {bar}>&1
zsh: can't clobber parameter bar containing file descriptor 15
% foo=
% : {bar}>&1
zsh: can't clobber parameter bar containing file descriptor 15
% echo $bar
15
(at this point bar somehow became of type "integer", i think after it
was an array, so the earlier assignment bar=foo resolved foo to 15).

Of course, all these are the result of the fact that when the
clobbering is checked, the parameter name is passed to getintvalue()
which does mathevali() on the contents (possibly after joining if it
was an array). Should we perhaps instead explicitly check that the
parameter is a) a scalar b) just do atoi() or whichever function is
best for this, and compare directly?

I think it's at least not expected that this parameter is only subject
to math evaluation if the clobber option is unset.

-- 
Mikael Magnusson


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Somewhat unexpected results of {myfd}>&1 when noclobber set
  2013-03-09 10:33 Somewhat unexpected results of {myfd}>&1 when noclobber set Mikael Magnusson
@ 2013-03-09 15:12 ` Bart Schaefer
  2013-03-10 12:11   ` Mikael Magnusson
  2013-03-10 18:52   ` Peter Stephenson
  0 siblings, 2 replies; 6+ messages in thread
From: Bart Schaefer @ 2013-03-09 15:12 UTC (permalink / raw)
  To: zsh workers

On Mar 9, 11:33am, Mikael Magnusson wrote:
}
} % bar=( 14 15 )
} % : {bar}>&1
} zsh: bad math expression: operator expected at `15'
} % echo $bar
} 16

This is clearly a bug.  Failing the math eval should either abort the
entire operation, or not print the warning.  I think the latter would
be considered the intended behavior, that is, bar does not contain a
descriptor so it simply gets assigned a new one by the redirection.

} % bar=foo
} % : {bar}>&1
} zsh: can't clobber parameter bar containing file descriptor 15
} % foo=
} % : {bar}>&1
} zsh: can't clobber parameter bar containing file descriptor 15
} % echo $bar
} 15

I can't reproduce that one.  For me, after unsetting foo or setting it
to empty, {bar}>&1 simply assigns a new descriptor to bar.

} (at this point bar somehow became of type "integer", i think after it
} was an array, so the earlier assignment bar=foo resolved foo to 15).

Variables to which descriptors are assigned by redirection are set to
integer type, even if their original type was something else.  Given
that I can't reproduce other parts of your steps, I can't say whether
this happened coincident with the spurious "bad math expression" or
somewhere else.

} I think it's at least not expected that this parameter is only subject
} to math evaluation if the clobber option is unset.

Just to clarify:  The statements

    setopt clobber
    bar=15
    : {bar}>&2

do NOT result in 2 being dup'd to 15, it results in 2 being dup'd to a
new descriptor and that new descriptor being assigned to bar.  The
value is *examined* only when noclobber, so whether it is also math-
evaluated is really beside the point.

The real question is whether math evaluation is applied when you do

    print something >&$bar

If $bar is not evaluated in that context, then it should not be in the
dup context either, but if it IS evaluated in that context, then it
should be treated consistently .  Guess what:

    integer bar=1+1
    print something >&$bar

DOES print to stderr, so I would argue that the current behavior is
the correct one (except for the spurious warning message).


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Somewhat unexpected results of {myfd}>&1 when noclobber set
  2013-03-09 15:12 ` Bart Schaefer
@ 2013-03-10 12:11   ` Mikael Magnusson
  2013-03-10 18:26     ` Bart Schaefer
  2013-03-10 18:52   ` Peter Stephenson
  1 sibling, 1 reply; 6+ messages in thread
From: Mikael Magnusson @ 2013-03-10 12:11 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: zsh workers

On 9 March 2013 16:12, Bart Schaefer <schaefer@brasslantern.com> wrote:

> The real question is whether math evaluation is applied when you do
>
>     print something >&$bar
>
> If $bar is not evaluated in that context, then it should not be in the
> dup context either, but if it IS evaluated in that context, then it
> should be treated consistently .  Guess what:
>
>     integer bar=1+1
>     print something >&$bar
>
> DOES print to stderr, so I would argue that the current behavior is
> the correct one (except for the spurious warning message).

Well, this 1+1 is evaluated when you assign to bar, not when you do >&$bar...
(not ignoring the rest of the message, just replying to this part for now).

% foo=1+1
% echo $foo
1+1
% print something >&$foo

results in the file 1+1 being created with contents 'something'.

-- 
Mikael Magnusson


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Somewhat unexpected results of {myfd}>&1 when noclobber set
  2013-03-10 12:11   ` Mikael Magnusson
@ 2013-03-10 18:26     ` Bart Schaefer
  0 siblings, 0 replies; 6+ messages in thread
From: Bart Schaefer @ 2013-03-10 18:26 UTC (permalink / raw)
  To: zsh workers

On Mar 10,  1:11pm, Mikael Magnusson wrote:
}
} On 9 March 2013 16:12, Bart Schaefer <schaefer@brasslantern.com> wrote:
} 
} >     integer bar=1+1
} >     print something >&$bar
} 
} Well, this 1+1 is evaluated when you assign to bar, not when you do >&$bar...
} (not ignoring the rest of the message, just replying to this part for now).
} 
} % foo=1+1
} % echo $foo
} 1+1
} % print something >&$foo
} 
} results in the file 1+1 being created with contents 'something'.

You missed the very important "integer" declaration.  If you change your
test to begin

% integer foo=1+1

you will get a very different result.  Because the variables created with
{foo}>& are implicitly given integer type, you have to try >&$foo with an
integer foo, not an ordinary scalar foo.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Somewhat unexpected results of {myfd}>&1 when noclobber set
  2013-03-09 15:12 ` Bart Schaefer
  2013-03-10 12:11   ` Mikael Magnusson
@ 2013-03-10 18:52   ` Peter Stephenson
  2013-03-10 20:17     ` Peter Stephenson
  1 sibling, 1 reply; 6+ messages in thread
From: Peter Stephenson @ 2013-03-10 18:52 UTC (permalink / raw)
  To: zsh workers

On Sat, 09 Mar 2013 07:12:52 -0800
Bart Schaefer <schaefer@brasslantern.com> wrote:
> On Mar 9, 11:33am, Mikael Magnusson wrote:
> }
> } % bar=( 14 15 )
> } % : {bar}>&1
> } zsh: bad math expression: operator expected at `15'
> } % echo $bar
> } 16
> 
> This is clearly a bug.  Failing the math eval should either abort the
> entire operation, or not print the warning.  I think the latter would
> be considered the intended behavior, that is, bar does not contain a
> descriptor so it simply gets assigned a new one by the redirection.

I suppose so, it's consistent with

% setopt noclobber
% foo=fictional
% exec {foo}>&1
% print $foo
11

But I think Michael's right that to get that effect we don't want the
matheval at all --- we just want to see if foo contains an integer (it
looks like we also check if it's a previously opened fd after retrieving it).
We're only interested in whether foo has previously been set to an
actual descriptor, not to something that might in future evaluate to a
descriptor, which wouldn't make sense.  So if "foo=10+1" it's also not a
descriptor (can't be the result of a previous fd-open-and-assign-to-variable)  and so can be clobbered.

-- 
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Somewhat unexpected results of {myfd}>&1 when noclobber set
  2013-03-10 18:52   ` Peter Stephenson
@ 2013-03-10 20:17     ` Peter Stephenson
  0 siblings, 0 replies; 6+ messages in thread
From: Peter Stephenson @ 2013-03-10 20:17 UTC (permalink / raw)
  To: zsh workers

On Sun, 10 Mar 2013 18:52:04 +0000
Peter Stephenson <p.w.stephenson@ntlworld.com> wrote:
> On Sat, 09 Mar 2013 07:12:52 -0800
> Bart Schaefer <schaefer@brasslantern.com> wrote:
> > On Mar 9, 11:33am, Mikael Magnusson wrote:
> > }
> > } % bar=( 14 15 )
> > } % : {bar}>&1
> > } zsh: bad math expression: operator expected at `15'
> > } % echo $bar
> > } 16
> > 
> > This is clearly a bug.  Failing the math eval should either abort the
> > entire operation, or not print the warning.  I think the latter would
> > be considered the intended behavior, that is, bar does not contain a
> > descriptor so it simply gets assigned a new one by the redirection.
> 
> I suppose so
>...
> But I think Michael's right that to get that effect we don't want the
> matheval at all --- we just want to see if foo contains an integer (it
> looks like we also check if it's a previously opened fd after retrieving it).

Here's my go.

Index: Src/exec.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/exec.c,v
retrieving revision 1.215
diff -p -u -r1.215 exec.c
--- Src/exec.c	13 Dec 2012 10:37:00 -0000	1.215
+++ Src/exec.c	10 Mar 2013 20:16:44 -0000
@@ -1885,7 +1885,14 @@ checkclobberparam(struct redir *f)
 	return 0;
     }
 
-    if (!isset(CLOBBER) && (fd = (int)getintvalue(v)) &&
+    /*
+     * We can't clobber the value in the parameter if it's
+     * already an opened file descriptor --- that means it's a decimal
+     * integer corresponding to an opened file descriptor,
+     * not merely an expression that evaluates to a file descriptor.
+     */
+    if (!isset(CLOBBER) && (s = getstrvalue(v)) &&
+	(fd = (int)zstrtol(s, &s, 10)) >= 0 && !*s &&
 	fd <= max_zsh_fd && fdtable[fd] == FDT_EXTERNAL) {
 	zwarn("can't clobber parameter %s containing file descriptor %d",
 	     f->varid, fd);
Index: Test/A04redirect.ztst
===================================================================
RCS file: /cvsroot/zsh/zsh/Test/A04redirect.ztst,v
retrieving revision 1.25
diff -p -u -r1.25 A04redirect.ztst
--- Test/A04redirect.ztst	15 Nov 2012 21:08:16 -0000	1.25
+++ Test/A04redirect.ztst	10 Mar 2013 20:16:44 -0000
@@ -328,6 +328,17 @@
 1q:NO_CLOBBER prevents overwriting parameter with allocated fd
 ?(eval):4: can't clobber parameter myfd containing file descriptor $myfd
 
+  (setopt noclobber
+   exec {myfd}>logfile2b
+   print First open >&$myfd
+   rm -f logfile2b # prevent normal file no_clobberation
+   myotherfd="${myfd}+0"
+   exec {myotherfd}>logfile2b
+   print Overwritten >&$myotherfd)
+   cat logfile2b
+0:NO_CLOBBER doesn't complain about any other expression
+>Overwritten
+
   (exec {myfd}>logfile4
   echo $myfd
   exec {myfd}>&-

-- 
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2013-03-10 20:45 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-03-09 10:33 Somewhat unexpected results of {myfd}>&1 when noclobber set Mikael Magnusson
2013-03-09 15:12 ` Bart Schaefer
2013-03-10 12:11   ` Mikael Magnusson
2013-03-10 18:26     ` Bart Schaefer
2013-03-10 18:52   ` Peter Stephenson
2013-03-10 20:17     ` Peter Stephenson

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).