mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-09-15 21:00:27 +00:00
Fix tailssh pixels
This commit is contained in:
@@ -25,7 +25,7 @@ func OpenNativeShellSession(
|
|||||||
cwd,
|
cwd,
|
||||||
int(uid), int(gid),
|
int(uid), int(gid),
|
||||||
common.Map(iteratorToArray[int32](groups), func(g int32) int { return int(g) }),
|
common.Map(iteratorToArray[int32](groups), func(g int32) int { return int(g) }),
|
||||||
uint16(rows), uint16(cols),
|
uint16(rows), uint16(cols), 0, 0,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -58,7 +58,7 @@ func (s *nativeShellSession) MasterFD() int32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *nativeShellSession) Resize(rows, cols int32) error {
|
func (s *nativeShellSession) Resize(rows, cols int32) error {
|
||||||
return s.shell.Resize(uint16(rows), uint16(cols))
|
return s.shell.Resize(uint16(rows), uint16(cols), 0, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *nativeShellSession) Signal(sig int32) error {
|
func (s *nativeShellSession) Signal(sig int32) error {
|
||||||
|
|||||||
@@ -582,11 +582,13 @@ func (s *Server) handleSession(session gliderssh.Session) {
|
|||||||
session.DisablePTYEmulation()
|
session.DisablePTYEmulation()
|
||||||
command := session.RawCommand()
|
command := session.RawCommand()
|
||||||
var term string
|
var term string
|
||||||
var rows, cols uint16
|
var rows, cols, widthPixels, heightPixels uint16
|
||||||
if isPty {
|
if isPty {
|
||||||
term = ptyReq.Term
|
term = ptyReq.Term
|
||||||
rows = clampWindowDimension(ptyReq.Window.Height)
|
rows = clampWindowDimension(ptyReq.Window.Height)
|
||||||
cols = clampWindowDimension(ptyReq.Window.Width)
|
cols = clampWindowDimension(ptyReq.Window.Width)
|
||||||
|
widthPixels = clampWindowDimension(ptyReq.Window.WidthPixels)
|
||||||
|
heightPixels = clampWindowDimension(ptyReq.Window.HeightPixels)
|
||||||
}
|
}
|
||||||
var rec *recording
|
var rec *recording
|
||||||
recorderList, onFailure := recorders(connInfo)
|
recorderList, onFailure := recorders(connInfo)
|
||||||
@@ -611,12 +613,14 @@ func (s *Server) handleSession(session gliderssh.Session) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
shellSession, err := s.backend.OpenSession(shellRequest{
|
shellSession, err := s.backend.OpenSession(shellRequest{
|
||||||
User: localUser,
|
User: localUser,
|
||||||
Command: command,
|
Command: command,
|
||||||
Env: env,
|
Env: env,
|
||||||
Term: term,
|
Term: term,
|
||||||
Rows: rows,
|
Rows: rows,
|
||||||
Cols: cols,
|
Cols: cols,
|
||||||
|
WidthPixels: widthPixels,
|
||||||
|
HeightPixels: heightPixels,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Error("failed to open shell session: ", err)
|
s.logger.Error("failed to open shell session: ", err)
|
||||||
@@ -661,7 +665,12 @@ func (s *Server) handleSession(session gliderssh.Session) {
|
|||||||
for win := range winCh {
|
for win := range winCh {
|
||||||
shellAccess.Lock()
|
shellAccess.Lock()
|
||||||
if shellAlive {
|
if shellAlive {
|
||||||
shellSession.Resize(clampWindowDimension(win.Height), clampWindowDimension(win.Width))
|
shellSession.Resize(
|
||||||
|
clampWindowDimension(win.Height),
|
||||||
|
clampWindowDimension(win.Width),
|
||||||
|
clampWindowDimension(win.WidthPixels),
|
||||||
|
clampWindowDimension(win.HeightPixels),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
shellAccess.Unlock()
|
shellAccess.Unlock()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,12 +14,14 @@ type shellBackend interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type shellRequest struct {
|
type shellRequest struct {
|
||||||
User *adapter.PlatformUser
|
User *adapter.PlatformUser
|
||||||
Command string
|
Command string
|
||||||
Env []string
|
Env []string
|
||||||
Term string
|
Term string
|
||||||
Rows uint16
|
Rows uint16
|
||||||
Cols uint16
|
Cols uint16
|
||||||
|
WidthPixels uint16
|
||||||
|
HeightPixels uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
type shellSession interface {
|
type shellSession interface {
|
||||||
@@ -27,7 +29,7 @@ type shellSession interface {
|
|||||||
// CloseWrite signals EOF on the child's stdin without tearing down the
|
// CloseWrite signals EOF on the child's stdin without tearing down the
|
||||||
// session, so programs that read stdin to EOF can finish normally.
|
// session, so programs that read stdin to EOF can finish normally.
|
||||||
CloseWrite() error
|
CloseWrite() error
|
||||||
Resize(rows, cols uint16) error
|
Resize(rows, cols, widthPixels, heightPixels uint16) error
|
||||||
Signal(sig int) error
|
Signal(sig int) error
|
||||||
Wait() (exitStatus uint32, err error)
|
Wait() (exitStatus uint32, err error)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,11 +25,15 @@ func (b *platformShellBackend) OpenSession(request shellRequest) (shellSession,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
master := os.NewFile(uintptr(dupFd), "pty-master")
|
master := os.NewFile(uintptr(dupFd), "pty-master")
|
||||||
return &platformShellSession{
|
shellSession := &platformShellSession{
|
||||||
session: session,
|
session: session,
|
||||||
master: master,
|
master: master,
|
||||||
isPty: request.Term != "",
|
isPty: request.Term != "",
|
||||||
}, nil
|
}
|
||||||
|
if shellSession.isPty && (request.WidthPixels > 0 || request.HeightPixels > 0) {
|
||||||
|
_ = SetWinsize(int(master.Fd()), request.Rows, request.Cols, request.WidthPixels, request.HeightPixels)
|
||||||
|
}
|
||||||
|
return shellSession, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *platformShellBackend) Close() error {
|
func (b *platformShellBackend) Close() error {
|
||||||
@@ -61,8 +65,17 @@ func (s *platformShellSession) CloseWrite() error {
|
|||||||
return syscall.Shutdown(int(s.master.Fd()), syscall.SHUT_WR)
|
return syscall.Shutdown(int(s.master.Fd()), syscall.SHUT_WR)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *platformShellSession) Resize(rows, cols uint16) error {
|
func (s *platformShellSession) Resize(rows, cols, widthPixels, heightPixels uint16) error {
|
||||||
return s.session.Resize(int32(rows), int32(cols))
|
err := s.session.Resize(int32(rows), int32(cols))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// The platform interface carries no pixel dimensions; set them directly
|
||||||
|
// on the duplicated pty master.
|
||||||
|
if s.isPty && (widthPixels > 0 || heightPixels > 0) {
|
||||||
|
return SetWinsize(int(s.master.Fd()), rows, cols, widthPixels, heightPixels)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *platformShellSession) Signal(sig int) error {
|
func (s *platformShellSession) Signal(sig int) error {
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ func (b *directShellBackend) OpenSession(request shellRequest) (shellSession, er
|
|||||||
args = []string{"-" + filepath.Base(shell)}
|
args = []string{"-" + filepath.Base(shell)}
|
||||||
}
|
}
|
||||||
if request.Term != "" {
|
if request.Term != "" {
|
||||||
return OpenPtyShell(shell, args, request.Env, request.User.HomeDir, request.User.Uid, request.User.Gid, request.User.Groups, request.Rows, request.Cols)
|
return OpenPtyShell(shell, args, request.Env, request.User.HomeDir, request.User.Uid, request.User.Gid, request.User.Groups, request.Rows, request.Cols, request.WidthPixels, request.HeightPixels)
|
||||||
}
|
}
|
||||||
return OpenSocketpairShell(shell, args, request.Env, request.User.HomeDir, request.User.Uid, request.User.Gid, request.User.Groups)
|
return OpenSocketpairShell(shell, args, request.Env, request.User.HomeDir, request.User.Uid, request.User.Gid, request.User.Groups)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -325,7 +325,7 @@ func (s *conptyShellSession) Write(p []byte) (int, error) {
|
|||||||
return s.input.Write(p)
|
return s.input.Write(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *conptyShellSession) Resize(rows, cols uint16) error {
|
func (s *conptyShellSession) Resize(rows, cols, _, _ uint16) error {
|
||||||
return s.console.Resize(windows.Coord{X: clampConsoleDimension(cols), Y: clampConsoleDimension(rows)})
|
return s.console.Resize(windows.Coord{X: clampConsoleDimension(cols), Y: clampConsoleDimension(rows)})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -451,7 +451,7 @@ func (s *pipeShellSession) Write(p []byte) (int, error) {
|
|||||||
return s.stdin.Write(p)
|
return s.stdin.Write(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *pipeShellSession) Resize(_, _ uint16) error {
|
func (s *pipeShellSession) Resize(_, _, _, _ uint16) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ type Shell struct {
|
|||||||
isPty bool
|
isPty bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func OpenPtyShell(shell string, args, env []string, dir string, uid, gid int, groups []int, rows, cols uint16) (*Shell, error) {
|
func OpenPtyShell(shell string, args, env []string, dir string, uid, gid int, groups []int, rows, cols, widthPixels, heightPixels uint16) (*Shell, error) {
|
||||||
master, process, err := StartPtyProcess(shell, args, env, dir, uid, gid, groups, rows, cols)
|
master, process, err := StartPtyProcess(shell, args, env, dir, uid, gid, groups, rows, cols, widthPixels, heightPixels)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -52,11 +52,11 @@ func (s *Shell) Write(p []byte) (int, error) {
|
|||||||
return s.master.Write(p)
|
return s.master.Write(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Shell) Resize(rows, cols uint16) error {
|
func (s *Shell) Resize(rows, cols, widthPixels, heightPixels uint16) error {
|
||||||
if !s.isPty {
|
if !s.isPty {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return SetWinsize(int(s.master.Fd()), rows, cols)
|
return SetWinsize(int(s.master.Fd()), rows, cols, widthPixels, heightPixels)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Shell) Signal(sig int) error {
|
func (s *Shell) Signal(sig int) error {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import (
|
|||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
func StartPtyProcess(shell string, args, env []string, dir string, uid, gid int, groups []int, rows, cols uint16) (*os.File, *os.Process, error) {
|
func StartPtyProcess(shell string, args, env []string, dir string, uid, gid int, groups []int, rows, cols, widthPixels, heightPixels uint16) (*os.File, *os.Process, error) {
|
||||||
cmd := exec.Command(shell)
|
cmd := exec.Command(shell)
|
||||||
cmd.Args = args
|
cmd.Args = args
|
||||||
cmd.Dir = dir
|
cmd.Dir = dir
|
||||||
@@ -27,7 +27,7 @@ func StartPtyProcess(shell string, args, env []string, dir string, uid, gid int,
|
|||||||
setCredential(attrs, uid, gid, groups)
|
setCredential(attrs, uid, gid, groups)
|
||||||
var size *pty.Winsize
|
var size *pty.Winsize
|
||||||
if rows > 0 && cols > 0 {
|
if rows > 0 && cols > 0 {
|
||||||
size = &pty.Winsize{Rows: rows, Cols: cols}
|
size = &pty.Winsize{Rows: rows, Cols: cols, X: widthPixels, Y: heightPixels}
|
||||||
}
|
}
|
||||||
master, err := pty.StartWithAttrs(cmd, size, attrs)
|
master, err := pty.StartWithAttrs(cmd, size, attrs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -94,6 +94,11 @@ func setCredential(attr *syscall.SysProcAttr, uid, gid int, groups []int) {
|
|||||||
attr.Credential = cred
|
attr.Credential = cred
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetWinsize(fd int, rows, cols uint16) error {
|
func SetWinsize(fd int, rows, cols, widthPixels, heightPixels uint16) error {
|
||||||
return unix.IoctlSetWinsize(fd, unix.TIOCSWINSZ, &unix.Winsize{Row: rows, Col: cols})
|
return unix.IoctlSetWinsize(fd, unix.TIOCSWINSZ, &unix.Winsize{
|
||||||
|
Row: rows,
|
||||||
|
Col: cols,
|
||||||
|
Xpixel: widthPixels,
|
||||||
|
Ypixel: heightPixels,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user