@@ -320,7 +320,7 @@ func (a *agent) runStartupScript(ctx context.Context, script string) error {
320
320
return nil
321
321
}
322
322
323
- writer , err := os .OpenFile (filepath .Join (os .TempDir (), "coder-startup-script.log" ), os .O_CREATE | os .O_RDWR , 0600 )
323
+ writer , err := os .OpenFile (filepath .Join (os .TempDir (), "coder-startup-script.log" ), os .O_CREATE | os .O_RDWR , 0o600 )
324
324
if err != nil {
325
325
return xerrors .Errorf ("open startup script log file: %w" , err )
326
326
}
@@ -415,6 +415,8 @@ func (a *agent) init(ctx context.Context) {
415
415
},
416
416
SubsystemHandlers : map [string ]ssh.SubsystemHandler {
417
417
"sftp" : func (session ssh.Session ) {
418
+ session .DisablePTYEmulation ()
419
+
418
420
server , err := sftp .NewServer (session )
419
421
if err != nil {
420
422
a .logger .Debug (session .Context (), "initialize sftp server" , slog .Error (err ))
@@ -539,7 +541,8 @@ func (a *agent) createCommand(ctx context.Context, rawCommand string, env []stri
539
541
}
540
542
541
543
func (a * agent ) handleSSHSession (session ssh.Session ) (retErr error ) {
542
- cmd , err := a .createCommand (session .Context (), session .RawCommand (), session .Environ ())
544
+ ctx := session .Context ()
545
+ cmd , err := a .createCommand (ctx , session .RawCommand (), session .Environ ())
543
546
if err != nil {
544
547
return err
545
548
}
@@ -556,32 +559,34 @@ func (a *agent) handleSSHSession(session ssh.Session) (retErr error) {
556
559
557
560
sshPty , windowSize , isPty := session .Pty ()
558
561
if isPty {
562
+ // Disable minimal PTY emulation set by gliderlabs/ssh (NL-to-CRNL).
563
+ // See https://github.com/coder/coder/issues/3371.
564
+ session .DisablePTYEmulation ()
565
+
559
566
cmd .Env = append (cmd .Env , fmt .Sprintf ("TERM=%s" , sshPty .Term ))
560
567
561
568
// The pty package sets `SSH_TTY` on supported platforms.
562
- ptty , process , err := pty .Start (cmd )
569
+ ptty , process , err := pty .Start (cmd , pty .WithPTYOption (
570
+ pty .WithSSHRequest (sshPty ),
571
+ pty .WithLogger (slog .Stdlib (ctx , a .logger , slog .LevelInfo )),
572
+ ))
563
573
if err != nil {
564
574
return xerrors .Errorf ("start command: %w" , err )
565
575
}
566
576
defer func () {
567
577
closeErr := ptty .Close ()
568
578
if closeErr != nil {
569
- a .logger .Warn (context .Background (), "failed to close tty" ,
570
- slog .Error (closeErr ))
579
+ a .logger .Warn (ctx , "failed to close tty" , slog .Error (closeErr ))
571
580
if retErr == nil {
572
581
retErr = closeErr
573
582
}
574
583
}
575
584
}()
576
- err = ptty .Resize (uint16 (sshPty .Window .Height ), uint16 (sshPty .Window .Width ))
577
- if err != nil {
578
- return xerrors .Errorf ("resize ptty: %w" , err )
579
- }
580
585
go func () {
581
586
for win := range windowSize {
582
587
resizeErr := ptty .Resize (uint16 (win .Height ), uint16 (win .Width ))
583
588
if resizeErr != nil {
584
- a .logger .Warn (context . Background () , "failed to resize tty" , slog .Error (resizeErr ))
589
+ a .logger .Warn (ctx , "failed to resize tty" , slog .Error (resizeErr ))
585
590
}
586
591
}
587
592
}()
@@ -596,8 +601,7 @@ func (a *agent) handleSSHSession(session ssh.Session) (retErr error) {
596
601
// ExitErrors just mean the command we run returned a non-zero exit code, which is normal
597
602
// and not something to be concerned about. But, if it's something else, we should log it.
598
603
if err != nil && ! xerrors .As (err , & exitErr ) {
599
- a .logger .Warn (context .Background (), "wait error" ,
600
- slog .Error (err ))
604
+ a .logger .Warn (ctx , "wait error" , slog .Error (err ))
601
605
}
602
606
return err
603
607
}
0 commit comments