Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

233 lines
5.3 KiB

  1. package Env;
  2. =head1 NAME
  3. Env - perl module that imports environment variables as scalars or arrays
  4. =head1 SYNOPSIS
  5. use Env;
  6. use Env qw(PATH HOME TERM);
  7. use Env qw($SHELL @LD_LIBRARY_PATH);
  8. =head1 DESCRIPTION
  9. Perl maintains environment variables in a special hash named C<%ENV>. For
  10. when this access method is inconvenient, the Perl module C<Env> allows
  11. environment variables to be treated as scalar or array variables.
  12. The C<Env::import()> function ties environment variables with suitable
  13. names to global Perl variables with the same names. By default it
  14. ties all existing environment variables (C<keys %ENV>) to scalars. If
  15. the C<import> function receives arguments, it takes them to be a list of
  16. variables to tie; it's okay if they don't yet exist. The scalar type
  17. prefix '$' is inferred for any element of this list not prefixed by '$'
  18. or '@'. Arrays are implemented in terms of C<split> and C<join>, using
  19. C<$Config::Config{path_sep}> as the delimiter.
  20. After an environment variable is tied, merely use it like a normal variable.
  21. You may access its value
  22. @path = split(/:/, $PATH);
  23. print join("\n", @LD_LIBRARY_PATH), "\n";
  24. or modify it
  25. $PATH .= ":.";
  26. push @LD_LIBRARY_PATH, $dir;
  27. however you'd like. Bear in mind, however, that each access to a tied array
  28. variable requires splitting the environment variable's string anew.
  29. The code:
  30. use Env qw(@PATH);
  31. push @PATH, '.';
  32. is equivalent to:
  33. use Env qw(PATH);
  34. $PATH .= ":.";
  35. except that if C<$ENV{PATH}> started out empty, the second approach leaves
  36. it with the (odd) value "C<:.>", but the first approach leaves it with "C<.>".
  37. To remove a tied environment variable from
  38. the environment, assign it the undefined value
  39. undef $PATH;
  40. undef @LD_LIBRARY_PATH;
  41. =head1 LIMITATIONS
  42. On VMS systems, arrays tied to environment variables are read-only. Attempting
  43. to change anything will cause a warning.
  44. =head1 AUTHOR
  45. Chip Salzenberg E<lt>F<[email protected]>E<gt>
  46. and
  47. Gregor N. Purdy E<lt>F<[email protected]>E<gt>
  48. =cut
  49. sub import {
  50. my ($callpack) = caller(0);
  51. my $pack = shift;
  52. my @vars = grep /^[\$\@]?[A-Za-z_]\w*$/, (@_ ? @_ : keys(%ENV));
  53. return unless @vars;
  54. @vars = map { m/^[\$\@]/ ? $_ : '$'.$_ } @vars;
  55. eval "package $callpack; use vars qw(" . join(' ', @vars) . ")";
  56. die $@ if $@;
  57. foreach (@vars) {
  58. my ($type, $name) = m/^([\$\@])(.*)$/;
  59. if ($type eq '$') {
  60. tie ${"${callpack}::$name"}, Env, $name;
  61. } else {
  62. if ($^O eq 'VMS') {
  63. tie @{"${callpack}::$name"}, Env::Array::VMS, $name;
  64. } else {
  65. tie @{"${callpack}::$name"}, Env::Array, $name;
  66. }
  67. }
  68. }
  69. }
  70. sub TIESCALAR {
  71. bless \($_[1]);
  72. }
  73. sub FETCH {
  74. my ($self) = @_;
  75. $ENV{$$self};
  76. }
  77. sub STORE {
  78. my ($self, $value) = @_;
  79. if (defined($value)) {
  80. $ENV{$$self} = $value;
  81. } else {
  82. delete $ENV{$$self};
  83. }
  84. }
  85. ######################################################################
  86. package Env::Array;
  87. use Config;
  88. use Tie::Array;
  89. @ISA = qw(Tie::Array);
  90. my $sep = $Config::Config{path_sep};
  91. sub TIEARRAY {
  92. bless \($_[1]);
  93. }
  94. sub FETCHSIZE {
  95. my ($self) = @_;
  96. my @temp = split($sep, $ENV{$$self});
  97. return scalar(@temp);
  98. }
  99. sub STORESIZE {
  100. my ($self, $size) = @_;
  101. my @temp = split($sep, $ENV{$$self});
  102. $#temp = $size - 1;
  103. $ENV{$$self} = join($sep, @temp);
  104. }
  105. sub CLEAR {
  106. my ($self) = @_;
  107. $ENV{$$self} = '';
  108. }
  109. sub FETCH {
  110. my ($self, $index) = @_;
  111. return (split($sep, $ENV{$$self}))[$index];
  112. }
  113. sub STORE {
  114. my ($self, $index, $value) = @_;
  115. my @temp = split($sep, $ENV{$$self});
  116. $temp[$index] = $value;
  117. $ENV{$$self} = join($sep, @temp);
  118. return $value;
  119. }
  120. sub PUSH {
  121. my $self = shift;
  122. my @temp = split($sep, $ENV{$$self});
  123. push @temp, @_;
  124. $ENV{$$self} = join($sep, @temp);
  125. return scalar(@temp);
  126. }
  127. sub POP {
  128. my ($self) = @_;
  129. my @temp = split($sep, $ENV{$$self});
  130. my $result = pop @temp;
  131. $ENV{$$self} = join($sep, @temp);
  132. return $result;
  133. }
  134. sub UNSHIFT {
  135. my $self = shift;
  136. my @temp = split($sep, $ENV{$$self});
  137. my $result = unshift @temp, @_;
  138. $ENV{$$self} = join($sep, @temp);
  139. return $result;
  140. }
  141. sub SHIFT {
  142. my ($self) = @_;
  143. my @temp = split($sep, $ENV{$$self});
  144. my $result = shift @temp;
  145. $ENV{$$self} = join($sep, @temp);
  146. return $result;
  147. }
  148. sub SPLICE {
  149. my $self = shift;
  150. my $offset = shift;
  151. my $length = shift;
  152. my @temp = split($sep, $ENV{$$self});
  153. if (wantarray) {
  154. my @result = splice @temp, $self, $offset, $length, @_;
  155. $ENV{$$self} = join($sep, @temp);
  156. return @result;
  157. } else {
  158. my $result = scalar splice @temp, $offset, $length, @_;
  159. $ENV{$$self} = join($sep, @temp);
  160. return $result;
  161. }
  162. }
  163. ######################################################################
  164. package Env::Array::VMS;
  165. use Tie::Array;
  166. @ISA = qw(Tie::Array);
  167. sub TIEARRAY {
  168. bless \($_[1]);
  169. }
  170. sub FETCHSIZE {
  171. my ($self) = @_;
  172. my $i = 0;
  173. while ($i < 127 and defined $ENV{$$self . ';' . $i}) { $i++; };
  174. return $i;
  175. }
  176. sub FETCH {
  177. my ($self, $index) = @_;
  178. return $ENV{$$self . ';' . $index};
  179. }
  180. 1;