Re: AIX and Interix also do early PID recycling.

2012-08-20 Thread Michael Haubenwallner


On 07/29/2012 12:46 AM, Chet Ramey wrote:
> On 7/27/12 9:50 AM, Michael Haubenwallner wrote:
> 
>> With attached patch I haven't been able to break the testcase below so far
>> on that AIX 6.1 box here.
>>
>> But still, the other one using the $()-childs still fails.
> 
> Try the attached patch for that.

Collecting the patches and cleaning up now unused code, attached patch
seems to fix both CHILD_MAX related problems on that AIX box here now,
without using the RECYCLES_PIDS workaround.

Thank you!

/haubi/
Bash assumes pids aren't reused before sysconf(_SC_CHILD_MAX) immediate childs
(the dynamic value), as well as ascending and wrapped around pid values.

However, as specified by POSIX, conforming kernels actually guarantee for
CHILD_MAX imediate childs (the static value) before reusing pids. Additionally,
AIX (at least) does not guarantee for ascending pid values at all. Actually,
AIX reuses pids after its CHILD_MAX value of 128 in somewhat random order in
some configuration- or load-cases, resulting in race conditions like these:
http://lists.gnu.org/archive/html/bug-bash/2008-07/msg00117.html

This looks like a similar problem with Cygwin, where RECYCLES_PIDS is defined
as the workaround, but that isn't really correct for AIX (and maybe Interix):
http://www.cygwin.com/ml/cygwin/2004-09/msg00882.html
http://www.cygwin.com/ml/cygwin/2002-08/msg00449.html
*** jobs.c.orig	2012-08-20 16:23:51 +0200
--- jobs.c	2012-08-20 16:51:36 +0200
***
*** 317,324 
  static char retcode_name_buffer[64];
  
- /* flags to detect pid wraparound */
- static pid_t first_pid = NO_PID;
- static int pid_wrap = -1;
- 
  #if !defined (_POSIX_VERSION)
  
--- 317,320 
***
*** 347,352 
  {
js = zerojs;
-   first_pid = NO_PID;
-   pid_wrap = -1;
  }
  
--- 343,346 
***
*** 1823,1833 
  	 as the proper pgrp if this is the first child. */
  
