Re: Bug in bash(1)

2013-08-23 Thread Chet Ramey
On 8/21/13 1:21 PM, Thomas Hood wrote:
> There appears to be a redundancy in the description of the "disown"
> builtin in bash(1). Version is 4.2.

Thanks for the report and patch.

Chet

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Bogus SIGPIPE bug

2013-08-23 Thread Thomas Hood
I have isolated a bug in bash 3.2 which doesn't appear in later
versions of bash I have tried; now I am trying to figure out when
where the bug got fixed so I can make an upgrade plan. I am using SLES
11 SP2.

To reproduce the issue do the following.
* Block SIGPIPE in the current process.
* From the current process, start bash interactively. (The new bash
process also has SIGPIPE blocked.)
* In the latter bash process, run a test program. (The new
test-program process also has SIGPIPE blocked.)

The latter process sees a pending SIGPIPE supposedly sent by itself.
If it unblocks SIGPIPE then it receives this signal immediately.

If the test program is started in various unusual ways such as the
following then it does NOT receive SIGPIPE:

bash -c '{ test ; }'
bash -c ': ; test'
bash -c 'test ; :'
( { test ; } )
( test ; : )
echo test | bash -s

whereas it DOES receive SIGPIPE if it as started as follows.

bash -c test
test
( test )
( test ; )
{ test ; }

I have searched in the mailing list archives and looked in the bash
docs but haven't found a clue as to where this bug was fixed. Does
this ring a bell with anyone or is this most likely a distro-specific
bug?

Info:

$ bash --version
GNU bash, version 3.2.51(1)-release (x86_64-suse-linux-gnu)
> rpm -q -a|grep bash
bash-3.2-147.9.13
$ cat /etc/issue
Welcome to SUSE Linux Enterprise Server 11 SP2  (x86_64) - Kernel \r (\l).

I attach the test program I use.
-- 
Thomas Hood
RAAF Technology bv
#include 
#include 
#include 
#include 

static void sigactor(int signum, siginfo_t *si, void *ctx) {
	 printf("Caught signal %d sent by process %d\n", signum, si->si_pid);
}

int main()
{
	sigset_t sigmask;
	struct sigaction act;

	act.sa_sigaction = sigactor;
	act.sa_flags = SA_RESTART | SA_SIGINFO;

	printf("Running with PID %d\n", getpid());

	printf("Will retrieve existing signal mask\n");
	if (sigprocmask(SIG_SETMASK, NULL, &sigmask)) {
		printf("Failed to retrieve existing signal mask\n");
		return 1;
	}
	if (sigismember (&sigmask, SIGPIPE)) {
		printf("SIGPIPE is blocked\n");
	} else {
		printf("SIGPIPE is not blocked\n");
	}

	printf("Will check for signals pending\n");
	if (sigpending(&sigmask)) {
		printf("Failed to check for signals pending\n");
		return 1;
	}
	if (sigismember (&sigmask, SIGPIPE)) {
		printf("SIGPIPE is pending\n");
	} else {
		printf("SIGPIPE is not pending\n");
	}

	printf("Will install signal handler\n");
	if (sigaction(SIGPIPE, &act, NULL) || sigaction(SIGHUP, &act, NULL) || sigaction(SIGTERM, &act, NULL)) {
		printf("Failed to install signal handler\n");
		return 1;
	}

	//printf("Will sleep\n");
	//sleep(30);

	sigemptyset(&sigmask);
	sigaddset(&sigmask, SIGPIPE);

	printf("Will unblock signal\n");
	if (sigprocmask(SIG_UNBLOCK, &sigmask, NULL)) {
		printf("Error unblocking signal\n");
		return 1;
	}

	printf("Will exit\n");
	return 0;
}


RFE: readarray "-0" (or reciprocal of printf "%s\x00" "${AR[@]}" )

2013-08-23 Thread Linda Walsh

I was doing some file tree tests,
and just noticed, I can print out file
names with nulls at the end of them from
an array with printf (neat!)

However, has any thought (or is there a way already?)
to read in a bunch of null terminated names from
the output of such a construct?








Re: RFE: readarray "-0" (or reciprocal of printf "%s\x00" "${AR[@]}" )

2013-08-23 Thread Eduardo A . Bustamante López
> However, has any thought (or is there a way already?)
> to read in a bunch of null terminated names from
> the output of such a construct?

Well, there's not a construct to build an array like you mention, but
you can use read and a while loop like this:

while IFS= read -rd '' elem; do
  echo "<$elem>";
done < <(printf '%s\0' a b '1 2 3' $'x y \n z')

Which outputs:



<1 2 3>


Now, in more detail:

#  .- This is used to disable leading/trailing whitespace
#  |   trimming.
#  v
while IFS= read -rd '' elem; do
#^.. When you pass an empty string as a
#"delimiter" for read, it (read) will read
#until it finds a NUL character.
  echo "<$elem>";
done < <(printf '%s\0' a b '1 2 3' $'x y \n z')
#   ^.. we use process substitution ( <(...) ) instead of a
#   normal anonymous pipe in case we want to create some
#   persistent variables.

Just be careful, as written above, it requires each record to end
with a NUL byte. If there's no guarantee of a trailing NUL for each
record, you will have to test if read managed to read one last
element with no trailing NUL, it looks something like this:

while ... read -r ... something; do
  ...
done

[[ $something ]] && ...



-- 
Eduardo Bustamante