@@ -353,7 +353,8 @@ type GPIOChip struct {
353353 // The file descriptor to the Path device.
354354 fd uintptr
355355 // File associated with the file descriptor.
356- file * os.File
356+ file * os.File
357+ osfile * os.File
357358}
358359
359360func (chip * GPIOChip ) Name () string {
@@ -393,7 +394,9 @@ func newGPIOChip(path string) (*GPIOChip, error) {
393394 }
394395 chip .file = f
395396 chip .fd = chip .file .Fd ()
396- os .NewFile (uintptr (chip .fd ), "GPIO Chip - " + path )
397+ // failure to maintain a reference leads to the file being garbage
398+ // collected and the handle closed...
399+ chip .osfile = os .NewFile (uintptr (chip .fd ), "GPIO Chip - " + path )
397400 var info gpiochip_info
398401 err = ioctl_gpiochip_info (chip .fd , & info )
399402 if err != nil {
@@ -425,7 +428,10 @@ func newGPIOChip(path string) (*GPIOChip, error) {
425428// along with any configured Lines and LineSets.
426429func (chip * GPIOChip ) Close () {
427430 _ = chip .file .Close ()
428-
431+ _ = chip .osfile .Close ()
432+ chip .file = nil
433+ chip .osfile = nil
434+ chip .fd = 0
429435 for _ , line := range chip .lines {
430436 if line .fd != 0 {
431437 line .Close ()
@@ -644,7 +650,9 @@ func (d *driverGPIO) Init() (bool, error) {
644650 for _ , chip := range chips {
645651 // On a pi, gpiochip0 is also symlinked to gpiochip4, checking the map
646652 // ensures we don't duplicate the chip.
647- if _ , found := mName [chip .Name ()]; ! found {
653+ if _ , found := mName [chip .Name ()]; found {
654+ chip .Close ()
655+ } else {
648656 Chips = append (Chips , chip )
649657 mName [chip .Name ()] = struct {}{}
650658 // Now, iterate over the lines on this chip.
0 commit comments