Ioctl()
La funzione della libreria di C
int ioctl(int fd, int request, ...);
comunica con il dispositivo, rappresentato dal file descriptor (1° argomento della funzione) del file-descriptor, passandogli un comando come Intero.
E' solitamente presente un terzo argomento, che può essere un numero di tipo Long oppure un puntatore ad una Struttura. Il significato di questo argomento, il valore restituito ed eventuali codici di errore dipendono dal comando utilizzato. In caso di errore spesso viene restituito il valore -1.
Ogni dispositivo ha propri comandi, da utilizzare nel secondo parametro della funzione ioctl() sia per leggere (ossia per inviare informazioni da un processo al kernel) sia per scrivere (ossia per ritornare informazioni al processo), o entrambi oppure nessuno dei due.
Volendola utilizzare in Gambas, bisognerà dichiararla con Extern, nonché dichiarare la libreria di C: libc.so.6, nella quale la funzione è contenuta:
Private Extern ioctl(fd As Integer, request As Integer, arg As [Long o Struttura]) As Integer In "libc:6"
Nell'esempio, che segue, di uso in Gambas la funzione esterna ioctl() sarà utilizzata per comunicare con il dispositivo lettore CDROM attraverso il file descritptor del suo file-device, al fine di ottenere informazioni sul lettore medesimo e sul CD inserito:
Public Struct cdrom_tochdr
cdth_trk0 As Byte
cdth_trk1 As Byte
End Struct
Library "libc:6"
Private Enum CDROMREADTOCHDR = &5305,
CDROM_MEDIA_CHANGED = &5325,
CDROM_DRIVE_STATUS,
CDROM_DISC_STATUS
Private Enum ERRORE = -1,
CDS_NO_INFO,
CDS_NO_DISC,
CDS_TRAY_OPEN,
CDS_DRIVE_NOT_READY,
CDS_DISC_OK
Private Enum CDS_AUDIO = 100,
CDS_DATA_1,
CDS_DATA_2,
CDS_XA_2_2,
CDS_XA_2_1,
CDS_MIXED
' In questo caso il terzo parametro è un "Intero Lungo":
Private Extern ioctl(di As Integer, req As Integer, arg As Long) As Integer
' Poiché in quest'altro caso il terzo parametro è una "Struttura",
' bisognerà dare alla funzione un nome diverso, e richiamare comunque il vero nome con "Exec":
Private Extern ioctl2(di As Integer, req As Integer, arg As Cdrom_tochdr) As Integer Exec "ioctl"
Public Sub Main()
Dim fl As File
Dim fd, i As Integer
Dim tocHdr As New Cdrom_tochdr
fl = Open "/dev/cdrom" For Read
If IsNull(fl) Then Error.Raise("Impossibile aprire il file-device !")
fd = fl.Handle
If fd < 0 Then Error.Raise("File-device del Drive CD non trovato !")
i = ioctl(fd, CDROM_DRIVE_STATUS, 0)
Select Case i
Case CDS_NO_INFO
Print "Informazioni sul lettore non disponibile !"
Case CDS_NO_DISC
Print "Nessun disco nel lettore !"
Case CDS_TRAY_OPEN
Print "Cassetto del lettore aperto !"
Case CDS_DRIVE_NOT_READY
Print "Lettore non pronto !"
Case CDS_DISC_OK
Print "Stato del lettore: regolare."
Case ERRORE
Print "Errore nella lettura delle informazioni sul lettore CDROM !"
End Select
Print "\n== Informazioni sul disco =="
i = ioctl(fd, CDROM_DISC_STATUS, 0)
Select Case i
Case CDS_NO_INFO
Print "Informazioni sul tipo di disco non disponibile !"
Case CDS_NO_DISC
Print "Nessun disco nel lettore !"
Case CDS_AUDIO
Print "CD AUDIO"
Case CDS_DATA_1
Print "CD Dati_1"
Case CDS_DATA_2
Print "CD Dati_2"
Case CDS_XA_2_2
Print "CD-Extended Architecture 2_2"
Case CDS_XA_2_1
Print "CD-Extended Architecture 2_1"
Case CDS_MIXED
Print "CD Misto"
End Select
ioctl2(fd, CDROMREADTOCHDR, tocHdr)
Print "Numero Tracce presenti: "; tocHdr.cdth_trk1
i = ioctl(fd, CDROM_MEDIA_CHANGED, 0)
If i = 0 Then
Print "Il disco all'interno del lettore non è stato cambiato."
Else
Print "Il disco all'interno del lettore è stato cambiato."
Endif
End