Ho un semplice pezzo di codice che scrive periodicamente i dati su un file system che viene passato ad esso. Il fd sarà probabilmente una pipe o socket ma potrebbe potenzialmente essere qualsiasi cosa. Sono in grado di rilevare quando il socket/pipe è chiuso/rotto ogni volta che scrivo() ad esso, dal momento che ottengo un errore EPIPE (sto ignorando SIGPIPE). Ma non scrivo tutto il tempo, e quindi non posso rilevare una presa chiusa per molto tempo. Ho bisogno di reagire alla chiusura al più presto. C'è un metodo per controllare il fd senza dover scrivere()? Potrei quindi farlo periodicamente se non scrivo nulla.Linux: Verifica se un socket/pipe è interrotto senza fare una read()/write()
risposta
struct pollfd pfd = {.fd = yourfd, .events = POLLERR};
if (poll(&pfd, 1, whatever) < 0) abort();
if (pfd.revents & POLLERR) printf("pipe is broken\n");
Questo funziona per me. Nota che i socket non sono esattamente pipe e quindi mostrano un comportamento differente (-> usa POLLRDHUP).
Aha! Ho avuto un errore di battitura e stavo controllando gli eventi in uscita invece di revents. Molte grazie, ha funzionato alla grande. – gimmeamilk
Ottima risposta. Sono troppo abituato a selezionare() chiama. Devo cercare di evolvere definitivamente su questo punto. +1 –
Prova con il parametro di selezione ed i suoi errorfds:
int **select**(int nfds, fd_set *restrict readfds,
fd_set *restrict writefds, **fd_set *restrict errorfds**,
struct timeval *restrict timeout);
Grazie, ma ho provato ad aggiungere il mio fd al set di eccezioni e non ho potuto farlo funzionare in modo diverso quando la pipe era rotta. (Potrebbe funzionare bene con il socket, non ho ancora provato dal momento che il mio setup attuale mi da un pipe) – gimmeamilk
Belle risposte, mi piacciono ... Ho anche bisogno di uscire dalla select habbit e nel (e) sondaggio.
Ecco alcuni metodi più tradizionali, se avete bisogno di loro:
/* check whether a file-descriptor is valid */
int fd_valid(int fd)
{
if (fcntl(fd, F_GETFL) == -1 && errno == EBADF) return FALSE;
return TRUE;
}
Questo si cerca di duplicare la presa/fd. E 'molto più semplice di quanto negli sguardi, ho lasciato un sacco di debug.
/* check a file descriptor */
int fd_check(int i) {
int fd_dup = dup(i);
if (fd_dup == -1) {
strcpy(errst, strerror(errno));
// EBADF oldfd isn’t an open file descriptor, or newfd is out of the allowed range for file descriptors.
// EBUSY (Linux only) This may be returned by dup2() during a race condition with open(2) and dup().
// EINTR The dup2() call was interrupted by a signal; see signal(7).
// EMFILE The process already has the maximum number of file descriptors open and tried to open a new one.
if (errno == EBADF) {
return FALSE;
}
return TRUE;
}
close(fd_dup);
return TRUE;
}
- 1. Verifica se stdin è vuoto
- 2. linux + verifica se il file è testo o binario
- 3. Verifica se una colonna NON è NULL
- 4. Ruby: verifica se una porta è aperta
- 5. Verifica se una stringa python è stampabile
- 6. Verifica se una costante è già definita
- 7. Verifica se una condizione è falsa
- 8. Verifica se un intero è compreso nell'intervallo
- 9. Verifica se una classe ha un attributo?
- 10. IOS: verifica se una stringa è una stringa vuota
- 11. Verifica se una funzione std :: è assegnata a un nullptr
- 12. MySQL verifica se esiste una tabella senza generare un'eccezione
- 13. Android: Verifica se un frammento è visibile
- 14. Verifica se è disponibile un modulo node.js
- 15. Sourcetree: verifica se un ramo è unito
- 16. Verifica se un iteratore è valido
- 17. Verifica se BigDecimal è un valore intero
- 18. Verifica se un video è disponibile
- 19. verifica se un file binario è stato compilato con "-static"
- 20. Verifica se l'avviso è disabilitato
- 21. Verifica se javascript è abilitato
- 22. Verifica se Skype è installato
- 23. Verifica se esiste una risorsa
- 24. Verifica se un flusso è un file zip
- 25. Verifica se un collegamento è morto o non si utilizza Python senza scaricare la pagina web
- 26. Verifica se una variabile è definita in lingua template templating
- 27. Verifica se una stringa è interamente maiuscola in Rails
- 28. Verifica se una chiave non è attiva con Qt
- 29. Verifica se l'applicazione è installata nel registro
- 30. Verifica se un elemento è realmente visibile all'utente
selezionare, sondaggio, e epoll saranno tutti vi dirà –
Grazie per la risposta, ma non sono sicuro come fare questo lavoro con tubi. Ho provato una chiamata select() con il mio fd nella scrittura e salvo i fdset, e il risultato della chiamata non cambia quando la pipe è rotta (restituire sempre il mio fd nel set di scrittura). Ho anche provato poll() con tutti gli eventi impostati e ancora non c'è differenza. – gimmeamilk
Non spingere il tuo fd nei set di scrittura. Solo l'eccetto. –