Appel de stat Linux avec un timeout

Existe-t-il un moyen de faire en sorte que l’appel du système de statistiques Linux se fasse avec un délai d’attente?

J’utilise un système de fichiers dissortingbué et, en théorie, tous les appels de mon système de fichiers doivent recevoir une réponse rapide. En pratique, ils ne le sont pas. Après un laps de temps déterminé, je préfère avoir un délai et un code d’erreur que de continuer à accrocher.

J’ai essayé de générer la demande dans un autre thread, mais cela a des interactions indésirables avec gdb et c’est une manière assez détournée d’exprimer ce que je veux vraiment: un timeout.

En supposant que vous utilisez C, et que vous pouvez définir le gestionnaire SIGALARM toute sécurité, vous pouvez utiliser un code similaire à celui-ci, juste avec un appel de bibliothèque différent: statvfs peut-il bloquer sur certains périphériques réseau? Comment gérer cette affaire?

Coupez et collez le code et modifiez statvfs en stat :

 #include  #include  #include  #include  // alarm handler doesn't need to do anything // other than simply exist static void alarm_handler( int sig ) { return; } . . . // stat() with a timeout measured in seconds // will return -1 with errno set to EINTR should // it time out int statvfs_try( const char *path, struct stat *s, unsigned int seconds ) { struct sigaction newact; struct sigaction oldact; // make sure they're entirely clear (yes I'm paranoid...) memset( &newact, 0, sizeof( newact ) ); memset( &oldact, 0, sizeof( oldact) ); sigemptyset( &newact.sa_mask ); // note that does not have SA_RESTART set, so // stat() should be interrupted on a signal // (hopefully your libc doesn't restart it...) newact.sa_flags = 0; newact.sa_handler = alarm_handler; sigaction( SIGALRM, &newact, &oldact ); alarm( seconds ); // clear errno errno = 0; int rc = stat( path, s ); // save the errno value as alarm() and sigaction() might change it int save_errno = errno; // clear any alarm and reset the signal handler alarm( 0 ); sigaction( SIGALRM, &oldact, NULL ); errno = saved_errno; return( rc ); }