(inv *serpent.Invocation, client *codersdk.Client, args handleRPTYArgs)
| 83 | } |
| 84 | |
| 85 | func handleRPTY(inv *serpent.Invocation, client *codersdk.Client, args handleRPTYArgs) error { |
| 86 | ctx, cancel := context.WithCancel(inv.Context()) |
| 87 | defer cancel() |
| 88 | |
| 89 | var reconnectID uuid.UUID |
| 90 | if args.ReconnectID != "" { |
| 91 | rid, err := uuid.Parse(args.ReconnectID) |
| 92 | if err != nil { |
| 93 | return xerrors.Errorf("invalid reconnect ID: %w", err) |
| 94 | } |
| 95 | reconnectID = rid |
| 96 | } else { |
| 97 | reconnectID = uuid.New() |
| 98 | } |
| 99 | |
| 100 | ws, agt, _, err := GetWorkspaceAndAgent(ctx, inv, client, true, args.NamedWorkspace) |
| 101 | if err != nil { |
| 102 | return err |
| 103 | } |
| 104 | |
| 105 | var ctID string |
| 106 | if args.Container != "" { |
| 107 | cts, err := client.WorkspaceAgentListContainers(ctx, agt.ID, nil) |
| 108 | if err != nil { |
| 109 | return err |
| 110 | } |
| 111 | for _, ct := range cts.Containers { |
| 112 | if ct.FriendlyName == args.Container || ct.ID == args.Container { |
| 113 | ctID = ct.ID |
| 114 | break |
| 115 | } |
| 116 | } |
| 117 | if ctID == "" { |
| 118 | return xerrors.Errorf("container %q not found", args.Container) |
| 119 | } |
| 120 | } |
| 121 | |
| 122 | // Get the width and height of the terminal. |
| 123 | var termWidth, termHeight uint16 |
| 124 | stdoutFile, validOut := inv.Stdout.(*os.File) |
| 125 | if validOut && isatty.IsTerminal(stdoutFile.Fd()) { |
| 126 | w, h, err := term.GetSize(int(stdoutFile.Fd())) |
| 127 | if err == nil { |
| 128 | //nolint: gosec |
| 129 | termWidth, termHeight = uint16(w), uint16(h) |
| 130 | } |
| 131 | } |
| 132 | |
| 133 | // Set stdin to raw mode so that control characters work. |
| 134 | stdinFile, validIn := inv.Stdin.(*os.File) |
| 135 | if validIn && isatty.IsTerminal(stdinFile.Fd()) { |
| 136 | inState, err := pty.MakeInputRaw(stdinFile.Fd()) |
| 137 | if err != nil { |
| 138 | return xerrors.Errorf("failed to set input terminal to raw mode: %w", err) |
| 139 | } |
| 140 | defer func() { |
| 141 | _ = pty.RestoreTerminal(stdinFile.Fd(), inState) |
| 142 | }() |
no test coverage detected