pty_darwin.go 1.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. package pty
  2. import (
  3. "errors"
  4. "os"
  5. "syscall"
  6. "unsafe"
  7. )
  8. func open() (pty, tty *os.File, err error) {
  9. p, err := os.OpenFile("/dev/ptmx", os.O_RDWR, 0)
  10. if err != nil {
  11. return nil, nil, err
  12. }
  13. sname, err := ptsname(p)
  14. if err != nil {
  15. return nil, nil, err
  16. }
  17. err = grantpt(p)
  18. if err != nil {
  19. return nil, nil, err
  20. }
  21. err = unlockpt(p)
  22. if err != nil {
  23. return nil, nil, err
  24. }
  25. t, err := os.OpenFile(sname, os.O_RDWR, 0)
  26. if err != nil {
  27. return nil, nil, err
  28. }
  29. return p, t, nil
  30. }
  31. func ptsname(f *os.File) (string, error) {
  32. n := make([]byte, _IOC_PARM_LEN(syscall.TIOCPTYGNAME))
  33. err := ioctl(f.Fd(), syscall.TIOCPTYGNAME, uintptr(unsafe.Pointer(&n[0])))
  34. if err != nil {
  35. return "", err
  36. }
  37. for i, c := range n {
  38. if c == 0 {
  39. return string(n[:i]), nil
  40. }
  41. }
  42. return "", errors.New("TIOCPTYGNAME string not NUL-terminated")
  43. }
  44. func grantpt(f *os.File) error {
  45. return ioctl(f.Fd(), syscall.TIOCPTYGRANT, 0)
  46. }
  47. func unlockpt(f *os.File) error {
  48. return ioctl(f.Fd(), syscall.TIOCPTYUNLK, 0)
  49. }