diff --git a/lib/CustomCommands.pm b/lib/CustomCommands.pm index 63120f8..d6b9b54 100644 --- a/lib/CustomCommands.pm +++ b/lib/CustomCommands.pm @@ -52,11 +52,15 @@ sub handle { # Check PATH directly foreach my $path (split(/:/, $ENV{PATH})) { my $full_path = "$path/$cmd_name"; - if (-x $full_path) { - #print STDERR "DEBUG: Found in PATH: $full_path\n"; - system($command); - return 2; # System command executed - } + if (-x $full_path) { + my $pid = fork(); + die "Fork failed: $!" unless defined $pid; + if ($pid == 0) { # Child + exec($full_path, split(/\s+/, $command)) or die "Exec failed: $!"; + } + waitpid($pid, 0); # Wait for child + return 2; +} } #print STDERR "DEBUG: Command not found: $command\n"; return -1; # Command not found diff --git a/pshell.pl b/pshell.pl index 0b84f17..f4ed4dd 100755 --- a/pshell.pl +++ b/pshell.pl @@ -7,7 +7,65 @@ use Term::ReadLine; use Cwd; use File::HomeDir; use CustomCommands; -$ENV{TERM} = 'xterm-256color' unless exists $ENV{TERM}; +use POSIX qw(getlogin getuid setsid tcsetpgrp); + +# there is only one + +setsid(); # Start a new session +tcsetpgrp(0, getpgrp()); # Set TTY foreground process group + +# some env vars + +$ENV{HOME} ||= File::HomeDir->my_home; +$ENV{USER} ||= getlogin() || (getpwuid(getuid()))[0] || 'user'; +$ENV{LOGNAME} ||= $ENV{USER}; +$ENV{SHELL} ||= $0; # Path to pshell.pl or compiled binary +$ENV{PATH} ||= '/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin'; +$ENV{TERM} ||= 'xterm-256color'; + +# we a login shell? + +my $is_login_shell = ($0 =~ /^-/ || $ARGV[0] eq '-l'); +if ($is_login_shell) { + # Clear inherited environment for security, except essentials + %ENV = ( + HOME => $ENV{HOME}, + USER => $ENV{USER}, + LOGNAME => $ENV{LOGNAME}, + SHELL => $ENV{SHELL}, + TERM => $ENV{TERM}, + ); + # Reload system and user configs +} + +# system wide env vars + +# Parse /etc/environment silently +if (-r '/etc/environment') { + open my $fh, '<', '/etc/environment' or do { + warn "Could not open /etc/environment: $!" if $is_login_shell; + next; + }; + while (my $line = <$fh>) { + chomp $line; + next unless $line =~ /^(\w+)=(.*)$/; + $ENV{$1} = $2 unless exists $ENV{$1}; + } + close $fh; +} + +# Source /etc/profile silently +if (-r '/etc/profile') { + # Run /etc/profile in a subshell, capture env output, and suppress other prints + my $env_output = qx(/bin/sh -c '. /etc/profile >/dev/null 2>&1 && env'); + if ($? == 0) { + while ($env_output =~ /^(\w+)=(.*)$/mg) { + $ENV{$1} = $2 unless exists $ENV{$1}; + } + } else { + warn "Could not source /etc/profile: $!" if $is_login_shell; + } +} # Initialize command history and environment @@ -69,7 +127,12 @@ if (-e $rc_file && -r $rc_file) { while (my $line = <$fh>) { chomp $line; next unless length $line; - system($line); + if ($line =~ /^(\w+)=(.*)$/) { + $ENV{$1} = $2; + $env->set($1, $2); + } else { + system($line); + } } close $fh; }