Execute through shell for propper command expansion

This commit is contained in:
Peter Steinberger 2025-06-20 18:32:15 +02:00
parent b2cbb02bfd
commit bf31a85198

View file

@ -27,6 +27,7 @@ type PTY struct {
pty *os.File
oldState *term.State
streamWriter *protocol.StreamWriter
bufferWriter *BufferWriter // Direct buffer integration
stdinPipe *os.File
useEventDrivenStdin bool
resizeMutex sync.Mutex
@ -47,7 +48,17 @@ func NewPTY(session *Session) (*PTY, error) {
debugLog("[DEBUG] NewPTY: Initial cmdline: %v", cmdline)
cmd := exec.Command(cmdline[0], cmdline[1:]...)
// Execute through shell to handle aliases, functions, and proper PATH resolution
var cmd *exec.Cmd
if len(cmdline) == 1 && cmdline[0] == shell {
// If just launching the shell itself, don't use -c
cmd = exec.Command(shell)
} else {
// Execute command through shell for proper environment handling
shellCmd := strings.Join(cmdline, " ")
cmd = exec.Command(shell, "-c", shellCmd)
debugLog("[DEBUG] NewPTY: Executing through shell: %s -c %q", shell, shellCmd)
}
// Set working directory, ensuring it's valid
if session.info.Cwd != "" {
@ -193,6 +204,11 @@ func (p *PTY) Pid() int {
return 0
}
// SetBufferWriter sets a direct buffer writer for real-time terminal emulation
func (p *PTY) SetBufferWriter(bw *BufferWriter) {
p.bufferWriter = bw
}
func (p *PTY) Run() error {
defer func() {
if err := p.Close(); err != nil {
@ -257,9 +273,15 @@ func (p *PTY) Run() error {
p.session.info.Height = height
p.session.mu.Unlock()
// Write resize event to stream
if err := p.streamWriter.WriteResize(uint32(width), uint32(height)); err != nil {
log.Printf("[ERROR] PTY.Run: Failed to write resize event: %v", err)
// Write resize event
if p.bufferWriter != nil {
if err := p.bufferWriter.WriteResize(uint32(width), uint32(height)); err != nil {
log.Printf("[ERROR] PTY.Run: Failed to write resize to buffer: %v", err)
}
} else {
if err := p.streamWriter.WriteResize(uint32(width), uint32(height)); err != nil {
log.Printf("[ERROR] PTY.Run: Failed to write resize event: %v", err)
}
}
}
}
@ -285,10 +307,20 @@ func (p *PTY) Run() error {
n, err := p.pty.Read(buf)
if n > 0 {
debugLog("[DEBUG] PTY.Run: Read %d bytes of output from PTY", n)
if err := p.streamWriter.WriteOutput(buf[:n]); err != nil {
log.Printf("[ERROR] PTY.Run: Failed to write output: %v", err)
errCh <- fmt.Errorf("failed to write output: %w", err)
return
// Use buffer writer if available for direct integration
if p.bufferWriter != nil {
if _, err := p.bufferWriter.Write(buf[:n]); err != nil {
log.Printf("[ERROR] PTY.Run: Failed to write to buffer: %v", err)
errCh <- fmt.Errorf("failed to write to buffer: %w", err)
return
}
} else {
// Fallback to stream writer
if err := p.streamWriter.WriteOutput(buf[:n]); err != nil {
log.Printf("[ERROR] PTY.Run: Failed to write output: %v", err)
errCh <- fmt.Errorf("failed to write output: %w", err)
return
}
}
// Continue reading immediately if we got data
continue
@ -507,6 +539,17 @@ func (p *PTY) Resize(width, height int) error {
func (p *PTY) Close() error {
var firstErr error
// Close buffer writer if present
if p.bufferWriter != nil {
if err := p.bufferWriter.Close(); err != nil {
log.Printf("[ERROR] PTY.Close: Failed to close buffer writer: %v", err)
if firstErr == nil {
firstErr = err
}
}
}
if p.streamWriter != nil {
if err := p.streamWriter.Close(); err != nil {
log.Printf("[ERROR] PTY.Close: Failed to close stream writer: %v", err)
@ -533,3 +576,4 @@ func (p *PTY) Close() error {
}
return firstErr
}