use Win32
::TieRegistry
0.20;
Psh
::Util
::print_error_i18n
('no_libwin32');
my $console= new Win32
::Console
();
# For documentation see Psh::OS::Unix
$Psh::OS
::PATH_SEPARATOR
=';';
$Psh::OS
::FILE_SEPARATOR
='\\';
$Psh::history_file
= "psh_history";
sub reinstall_resize_handler
{
# actually we have no 'handlers' here but instead simply do it
my ($cols,$rows)=$console->Size();
my $name_from_reg = $Registry->{"HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\ComputerName\\ComputerName\\ComputerName"};
return $name_from_reg if $name_from_reg;
my $hosts_file = "$ENV{windir}\\HOSTS";
if (open(F_KNOWNHOST
,"< $hosts_file")) {
my $hosts_text = join('', <F_KNOWNHOST
>);
return Psh
::Util
::parse_hosts_file
($hosts_text);
my $tmp= Psh
::OS
::tmpnam
();
Pod
::Text
::pod2text
($tmp,*STDOUT
);
sub execute_complex_command
{
my $fgflag= shift @array;
Psh
::Util
::print_error
("No piping yet.\n");
for( my $i=0; $i<@array; $i++) {
my ($strategy, $how, $options, $words, $text, $opt)= @
{$array[$i]};
local $Psh::current_options
=$opt;
my $line= join(' ',@
$words);
my ($eval_thingie,$bgflag);
($success,$eval_thingie,$words,$bgflag,@return_val)= $strategy->execute( \
$line, $words, $how, 0);
if( defined($eval_thingie)) {
($obj,$success,@tmp)= _fork_process
($eval_thingie,$fgflag,$text,undef,$words);
!defined($return_val[0])) {
my $pid=$obj->GetProcessID();
my $job=Psh
::Joblist
::create_job
($pid,$string,$obj);
_wait_for_system
($obj, 1);
my $visindex= Psh
::Joblist
::get_job_number
($pid);
Psh
::Util
::print_out
("[$visindex] Background $pid $string\n");
return ($success,@return_val);
local( $Psh::code
, $Psh::fgflag
, $Psh::string
, $Psh::options
,
# TODO: perhaps we should use Win32::Process?
# hmm - won't help alot :-( - warp
# print_error_i18n('no_jobcontrol') unless $Psh::fgflag;
if( ref($Psh::code
) eq 'CODE') {
return (0,&{$Psh::code
});
Win32
::Process
::Create
($obj,
# We are passing around objects instead of pid because
# Win32::Process currently only allows me to create objects,
# not look them up via pid
return (0,system($Psh::code
));
_handle_wait_status
($obj,$quiet)
sub _handle_wait_status
{
my $pid= $obj->GetProcessID();
my $job= Psh
::Joblist
::get_job
($obj->GetProcessID());
my $command = $job->{call
};
my $visindex= Psh
::Joblist
::get_job_number
($pid);
my $tmp= Psh
::Locale
::get_text
('done');
Psh
::Util
::print_out
("[$visindex] \u$tmp $pid $command\n") unless $quiet;
Psh
::Joblist
::delete_job
($pid);
Win32
::NetAdmin
::GetUsers
("",FILTER_NORMAL_ACCOUNT
,\
@user_cache);
sub has_job_control
{ return 1; }
$job->{assoc_obj
}->Resume();
# void restart_job(bool FOREGROUND, int JOB_INDEX)
my ($fg_flag, $job_to_start) = @_;
my $job= Psh
::Joblist
::find_job
($job_to_start);
my $command = $job->{call
};
my $tmp=Psh
::Locale
::get_text
('restart');
my $qRunning = $job->{running
};
my $tmp= Psh
::Locale
::get_text
('foreground');
# bg request, and it's already running:
my $visindex = Psh
::Joblist
::get_job_number
($pid);
Psh
::Util
::print_out
("[$visindex] $verb $pid $command\n");
eval { _wait_for_system
($job->{assoc_obj
}, 0); };
$home=$ENV{HOME
}||$ENV{USERPROFILE
}||$ENV{HOMEDRIVE
}.$ENV{HOMEPATH
};
# There is a UserGetAttributes function in Win32::NetAdmin but
# it will only work if you're admin
# I'v searched my registry but did not find something usable
} # we really should return something (profile?)
push @rc, "\\etc\\pshrc" if -r
"\\etc\\pshrc";
push @rc, "$ENV{WINDIR}\\pshrc" if -r
"$ENV{WINDIR}\\pshrc";
my $home= Psh
::OS
::get_home_dir
();
if ($home) { push @rc, catfile
($home,'pshrc') };
sub remove_readline_handler
{1}
return substr($path,0,1) eq "\\" ||
my $extsep = $Psh::OS
::PATH_SEPARATOR
|| ';';
my $pathext = $ENV{PATHEXT
} || $Registry->{"HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\Environment\\PATHEXT"} || ".cmd;.bat;.exe;.com"; # Environment has precedence over LOCAL_MACHINE registry
return split("$extsep",$pathext);
# Simply doing backtick eval - mainly for Prompt evaluation
if (defined &Win32
::GetFullPathName
) {
my $tmp= Win32
::GetFullPathName
($dir);
$tmp=~tr
:\\:/:; # otherwise prompt code etc messes up
if (defined &Win32
::GetCwd
) {
return $tmp||Psh
::OS
::fb_getcwd
();
return $suggestion||$ENV{VISUAL
}||$ENV{EDITOR
}||'edit';
$path =~ s/^([a-z]:)/\u$1/s;
$path =~ s
|([^\\])\\+|$1\\|g
; # xx////xx -> xx/xx
$path =~ s
|(\\\
.)+\\|\\|g
; # xx/././xx -> xx/xx
$path =~ s
|^(\
.\\)+||s
unless $path eq ".\\"; # ./xx -> xx
unless $path =~ m
#^([A-Z]:)?\\\Z(?!\n)#s; # xx/ -> xx return $path;
$dir .= "\\" unless substr($dir,-1) eq "\\";
# append a slash to each argument unless it has one there
$_ .= "/" if $_ eq '' || substr($_,-1) ne "/";
return canonpath
(join('', @args));
sub file_name_is_absolute
{
return scalar($file =~ m{^([a-z]:)?[\\/]}is);
if ( $directories !~ m
|[\\/]\Z
(?
!\n)| ) {
return split( m
|[\\/]|, $directories );
my( @directories )= split( m
|[\\/]|, "${directories}dummy" ) ;
$directories[ $#directories ]= '' ;
my ($path, $nofile) = @_;
my ($volume,$directory,$file) = ('','','');
m
{^( (?
:[a
-zA
-Z
]:|(?
:\\\\|//)[^\\/]+[\\/][^\\/]+)?
)
(?
:\\\\|//)[^\\/]+[\\/][^\\/]+
( (?
:.*[\\\\/](?
:\
.\
.?\Z
(?
!\n))?
)?
)
return ($volume,$directory,$file);
if ( ! file_name_is_absolute
( $path ) ) {
if ( !defined( $base ) || $base eq '' ) {
$base = Psh
::OS
::getcwd_psh
() ;
elsif ( ! file_name_is_absolute
( $base ) ) {
$base = rel2abs
( $base ) ;
$base = canonpath
( $base ) ;
my ( $path_directories, $path_file ) =
(splitpath
( $path, 1 ))[1,2] ;
my ( $base_volume, $base_directories ) =
catdir
( $base_directories, $path_directories ),
return canonpath
( $path ) ;
Psh::OS::Win - Contains Windows specific code
An implementation of Psh::OS for Win32 systems. This module
Markus Peter, warp@spin.de
Omer Shenker, oshenker@iname.com
# The following is for Emacs - I hope it won't annoy anyone
# but this could solve the problems with different tab widths etc