-   if (first_pid == NO_PID)
- 	first_pid = pid;
-   else if (pid_wrap == -1 && pid < first_pid)
- 	pid_wrap = 0;
-   else if (pid_wrap == 0 && pid >= first_pid)
- 	pid_wrap = 1;
- 
if (job_control)
  	{
--- 1817,1820 
***
*** 1863,1875 
  #endif
  
!   if (pid_wrap > 0)
! 	delete_old_job (pid);
  
! #if !defined (RECYCLES_PIDS)
!   /* Only check for saved status if we've saved more than CHILD_MAX
! 	 statuses, unless the system recycles pids. */
!   if ((js.c_reaped + bgpids.npid) >= js.c_childmax)
! #endif
! 	bgp_delete (pid);		/* new process, discard any saved status */
  
last_made_pid = pid;
--- 1850,1856 
  #endif
  
!   delete_old_job (pid);
  
!   bgp_delete (pid);		/* new process, discard any saved status */
  
last_made_pid = pid;
*** execute_cmd.c.orig	2012-08-20 16:36:10 +0200
--- execute_cmd.c	2012-08-20 16:51:14 +0200
***
*** 742,748 
  
  	/* XXX - this is something to watch out for if there are problems
! 	   when the shell is compiled without job control. */
! 	if (already_making_children && pipe_out == NO_PIPE &&
! 	last_made_pid != last_pid)
  	  {
  	stop_pipeline (asynchronous, (COMMAND *)NULL);
--- 742,750 
  
  	/* XXX - this is something to watch out for if there are problems
! 	   when the shell is compiled without job control.  Don't worry about
! 	   whether or not last_made_pid == last_pid; already_making_children
! 	   tells us whether or not there are unwaited-for children to wait
! 	   for and reap. */
! 	if (already_making_children && pipe_out == NO_PIPE)
  	  {
  	stop_pipeline (asynchronous, (COMMAND *)NULL);


Re: bash does filename expansion when assigning to array member in compound form

2012-08-20 Thread Gundi Cress
Am Sat, 18 Aug 2012 19:55:17 +0100 schrieb Stephane Chazelas:

> 2012-08-18 10:26:22 -0500, Dan Douglas:
>> This is a feature that all shells with this style of compound
>> assignment have in common. If no explicit subscripts are given, the
>> text between the parentheses is processed exactly as though it were
>> arguments to a command including brace expansion, word-splitting, and
>> pathname expansion (and consequently, quoting is just as important).
>> This is an important feature because it allows storing the results of a
>> glob in an array easily.
>> 
>> If a subscript is given explicitly, then the right-hand side of the
>> assignment is treated exactly as an ordinary scalar assignment would
>> be, including all analagous behaviors for `+=' and the integer
>> attribute.
>> 
>>  $ set -x; a=( [1]=* )
>> + a=([1]=*)
> [...]
> 
> Nope:
> 
> ~/1$ touch '[1]=x'
> ~/1$ bash -c 'a=( [1]=* ); echo "${a[@]}"' [1]=x ~/1$ bash -c 'a=(
> [1]=asd ); echo "${a[@]}"'
> asd
> 
> That's a bug though.
>

I'm not sure if I got it right.
Please correct me if I got it wrong:

It is not generally a bug that Bash does filename expansion when assigning
to array members in compound form. Only if explicit indices identify 
array members in a compound assignment there should be no filename
expansion and it's a bug if Bash does so.


Gundi

  




Re: bash does filename expansion when assigning to array member in compound form

2012-08-20 Thread Roman Rakus

On 08/20/2012 07:12 PM, Gundi Cress wrote:

Am Sat, 18 Aug 2012 19:55:17 +0100 schrieb Stephane Chazelas:


2012-08-18 10:26:22 -0500, Dan Douglas:

This is a feature that all shells with this style of compound
assignment have in common. If no explicit subscripts are given, the
text between the parentheses is processed exactly as though it were
arguments to a command including brace expansion, word-splitting, and
pathname expansion (and consequently, quoting is just as important).
This is an important feature because it allows storing the results of a
glob in an array easily.

If a subscript is given explicitly, then the right-hand side of the
assignment is treated exactly as an ordinary scalar assignment would
be, including all analagous behaviors for `+=' and the integer
attribute.

  $ set -x; a=( [1]=* )
+ a=([1]=*)

[...]

Nope:

~/1$ touch '[1]=x'
~/1$ bash -c 'a=( [1]=* ); echo "${a[@]}"' [1]=x ~/1$ bash -c 'a=(
[1]=asd ); echo "${a[@]}"'
asd

That's a bug though.


I'm not sure if I got it right.
Please correct me if I got it wrong:

It is not generally a bug that Bash does filename expansion when assigning
to array members in compound form. Only if explicit indices identify
array members in a compound assignment there should be no filename
expansion and it's a bug if Bash does so.


Gundi

   



And how would you achieve to fill array with all file names containing 
`[1]=' for example.
Definitely it's good, if you want to be sure, to always quote all 
characters which means pathname expansion - `*', `?' and `['.


RR



Re: bash does filename expansion when assigning to array member in compound form

2012-08-20 Thread Dan Douglas
On Monday, August 20, 2012 07:44:51 PM Roman Rakus wrote:
> And how would you achieve to fill array with all file names containing 
> `[1]=' for example.

$ ls
[1]=a  [1]=b
$ ( typeset -a a=( \[1\]=* ); typeset -p a )
typeset -a a=('[1]=a' '[1]=b')
$ ( typeset -a a=( [1]=* ); typeset -p a )
typeset -a a=([1]='*')
$

In ksh93, by escaping. I think this is what most people would expect and 
probably what Bash intended.

Of course, In that shell in order to use "[n]="-style indexing each and every 
element needs to be specified that way explicitly. I like that Bash can just 
implicitly start counting at any index.
-- 
Dan Douglas



Re: bash does filename expansion when assigning to array member in compound form

2012-08-20 Thread Stephane Chazelas
2012-08-20 19:44:51 +0200, Roman Rakus:
[...]
> And how would you achieve to fill array with all file names
> containing `[1]=' for example.
[...]

Another interesting question is how to fill the array with all
the file names that start with a digit followed by "=".

$ touch {3..5}=foo
$ ls
3=foo  4=foo  5=foo
$ bash -c 'a=([0-9]=*); typeset -p a'
bash: [0-9]=*: bad array subscript
declare -a a='()'
$ bash -c 'shopt -s extglob; a=(@([0-9])=*); typeset -p a'
bash: -c: line 0: syntax error near unexpected token `('
bash: -c: line 0: `shopt -s extglob; a=(@([0-9])=*); typeset -p a'
$ bash -c 'shopt -s extglob
a=(@([0-9])=*); typeset -p a'
declare -a a='([0]="3=foo" [1]="4=foo" [2]="5=foo")'


> Definitely it's good, if you want to be sure, to always quote all
> characters which means pathname expansion - `*', `?' and `['.
[...]

Yes, the problem here is that "[" is overloaded in a conflicting
manner as a globbing operator and that poorly designed special
type of array assignment.

Quoting them will prevent both, it become more tricky if you
want only  one or the other.

Note that in bash that also means we need to quote variables in
there even if IFS is set to "".

$ bash -c 'a="*"; b=([1]=$a); typeset -p b'
declare -a b='([0]="[1]=bar")'

-- 
Stephane