archivos - ¿Cómo verificar si un descriptor de archivo dado almacenado en una variable sigue siendo válido?
descriptores de archivos linux (6)
Tengo un descriptor de archivo almacenado en una variable, por ejemplo, var. ¿Cómo puedo verificar si ese descriptor es válido en una etapa posterior?
fdvar1= open(.....);
fdvar2 = fdvar1; // Please ignore the bad design
....
// lots of loops , conditionals and threads. It can call close(fdvar2) also.
....
if(CheckValid(fdvar1)) // How can I do this check ?
write(fdvar1, ....);
Ahora quiero verificar si var1 (que aún conserva el descriptor abierto) sigue siendo válido. Cualquier API para eso?
De this artículo del foro:
int is_valid_fd(int fd)
{
return fcntl(fd, F_GETFL) != -1 || errno != EBADF;
}
fcntl (GETFL) es probablemente la operación más barata y menos probable de fallar que puede realizar en un descriptor de archivo. En particular, la especificación sugiere que no puede ser interrumpida por señales, ni se ve afectada por ningún tipo de bloqueo en cualquier lugar.
Me parece que si quiere saber si todavía apunta al mismo recurso, un enfoque (no perfecto) sería fstat()
el descriptor justo después de abrir y luego podrá hacerlo nuevamente y comparar los resultados. Comience por mirar .st_mode
& S_IFMT
e ir desde allí - ¿es un objeto del sistema de archivos? Mira .st_dev / .st_ino.
¿Es un zócalo? Pruebe getsockname()
, getpeername()
. No será 100% seguro, pero puede decirle si definitivamente no es lo mismo.
No creo que haya ninguna función que pueda indicarle si el descriptor aún es válido. El descriptor es típicamente solo un entero pequeño como 6 y su libc puede elegir reutilizar ese número si cierra el archivo y abre uno nuevo más tarde.
En su lugar, debería considerar usar dup()
para copiar el descriptor de archivo. Al duplicar el descriptor de archivo en lugar de utilizar el mismo descriptor en varios lugares, puede ser más fácil para usted saber si el descriptor de archivo sigue siendo válido. Solo debe recordar cerrar el descriptor original y el duplicado cuando haya terminado.
Puede usar la función fcntl()
:
int fd_is_valid(int fd)
{
return fcntl(fd, F_GETFD) != -1 || errno != EBADF;
}
Resolví este problema para mí. No sé si se puede usar para fines generales, pero para conexiones en serie funciona bien (por ejemplo, / dev / ttyUSB0).
struct stat s;
fstat(m_fileDescriptor, &s);
// struct stat::nlink_t st_nlink; ... number of hard links
if( s.st_nlink < 1 ){
// treat device disconnected case
}
Para más detalles, consulte, por ejemplo, la página man http://linux.die.net/man/2/fstat
Saludos, Flo
fcntl(fd, F_GETFD)
es la manera canónica más barata de verificar que fd
sea un descriptor de archivo abierto válido. Si necesita realizar un control por lotes mucho, el uso de poll
con un tiempo de espera cero y el miembro de events
establecido en 0 y la comprobación de POLLNVAL
en revents
después de su devolución es más eficiente.
Dicho esto, la operación "verificar si un identificador de recurso determinado sigue siendo válido" casi siempre es fundamentalmente incorrecta. Después de que se libera un identificador de recurso (por ejemplo, un fd está close
d), su valor puede reasignarse al siguiente recurso que asigne. Si hay referencias restantes que podrían usarse, operarán erróneamente el nuevo recurso en lugar del anterior. Por lo tanto, la respuesta real es probablemente: si aún no conoce la lógica de su programa, tiene importantes errores de lógica fundamental que deben corregirse.