Differenze tra le versioni di "Ioctl()"

Da Gambas-it.org - Wikipedia.
 
(27 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
 
La funzione della libreria di C
 
La funzione della libreria di C
  int ioctl(int fd, int request, ...);
+
  int ioctl(int __fd, unsigned long int __request, ...)
comunica con il dispositivo, rappresentato dal ''file descriptor'' (1° argomento della funzione) del relativo ''file-device'', passandogli un comando come Intero.
+
comunica con il dispositivo hardware, rappresentato dal ''file descriptor'' (1° argomento della funzione) del relativo ''file-device'', passandogli un comando come Intero ''Lungo'' (2° argomento della funzione).
  
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.
+
E' solitamente presente un terzo argomento, che può essere un numero di tipo ''Long'', una variabile del tipo di una ''Struttura'' oppure di tipo ''Puntatore''. Il significato di questo argomento, il valore restituito ed eventuali codici di errore dipendono dal comando utilizzato.
  
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.
+
In caso di errore spesso dalla funzione esterna "ioctl()" viene restituito il valore -1.
  
 +
Ogni dispositivo ha propri comandi, da utilizzare nel secondo parametro della funzione esterna "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:
+
Volendola utilizzare in Gambas, bisognerà dichiararla con Extern, nonché dichiarare la libreria di C, ''libc.so.6'', nella quale la funzione è contenuta:
  Private <FONT color=#B22222>Extern ioctl</font>(fd As Integer, request As Integer, arg As [''Long'' o ''Struttura'']) As Integer In "<FONT color=#B22222>libc:6</font>"
+
  Private <FONT color=#B22222>Extern ioctl</font>(__fd As Integer, __request As Long, arg As [''Long'' o ''Struttura'' o ''Puntatore'' o ''Array'']) As Integer In "<FONT color=#B22222>libc:6</font>"
 +
Nella dichiarazione con "Extern" il terzo argomento potrà essere anche semplicemente dichiarato con "<U>tre</u>" punti:
 +
Private Extern ioctl(__fd As Integer, __request As Long, <FONT color=#B22222><B>...</b></font>) As Integer
  
 
+
====Esempio pratico====
 
+
Nell'esempio, che segue, di uso in Gambas la funzione esterna "ioctl()" sarà utilizzata per comunicare con il dispositivo lettore CDROM attraverso il ''file descriptor'' del suo ''file-device'', al fine di ottenere informazioni sul lettore medesimo e sul CD inserito:
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:
+
Library "<FONT color=#B22222>libc:6</font>"
 +
 
  Public Struct cdrom_tochdr
 
  Public Struct cdrom_tochdr
 
   cdth_trk0 As Byte
 
   cdth_trk0 As Byte
Riga 24: Riga 28:
 
   cdte_adr_ctrl As Byte
 
   cdte_adr_ctrl As Byte
 
   cdte_format As Short
 
   cdte_format As Short
   cdte_minute As Byte
+
   minute As Byte
   cdte_second As Byte
+
   second As Byte
   cdte_frame As Byte
+
   frame As Byte
   cdte_lba As Integer
+
   lba As Integer
 
   cdte_datamode As Byte
 
   cdte_datamode As Byte
 
  End Struct
 
  End Struct
+
 
 
Library "<FONT color=#B22222>libc:6</font>"
 
 
 
  Private Enum CDROMREADTOCHDR = &5305,
 
  Private Enum CDROMREADTOCHDR = &5305,
 
               CDROMREADTOCENTRY,
 
               CDROMREADTOCENTRY,
Riga 56: Riga 57:
 
  Private Const CDROM_MSF As Byte = 2
 
  Private Const CDROM_MSF As Byte = 2
 
   
 
   
  <FONT Color=gray>' ''In questo caso il terzo parametro è un "Intero Lungo":''</font>
+
  <FONT Color=gray>' ''In questo caso il terzo parametro è un "Intero Lungo".''
  Private <FONT color=#B22222>Extern ioctl</font>(di As Integer, req As Integer, arg As Long) As Integer
+
' ''int ioctl(int __fd, unsigned long int __request, ...)''
 +
' ''Perform the I/O control operation specified by REQUEST on FD.''</font>
 +
  Private Extern <FONT color=#B22222>ioctl</font>(__fd As Integer, __request As Long, arg As Long) As Integer
 
   
 
   
  <FONT Color=gray>' ''Poiché in quest'altro caso il terzo parametro è una "Struttura",''
+
  <FONT Color=gray>' ''Poiché in quest'altro caso il terzo parametro è una "Struttura", bisognerà dare alla funzione un nome diverso, per differenziarla da quella precedente, e richiamarla con il vero nome mediante "Exec".''</font>
' ''bisognerà dare alla funzione un nome diverso, e richiamare comunque il vero nome con "Exec":''</font>
+
  Private Extern <FONT color=#B22222>ioctl2</font>(__fd As Integer, __request As Long, arg As Cdrom_tochdr) As Integer Exec "<FONT color=darkgreen>ioctl</font>"
  Private <FONT color=#B22222>Extern ioctl2</font>(di As Integer, req As Integer, arg As Cdrom_tochdr) As Integer Exec "ioctl"
 
 
   
 
   
  <FONT Color=gray>' ''Poiché in quest'altro caso il terzo parametro è una "Struttura" diversa dalla precedente,''
+
  <FONT Color=gray>' ''Poiché in quest'altro caso il terzo parametro è una "Struttura" diversa dalla precedente, bisognerà dare alla funzione un nome diverso, per differenziarla da quelle precedenti, e richiamarla con il vero nome mediante "Exec".''</font>
' ''bisognerà dare alla funzione un nome diverso, e richiamare comunque il vero nome con "Exec":''</font>
+
  Private Extern <FONT color=#B22222>ioctl3</font>(__fd As Integer, __request As Long, arg As Cdrom_tocentry) As Integer Exec "<FONT color=darkgreen>ioctl</font>"
  Private <FONT color=#B22222>Extern ioctl3</font>(di As Integer, req As Integer, arg As Cdrom_tocentry) As Integer Exec "ioctl"
 
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
   
 
   
 
   Dim fl As File
 
   Dim fl As File
Riga 74: Riga 75:
 
   Dim tocHdr As New Cdrom_tochdr
 
   Dim tocHdr As New Cdrom_tochdr
 
   Dim tocentry As New Cdrom_tocentry
 
   Dim tocentry As New Cdrom_tocentry
   Dim b, m, s As Byte
+
   Dim b, t, m, s As Byte
 
+
    
+
   fl = Open "/dev/cdrom" For Read
  fl = Open "/dev/cdrom" For Read
+
  If IsNull(fl) Then Error.Raise("Impossibile aprire il file-device !")
  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 = <FONT color=#B22222>ioctl</font>(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
 
   
 
   
  fd = fl.Handle
+
  Print "\n== Informazioni sul disco ==\e[31m"
  If fd < 0 Then Error.Raise("File-device del Drive CD non trovato !")
 
   
 
  i = <FONT color=#B22222>ioctl</font>(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 =="
 
   
 
  st = <FONT color=#B22222>ioctl</font>(fd, CDROM_DISC_STATUS, 0)
 
  Select Case st
 
    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
 
 
 
 
   
 
   
  i = <FONT color=#B22222>ioctl</font>(fd, CDROM_MEDIA_CHANGED, 0)
+
  st = <FONT color=#B22222>ioctl</font>(fd, CDROM_DISC_STATUS, 0)
  If i = 0 Then
+
  Select Case st
    Print "Il disco all'interno del lettore non è stato cambiato."
+
    Case CDS_NO_INFO
  Else
+
      Print "Informazioni sul tipo di disco non disponibile !"
    Print "Il disco all'interno del lettore è stato cambiato."
+
    Case CDS_NO_DISC
  Endif
+
      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
 +
  Print "\e[0m"
 
   
 
   
  <FONT color=#B22222>ioctl2</font>(fd, CDROMREADTOCHDR, tocHdr)
+
  i = <FONT color=#B22222>ioctl</font>(fd, CDROM_MEDIA_CHANGED, 0)
  Print "\nNumero Tracce presenti: "; tocHdr.cdth_trk1 - tocHdr.cdth_trk0
+
  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
 
   
 
   
  If st = 100 Then
+
  If st = 100 Then
    With tocentry
+
    <FONT color=#B22222>ioctl2</font>(fd, CDROMREADTOCHDR, tocHdr)
      .cdte_track = tocHdr.cdth_trk1
+
    Print "\nNumero Tracce audio presenti: "; tocHdr.cdth_trk1
      .cdte_format = CDROM_MSF
+
   
 +
    For b = tocHdr.cdth_trk0 To tocHdr.cdth_trk1 + 1
 +
      t = b
 +
      If b = tocHdr.cdth_trk1 + 1 Then
 +
        b = &AA
 +
        t = tocHdr.cdth_trk1 + 1
 +
      Endif
 +
      With tocentry
 +
        .cdte_track = b
 +
        .cdte_format = CDROM_MSF
 
         <FONT color=#B22222>ioctl3</font>(fd, CDROMREADTOCENTRY, tocentry)
 
         <FONT color=#B22222>ioctl3</font>(fd, CDROMREADTOCENTRY, tocentry)
      Print "Durata CD: "; Str(Date(0, 0, 0, 0, 0, 0, ((((.cdte_minute) * 60) + .cdte_second) * 1000)))
+
        If b > tocHdr.cdth_trk0 Then
    End With
+
          Print "Durata della traccia n. "; t - 1; ": "; Str(Time(0, 0, 0, (((.minute - m) * 60) + .second - s) * 1000))
 +
        Endif
 +
        m = .minute
 +
        s = .second
 +
      End With
 +
    Next
 +
  Endif
 
   
 
   
    For b = tocHdr.cdth_trk0 To tocHdr.cdth_trk1
+
  Print "\nDurata totale del CD-Audio: "; Time(0, 0, 0, ((tocentry.minute * 60) + tocentry.second) * 1000)
      With tocentry
 
        .cdte_track = b
 
        <FONT color=#B22222>ioctl3</font>(fd, CDROMREADTOCENTRY, tocentry)
 
        If b > tocHdr.cdth_trk0 Then
 
          Print "Durata della traccia n. ;"; b - 1; ": "; Str(Date(0, 0, 0, 0, 0, 0, ((((.cdte_minute - m) * 60) + .cdte_second - s) * 1000)))
 
        Endif
 
        m = .cdte_minute
 
        s = .cdte_second
 
      End With
 
    Next
 
  Endif
 
 
   
 
   
  '''End'''
+
  End
 +
 
 +
 
 +
 
 +
=Riferimenti=
 +
* Vedere anche le seguenti pagine:
 +
- [[Individuare_i_tasti_della_tastiera_intercettando_i_dati_grezzi_dal_suo_file-device#Usando_la_funzione_esterna_.22ioctl.28.29.22|Individuare i tasti della tastiera intercettando i dati grezzi dal suo file-device]]
 +
<BR> - [[Emulare in Gambas le macro IOC, IOR, IOW e IOWR usate con la funzione ioctl()]]

Versione attuale delle 15:21, 13 giu 2024

La funzione della libreria di C

int ioctl(int __fd, unsigned long int __request, ...)

comunica con il dispositivo hardware, rappresentato dal file descriptor (1° argomento della funzione) del relativo file-device, passandogli un comando come Intero Lungo (2° argomento della funzione).

E' solitamente presente un terzo argomento, che può essere un numero di tipo Long, una variabile del tipo di una Struttura oppure di tipo Puntatore. Il significato di questo argomento, il valore restituito ed eventuali codici di errore dipendono dal comando utilizzato.

In caso di errore spesso dalla funzione esterna "ioctl()" viene restituito il valore -1.

Ogni dispositivo ha propri comandi, da utilizzare nel secondo parametro della funzione esterna "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 Long, arg As [Long o Struttura o Puntatore o Array]) As Integer In "libc:6"

Nella dichiarazione con "Extern" il terzo argomento potrà essere anche semplicemente dichiarato con "tre" punti:

Private Extern ioctl(__fd As Integer, __request As Long, ...) As Integer

Esempio pratico

Nell'esempio, che segue, di uso in Gambas la funzione esterna "ioctl()" sarà utilizzata per comunicare con il dispositivo lettore CDROM attraverso il file descriptor del suo file-device, al fine di ottenere informazioni sul lettore medesimo e sul CD inserito:

Library "libc:6"

Public Struct cdrom_tochdr
  cdth_trk0 As Byte
  cdth_trk1 As Byte
End Struct

Public Struct cdrom_tocentry
  cdte_track As Byte
  cdte_adr_ctrl As Byte
  cdte_format As Short
  minute As Byte
  second As Byte
  frame As Byte
  lba As Integer
  cdte_datamode As Byte
End Struct
 
Private Enum CDROMREADTOCHDR = &5305,
             CDROMREADTOCENTRY,
             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

Private Const CDROM_MSF As Byte = 2

' In questo caso il terzo parametro è un "Intero Lungo".
' int ioctl(int __fd, unsigned long int __request, ...)
' Perform the I/O control operation specified by REQUEST on FD.
Private Extern ioctl(__fd As Integer, __request As Long, arg As Long) As Integer

' Poiché in quest'altro caso il terzo parametro è una "Struttura", bisognerà dare alla funzione un nome diverso, per differenziarla da quella precedente, e richiamarla con il vero nome mediante "Exec".
Private Extern ioctl2(__fd As Integer, __request As Long, arg As Cdrom_tochdr) As Integer Exec "ioctl"

' Poiché in quest'altro caso il terzo parametro è una "Struttura" diversa dalla precedente, bisognerà dare alla funzione un nome diverso, per differenziarla da quelle precedenti, e richiamarla con il vero nome mediante "Exec".
Private Extern ioctl3(__fd As Integer, __request As Long, arg As Cdrom_tocentry) As Integer Exec "ioctl"


Public Sub Main()

 Dim fl As File
 Dim fd, st, i As Integer
 Dim tocHdr As New Cdrom_tochdr
 Dim tocentry As New Cdrom_tocentry
 Dim b, t, m, s As Byte

 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 ==\e[31m"

 st = ioctl(fd, CDROM_DISC_STATUS, 0)
 Select Case st
   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
 Print "\e[0m"

 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

 If st = 100 Then
   ioctl2(fd, CDROMREADTOCHDR, tocHdr)
   Print "\nNumero Tracce audio presenti: "; tocHdr.cdth_trk1
   
   For b = tocHdr.cdth_trk0 To tocHdr.cdth_trk1 + 1
     t = b
     If b = tocHdr.cdth_trk1 + 1 Then
       b = &AA
       t = tocHdr.cdth_trk1 + 1
     Endif
     With tocentry
       .cdte_track = b
       .cdte_format = CDROM_MSF
       ioctl3(fd, CDROMREADTOCENTRY, tocentry)
       If b > tocHdr.cdth_trk0 Then
         Print "Durata della traccia n. "; t - 1; ": "; Str(Time(0, 0, 0, (((.minute - m) * 60) + .second - s) * 1000))
       Endif
       m = .minute
       s = .second
     End With
   Next
 Endif

 Print "\nDurata totale del CD-Audio: "; Time(0, 0, 0, ((tocentry.minute * 60) + tocentry.second) * 1000)

End


Riferimenti

  • Vedere anche le seguenti pagine:

- Individuare i tasti della tastiera intercettando i dati grezzi dal suo file-device
- Emulare in Gambas le macro IOC, IOR, IOW e IOWR usate con la funzione ioctl()