After initialization, ARGV is supposed to be under the control of the
application (the awk script). However, when fulfilling the assignment
specified by a "name=value" operand, the implementation modifies the
operand's ARGV entry behind the application's back, truncating it.
This commit undoes the munge before returning control to the
application.
History: setclvar had been modifying its string argument without
ill-effect from the beginning (7th Edition UNIX, 1979) [1], when,
in 1989, SVR4 switched the source of the argument from argv to ARGV
[2]. The former cannot be accessed by the application, the latter
can. Thus, a private implementation detail unintentionally became a
public defect.
After initialization, ARGV is supposed to be under the control of the application (the awk script). However, when fulfilling the assignment specified by a "name=value" operand, the implementation modifies the operand's ARGV entry behind the application's back, truncating it.
This commit undoes the munge before returning control to the application.
$ echo | ./master 'BEGIN { print ARGV[1] } { print ARGV[1] }' name=value name=value name
$ echo | ./a.out 'BEGIN { print ARGV[1] } { print ARGV[1] }' name=value name=value name=value
History: setclvar had been modifying its string argument without ill-effect from the beginning (7th Edition UNIX, 1979) [1], when, in 1989, SVR4 switched the source of the argument from argv to ARGV [2]. The former cannot be accessed by the application, the latter can. Thus, a private implementation detail unintentionally became a public defect.
[1] https://www.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/awk/lib.c [2] https://github.com/danfuzz/one-true-awk/blob/master/versions/1989-10-11/lib.c