Browse Source

Drop os.File in favor of unix.Open / unix.Close.

Beoran 4 years ago
parent
commit
4bbfc942be
2 changed files with 62 additions and 133 deletions
  1. 57 131
      os/linux/input/input_linux.go
  2. 5 2
      os/linux/input/input_linux_test.go

+ 57 - 131
os/linux/input/input_linux.go

@@ -18,9 +18,7 @@ import "syscall"
 // Device models an input device
 type Device struct {
     FileName string 
-    *os.File
-    syscall.RawConn
-    FD uintptr
+    fd int
     // Cached device information
     Info struct { 
         Events          []SupportedEvent
@@ -45,7 +43,7 @@ func LogDebug(format string, args...interface{}) {
 
 
 func (d * Device) KeepAlive() {
-    runtime.KeepAlive(d.File)
+    runtime.KeepAlive(d)
 }
 
 func (d * Device) String() string {
@@ -56,44 +54,25 @@ func (d * Device) String() string {
 }
 
 func (d *Device) SetNonblock(nonblocking bool) error {
-	var err error = nil
-	setnonblock := func(fd uintptr) {
-		err = unix.SetNonblock(int(fd), nonblocking)
-	}
-	err2 := d.Control(setnonblock)
-	if err2 != nil {
-		return err2
-	}
+	err := unix.SetNonblock(int(d.fd), nonblocking)
 	return err
 }
 
 func Open(name string) (*Device, error) {
-    f, err := os.OpenFile(filepath.Join(Directory, name), 
-        unix.O_ASYNC|unix.O_NONBLOCK|os.O_RDWR, 0666)
+	path := filepath.Join(Directory, name)
+    fd, err := unix.Open(path, unix.O_ASYNC|unix.O_NONBLOCK|unix.O_RDWR, 0666)
     if err != nil {
         return nil, err
     }
-        
-    rawConn, err := f.SyscallConn()
-    if err != nil {
-        return nil, err
-    }
-    // this is cheating ,but avoid me from calling .Fd()
-    // Furthermore, this is unlikely to change for real ddevice files
-    var FD uintptr
-    err = rawConn.Control(func(fd uintptr) {
-		FD = fd
-	}) 	
-	if err != nil {
-        return nil, err
-    }
     	        
-    device := &Device{FileName: name, File: f, RawConn: rawConn, FD: FD}
+    device := &Device{FileName: name, fd: fd}
         
     if err = device.SetNonblock(true) ;  err != nil {
         return nil, err
     }
     
+    runtime.SetFinalizer(device, (*Device).Close)
+    
     return device, nil
 }
 
@@ -154,42 +133,32 @@ func List() ([]string, error) {
 // Icotl performs an ioctl on the given device
 func (d * Device) Ioctl(code uint32, pointer unsafe.Pointer) error {
     var errno syscall.Errno = 0 
-    ioctler := func (fd uintptr) {
-        LogDebug("ioctl: %d %d %d\n", uintptr(fd), uintptr(code), uintptr(pointer))
+    LogDebug("ioctl: %d %d %d\n", uintptr(d.fd), uintptr(code), uintptr(pointer))
         _, _, errno = unix.Syscall(
             unix.SYS_IOCTL,
-            uintptr(fd),
+            uintptr(d.fd),
             uintptr(code),
             uintptr(pointer))
-    }
-    err2 := d.Control(ioctler)
-    if err2 != nil {
-        return err2
-    }
-    if errno == 0 {
-        return nil
-    }
-    return errno
+	if errno != 0 {
+		return errno
+	}            
+    return nil
 }
 
 // Read performs a read unix on the given device. The read is noblocking
 // and will retrn 0 if EAGEIN was raised.
 func (d * Device) Read(pointer unsafe.Pointer, size uintptr) (uintptr, error) {
+    if d.IsClosed() {
+		return 0, syscall.EINVAL
+	}	
     var errno syscall.Errno = 0 
     var read uintptr = 0
-    reader := func (fd uintptr) bool {
-        LogDebug("read: %d %d %d\n", uintptr(fd), uintptr(pointer), uintptr(size))
-        read, _, errno = unix.Syscall(
+    LogDebug("read: %d %d %d\n", uintptr(d.fd), uintptr(pointer), uintptr(size))
+    read, _, errno = unix.Syscall(
             unix.SYS_READ,
-            uintptr(fd),
+            uintptr(d.fd),
             uintptr(pointer),
             uintptr(size))
-        return true
-    }
-    err2 := d.RawConn.Read(reader)
-    if err2 != nil {
-        return read, err2
-    }
     if errno == 0 {
         return read, nil
     }
@@ -201,50 +170,53 @@ func (d * Device) Read(pointer unsafe.Pointer, size uintptr) (uintptr, error) {
 
 // Read performs a read unix on the given device. The read is blocking.
 func (d * Device) ReadBlock(pointer unsafe.Pointer, size uintptr) (uintptr, error) {
-    var errno syscall.Errno = 0 
-    var read uintptr = 0
-    reader := func (fd uintptr) bool {
-        LogDebug("read: %d %d %d\n", uintptr(fd), uintptr(pointer), uintptr(size))
-        read, _, errno = unix.Syscall(
-            unix.SYS_READ,
-            uintptr(fd),
-            uintptr(pointer),
-            uintptr(size))
-        return errno != syscall.EAGAIN
-    }
-    err2 := d.RawConn.Read(reader)
-    if err2 != nil {
-        return read, err2
-    }
-    if errno == 0 {
-        return read, nil
-    }
-    return read, errno
+	read, err := d.Read(pointer, size) 
+	for read < 1 {
+		if err != nil {
+			return 0, err
+		}
+		read, err = d.Read(pointer, size) 
+	}
+    return read, err
 }
 
 // Write performs a write unix on the given device. The write is blocking.
 func (d * Device) Write(pointer unsafe.Pointer, size uintptr) (uintptr, error) {
-    var errno syscall.Errno = 0 
+	if d.IsClosed() {
+		return 0, syscall.EINVAL
+	}
+		
+    var errno syscall.Errno = syscall.EAGAIN
     var wrote uintptr = 0
-    writer := func(fd uintptr) bool {
-        LogDebug("write: %d %d %d\n", uintptr(fd), uintptr(pointer), uintptr(size))
-        wrote, _, errno = unix.Syscall(
+    for errno == syscall.EAGAIN {
+		LogDebug("write: %d %d %d\n", uintptr(d.fd), uintptr(pointer), uintptr(size))
+		wrote, _, errno = unix.Syscall(
             unix.SYS_WRITE,
-            uintptr(fd),
+            uintptr(d.fd),
             uintptr(pointer),
             uintptr(size))
-        return errno != syscall.EAGAIN
-    }
-    err2 := d.RawConn.Write(writer)
-    if err2 != nil {
-        return wrote, err2
-    }
+	}
     if errno == 0 {
         return wrote, nil
     }
     return wrote, errno
 }
 
+func (d * Device) IsClosed() bool {
+	return d.fd < 0
+}
+
+// Close closes the device
+func (d * Device) Close() error { 
+	if d.IsClosed() {
+		return nil
+	}
+	err := unix.Close(d.fd)
+	if err != nil {
+		return err
+	}            
+	return nil
+}
 
 
 func (d * Device) DriverVersion() (int32, error) {
@@ -521,9 +493,9 @@ func (driver *Driver) connectDevice(device * Device) {
     driver.Lock()
     defer driver.Unlock()
     driver.DevicesByName[device.FileName] = device
-    driver.DevicesByFd[int(device.FD)] = device
+    driver.DevicesByFd[int(device.fd)] = device
     driver.Devices = append(driver.Devices, device)
-    pollfd := unix.PollFd{Fd: int32(device.FD), Events : unix.POLLIN}
+    pollfd := unix.PollFd{Fd: int32(device.fd), Events : unix.POLLIN}
     driver.fds = append(driver.fds, pollfd) 
     driver.Connect <- device
 }
@@ -532,12 +504,12 @@ func (driver *Driver) disconnectDevice(device * Device) {
     driver.Lock()
     defer driver.Unlock()
     delete(driver.DevicesByName, device.FileName)
-    delete(driver.DevicesByFd, int(device.FD))
+    delete(driver.DevicesByFd, int(device.fd))
     found := false
     var i int
     var pollfd unix.PollFd
     for i, pollfd = range driver.fds {
-        if pollfd.Fd == int32(device.FD) {
+        if pollfd.Fd == int32(device.fd) {
             found = true 
             break
         }
@@ -628,49 +600,3 @@ func (driver *Driver) Stop() {
 }
 
 
-/*    
-	printf("Supported events:\n");
-	for (i = 0; i < EV_MAX; i++)
-		if (TestBit(i, bit[0])) {
-            
-		}
-		
-
-	printf("Testing ... (interrupt to exit)\n");
-
-	while (1) {
-		rd = read(fd, ev, sizeof(struct input_event) * 64);
-
-		if (rd < (int) sizeof(struct input_event)) {
-			printf("yyy\n");
-			perror("\nevtest: error reading");
-			return 1;
-		}
-
-		for (i = 0; i < rd / sizeof(struct input_event); i++)
-
-			if (ev[i].type == EV_SYN) {
-				printf("Event: time %ld.%06ld, -------------- %s ------------\n",
-					ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].code ? "Config Sync" : "Report Sync" );
-			} else if (ev[i].type == EV_MSC && (ev[i].code == MSC_RAW || ev[i].code == MSC_SCAN)) {
-				printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %02x\n",
-					ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].type,
-					events[ev[i].type] ? events[ev[i].type] : "?",
-					ev[i].code,
-					names[ev[i].type] ? (names[ev[i].type][ev[i].code] ? names[ev[i].type][ev[i].code] : "?") : "?",
-					ev[i].value);
-			} else {
-				printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %d\n",
-					ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].type,
-					events[ev[i].type] ? events[ev[i].type] : "?",
-					ev[i].code,
-					names[ev[i].type] ? (names[ev[i].type][ev[i].code] ? names[ev[i].type][ev[i].code] : "?") : "?",
-					ev[i].value);
-			}	
-
-	}
-}
-*/
-
-
-

+ 5 - 2
os/linux/input/input_linux_test.go

@@ -9,8 +9,10 @@ import "gitlab.com/beoran/galago/os/linux"
 
 
 
-const IN = "by-id/usb-0583_USB_2-axis_8-button_gamepad-event-joystick"
+const IN1 = "by-id/usb-0583_USB_2-axis_8-button_gamepad-event-joystick"
 const IN2 = "by-id/usb-PixArt_USB_Optical_Mouse-event-mouse"
+const IN3 = "by-id/usb-Logitech_USB_Receiver-if02-event-mouse"
+const IN = IN3
 
 func TestList(t * testing.T) {
     names, err := List()
@@ -223,7 +225,8 @@ func TestDriver(t * testing.T) {
             for !done {
                 eve := <- driver.Events
                 fmt.Printf("%s\n", eve.String())
-                if eve.Type == linux.EV_KEY && eve.Code == linux.BTN_JOYSTICK {
+                if eve.Type == linux.EV_KEY && (
+					eve.Code == linux.BTN_JOYSTICK || eve.Code == linux.BTN_MOUSE) {
                     done = true
                 }   
             }