input_linux.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. package door
  2. import (
  3. "bufio"
  4. "bytes"
  5. "log"
  6. "strings"
  7. "syscall"
  8. "time"
  9. )
  10. var ReaderInterval = time.Duration(200) * time.Millisecond
  11. var ReaderTimeval syscall.Timeval = syscall.NsecToTimeval(int64(ReaderInterval))
  12. // Output a nice string representation of the rune buffer.
  13. func extended_output(buffer []rune) string {
  14. var output string = string(buffer)
  15. output = strings.Replace(output, "\x1b", "^[", -1)
  16. return output
  17. }
  18. // syscall.FdSet clear all
  19. func clearAll(fdSetPtr *syscall.FdSet) {
  20. for index := range (*fdSetPtr).Bits {
  21. (*fdSetPtr).Bits[index] = 0
  22. }
  23. }
  24. // syscall.FdSet set fd
  25. func set(fdSetPtr *syscall.FdSet, fd int) {
  26. (*fdSetPtr).Bits[fd/64] |= 1 << uint64(fd%64)
  27. }
  28. func RuneToInt8(r rune) int8 {
  29. return int8(r)
  30. }
  31. // go routine Reader for input
  32. // This "times out" every ReaderTimeval
  33. func Reader(d *Door) {
  34. // I need non-blocking reads here.
  35. /*
  36. ReaderTimeval = syscall.Timeval{Sec: int64(ReaderInterval.Seconds()),
  37. Usec: ReaderInterval.Microseconds() % time.Second.Microseconds()}
  38. */
  39. log.Println(ReaderInterval, ReaderTimeval)
  40. readerBuffer = make([]rune, 0, READ_SIZE*2)
  41. defer func() {
  42. log.Printf("~Reader\n")
  43. //if d.ReaderCanClose {
  44. d.wg.Done()
  45. //}
  46. }()
  47. defer func() {
  48. if err := recover(); err != nil {
  49. log.Printf("Reader: %#v\n", err)
  50. }
  51. }()
  52. var fdset syscall.FdSet
  53. var readbuffer [READ_SIZE]byte
  54. var runebuffer bytes.Buffer
  55. var runeread = bufio.NewReaderSize(&runebuffer, 1)
  56. var selectTimeval syscall.Timeval
  57. for {
  58. clearAll(&fdset)
  59. set(&fdset, d.READFD)
  60. selectTimeval = ReaderTimeval
  61. v, err := syscall.Select(d.READFD+1, &fdset, nil, nil, &selectTimeval)
  62. if err == syscall.EINTR {
  63. continue
  64. }
  65. // log.Printf("Select: %#v / %#v\n", v, err)
  66. if v == -1 {
  67. log.Printf("Reader ERR: %#v\n", err)
  68. d.readerMutex.Lock()
  69. if !d.ReaderClosed {
  70. d.ReaderClosed = true
  71. close(d.readerChannel)
  72. }
  73. return
  74. }
  75. if v == 0 {
  76. // timeout
  77. ReadRune(d, runeread, true)
  78. // process(d, false)
  79. d.readerMutex.Lock()
  80. if d.ReaderEnd {
  81. if !d.ReaderClosed {
  82. d.ReaderClosed = true
  83. close(d.readerChannel)
  84. }
  85. d.readerMutex.Unlock()
  86. return
  87. }
  88. d.readerMutex.Unlock()
  89. continue
  90. }
  91. // The buffer used here must have len & cap to size you want to read.
  92. // use [BUFF_SIZE]byte for readone
  93. r, err := syscall.Read(d.READFD, readbuffer[:])
  94. if r == -1 {
  95. log.Println("syscall.Read -1 (closed)")
  96. d.readerMutex.Lock()
  97. defer d.readerMutex.Unlock()
  98. if !d.ReaderClosed {
  99. d.ReaderClosed = true
  100. d.Disconnected = true
  101. close(d.readerChannel)
  102. }
  103. return
  104. }
  105. if r == 0 {
  106. log.Printf("Select said ready, but: %#v %#v\n", r, err)
  107. d.readerMutex.Lock()
  108. defer d.readerMutex.Unlock()
  109. if !d.ReaderClosed {
  110. d.ReaderClosed = true
  111. d.Disconnected = true
  112. close(d.readerChannel)
  113. }
  114. return
  115. }
  116. if DEBUG_INPUT {
  117. log.Printf("Reader << %d, %#v\n", r, readbuffer[:r])
  118. }
  119. // write the received bytes into runebuffer.
  120. runebuffer.Write(readbuffer[:r])
  121. ReadRune(d, runeread, false)
  122. // process(d, true)
  123. // buffer = append(buffer, readone[0])
  124. /*
  125. Take2:
  126. input, size = utf8.DecodeRune(buffer)
  127. if input != utf8.RuneError {
  128. d.readerChannel <- input
  129. for size > 0 {
  130. ArrayDelete(&buffer, 0)
  131. size--
  132. }
  133. if len(buffer) > 0 {
  134. goto Take2
  135. }
  136. timeoutCount = 0
  137. } else {
  138. // Not a valid rune
  139. continue
  140. }
  141. */
  142. // d.readerChannel <- rune(buffer[0])
  143. }
  144. }