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.

201 lines
4.1 KiB

  1. package Shell;
  2. use 5.005_64;
  3. use strict;
  4. use warnings;
  5. our($capture_stderr, $VERSION, $AUTOLOAD);
  6. $VERSION = '0.3';
  7. sub new { bless \$VERSION, shift } # Nothing better to bless
  8. sub DESTROY { }
  9. sub import {
  10. my $self = shift;
  11. my ($callpack, $callfile, $callline) = caller;
  12. my @EXPORT;
  13. if (@_) {
  14. @EXPORT = @_;
  15. } else {
  16. @EXPORT = 'AUTOLOAD';
  17. }
  18. foreach my $sym (@EXPORT) {
  19. no strict 'refs';
  20. *{"${callpack}::$sym"} = \&{"Shell::$sym"};
  21. }
  22. }
  23. sub AUTOLOAD {
  24. shift if ref $_[0] && $_[0]->isa( 'Shell' );
  25. my $cmd = $AUTOLOAD;
  26. $cmd =~ s/^.*:://;
  27. eval <<"*END*";
  28. sub $AUTOLOAD {
  29. if (\@_ < 1) {
  30. \$Shell::capture_stderr ? `$cmd 2>&1` : `$cmd`;
  31. } elsif ('$^O' eq 'os2') {
  32. local(\*SAVEOUT, \*READ, \*WRITE);
  33. open SAVEOUT, '>&STDOUT' or die;
  34. pipe READ, WRITE or die;
  35. open STDOUT, '>&WRITE' or die;
  36. close WRITE;
  37. my \$pid = system(1, '$cmd', \@_);
  38. die "Can't execute $cmd: \$!\\n" if \$pid < 0;
  39. open STDOUT, '>&SAVEOUT' or die;
  40. close SAVEOUT;
  41. if (wantarray) {
  42. my \@ret = <READ>;
  43. close READ;
  44. waitpid \$pid, 0;
  45. \@ret;
  46. } else {
  47. local(\$/) = undef;
  48. my \$ret = <READ>;
  49. close READ;
  50. waitpid \$pid, 0;
  51. \$ret;
  52. }
  53. } else {
  54. my \$a;
  55. my \@arr = \@_;
  56. if ('$^O' eq 'MSWin32') {
  57. # XXX this special-casing should not be needed
  58. # if we do quoting right on Windows. :-(
  59. #
  60. # First, escape all quotes. Cover the case where we
  61. # want to pass along a quote preceded by a backslash
  62. # (i.e., C<"param \\""" end">).
  63. # Ugly, yup? You know, windoze.
  64. # Enclose in quotes only the parameters that need it:
  65. # try this: c:\> dir "/w"
  66. # and this: c:\> dir /w
  67. for (\@arr) {
  68. s/"/\\\\"/g;
  69. s/\\\\\\\\"/\\\\\\\\"""/g;
  70. \$_ = qq["\$_"] if /\\s/;
  71. }
  72. } else {
  73. for (\@arr) {
  74. s/(['\\\\])/\\\\\$1/g;
  75. \$_ = \$_;
  76. }
  77. }
  78. push \@arr, '2>&1' if \$Shell::capture_stderr;
  79. open(SUBPROC, join(' ', '$cmd', \@arr, '|'))
  80. or die "Can't exec $cmd: \$!\\n";
  81. if (wantarray) {
  82. my \@ret = <SUBPROC>;
  83. close SUBPROC; # XXX Oughta use a destructor.
  84. \@ret;
  85. } else {
  86. local(\$/) = undef;
  87. my \$ret = <SUBPROC>;
  88. close SUBPROC;
  89. \$ret;
  90. }
  91. }
  92. }
  93. *END*
  94. die "$@\n" if $@;
  95. goto &$AUTOLOAD;
  96. }
  97. 1;
  98. __END__
  99. =head1 NAME
  100. Shell - run shell commands transparently within perl
  101. =head1 SYNOPSIS
  102. See below.
  103. =head1 DESCRIPTION
  104. Date: Thu, 22 Sep 94 16:18:16 -0700
  105. Message-Id: <[email protected]>
  106. To: perl5-porters@isu.edu
  107. From: Larry Wall <[email protected]>
  108. Subject: a new module I just wrote
  109. Here's one that'll whack your mind a little out.
  110. #!/usr/bin/perl
  111. use Shell;
  112. $foo = echo("howdy", "<funny>", "world");
  113. print $foo;
  114. $passwd = cat("</etc/passwd");
  115. print $passwd;
  116. sub ps;
  117. print ps -ww;
  118. cp("/etc/passwd", "/tmp/passwd");
  119. That's maybe too gonzo. It actually exports an AUTOLOAD to the current
  120. package (and uncovered a bug in Beta 3, by the way). Maybe the usual
  121. usage should be
  122. use Shell qw(echo cat ps cp);
  123. Larry
  124. If you set $Shell::capture_stderr to 1, the module will attempt to
  125. capture the STDERR of the process as well.
  126. The module now should work on Win32.
  127. Jenda
  128. There seemed to be a problem where all arguments to a shell command were
  129. quoted before being executed. As in the following example:
  130. cat('</etc/passwd');
  131. ls('*.pl');
  132. really turned into:
  133. cat '</etc/passwd'
  134. ls '*.pl'
  135. instead of:
  136. cat </etc/passwd
  137. ls *.pl
  138. and of course, this is wrong.
  139. I have fixed this bug, it was brought up by Wolfgang Laun [ID 20000326.008]
  140. Casey
  141. =head2 OBJECT ORIENTED SYNTAX
  142. Shell now has an OO interface. Good for namespace conservation
  143. and shell representation.
  144. use Shell;
  145. my $sh = Shell->new;
  146. print $sh->ls;
  147. Casey
  148. =head1 AUTHOR
  149. Larry Wall
  150. Changes by Jenda@Krynicky.cz and Dave Cottle <[email protected]>
  151. Changes and bug fixes by Casey Tweten <[email protected]>
  152. =cut