Puoi usare libudev
o analizzare udevadm
output come suggerito da @Ambroz Bizjak. Tuttavia, sconsiglio di aggiungere un processo aggiuntivo (stdbuf
) e lingua (NCD
), solo per analizzare l'output di udevadm.
Un passaggio tra il semplice libudev e l'analisi dell'output è la modifica dei sorgenti di udevadm. Questa soluzione riduce le risorse necessarie e salta del tutto il processo di analisi. Quando guardi il pacchetto udev, troverai i sorgenti per udevd e udevadm nel udev
cartella.
Ecco la routine principale in udevadm.c
e la fonte per udevadm monitor
in udevadm-monitor.c
. Ogni evento ricevuto verrà stampato tramite print_device()
. Qui è dove inserisci il tuo codice.
Se sei a corto di memoria, puoi rimuovere il codice non necessario per control
, info
, settle
, test-builtin
, test
e trigger
. Sul mio sistema (Ubuntu 12.04), questo riduce le dimensioni di udevadm di circa il 75%.
Sfortunatamente, non viene prodotto alcun evento udev su connessione/disconnessione sul lato gadget, quindi è quasi impossibile monitorare questi eventi.
Potresti monitorare i messaggi del kernel (dmesg). Sembra essere un'idea stupida. Oppure guarda alcuni file in sysfs. Forse il modo migliore è applicare patch al kernel.
aggiornamento: Non capisco perché questa risposta abbia ottenuto molti voti negativi.
Forse alcune persone mescolano la parte host USB (che produce eventi UDEV al momento del collegamento/scollegamento del dispositivo) e la parte dispositivo/gadget USB (che non produce tali eventi)
Se il tuo host Linux funziona come un gadget (dispositivo USB connesso a un host USB) non c'è un buon modo per rilevare gli eventi plug/unplug.
Prova:messaggio di Greg Kroah-Hartman
un'altra copia se il collegamento precedente non è attivo
Se vuoi tutto nel tuo singolo processo, dovrai usare libudev per ottenere gli eventi da udevd
o direttamente dal kernel.
Visto che potrebbe essere un problema usare libudev nella tua applicazione (mancanza di documentazione?), un'alternativa è usare il programma udevadm, che può:
- segnala gli eventi del dispositivo dopo essere stati elaborati da
udevd
(udevadm monitor --udev --property
), - riporta eventi devive direttamente dal kernel (
udevadm monitor --kernel --property
), e - scarica il database di udevd dei dispositivi correnti (ma non quello del kernel!) (
udevadm info --query all --export-db
)
udevadm
fa parte del pacchetto udev, ma non dovrebbe aver bisogno di udevd
se lo usi solo per segnalare eventi del kernel. Puoi usarlo facendo in modo che il tuo processo lo generi e analizzi il suo output standard (ma dovrai avviarlo tramite stdbuf -o L
).
In ogni caso, probabilmente ci vorrà molto lavoro. Ho già implementato molto di questo nel mio linguaggio di programmazione NCD, incluso il monitoraggio dei dispositivi USB. Potresti dare un'occhiata a NCD; è utile per molte attività di configurazione e gestisce bene l'hotplugging. Ad esempio, questo programma NCD stamperà gli eventi del dispositivo USB sullo standard output:
process main {
sys.watch_usb() watcher;
println(watcher.event_type, " ", watcher.devname, " ", watcher.vendor_id, ":", watcher.model_id);
watcher->nextevent();
}
Questo farà sì che NCD stampi qualcosa del genere (con un added
iniziale evento per qualsiasi dispositivo USB già collegato):
added /dev/bus/usb/002/045 0409:0059
added /dev/bus/usb/002/046 046d:c313
added /dev/bus/usb/002/047 046d:c03e
added /dev/bus/usb/002/048 0557:2008
removed /dev/bus/usb/002/048 0557:2008
Puoi anche usare NCD solo per questo e analizzare this output standard - con cui è molto più facile lavorare che giocare direttamente con udevadm.
Nota che lo stesso NCD usa udevadm
, e lo fa richiedono che udevd sia in esecuzione; ma perché è un problema comunque? (con un po' di lavoro questa dipendenza potrebbe essere rimossa)