// List the serial ports available on the system. func ListPorts() ([]*Info, error) { var p **C.struct_sp_port if err := C.sp_list_ports(&p); err != C.SP_OK { return nil, errmsg(err) } defer C.sp_free_port_list(p) // Convert the C array into a Go slice // See: https://code.google.com/p/go-wiki/wiki/cgo pp := (*[1 << 15]*C.struct_sp_port)(unsafe.Pointer(p)) // count number of ports c := 0 for ; uintptr(unsafe.Pointer(pp[c])) != 0; c++ { } // populate ports := make([]*Info, c) for j := 0; j < c; j++ { var pc *C.struct_sp_port if err := errmsg(C.sp_copy_port(pp[j], &pc)); err != nil { return nil, err } if sp, err := newInfo(pc); err != nil { return nil, err } else { ports[j] = sp } } return ports, nil }
// Wrap a sp_port struct in a go Port struct and set finalizer for // garbage collection. func newPort(info *Info) (*Port, error) { port := &Port{} // copy info if info != nil { if err := errmsg(C.sp_copy_port(info.p, &port.p)); err != nil { return nil, err } } // set finalizers runtime.SetFinalizer(port, (*Port).free) return port, nil }