miércoles, 10 de marzo de 2010

Uname & Select

UNAME(2)

NOMBRE uname - obtiene el nombre e información del núcleo actual

SINOPSIS #include %lt;sys/utsname.h%gt;

int uname(struct utsname *buf);

DESCRIPCIÓN uname devuelve información del sistema en la estructura apuntada por

buf. La estructura utsname se define en %lt;sys/utsname.h%gt;:

struct utsname {

char sysname[]; //Nombre del Sistema

char nodename[]; //Nombre de la maquina en la(s) red(es) *

char release[];

char version[]; Version del Kernel

char machine[];

#ifdef _GNU_SOURCE

char domainname[]; //Nombre del Dominio

#endif

};

La longitud de los vectores de la estructura utsname es indefinida; los campos terminan en NUL.

VALOR DEVUELTO Éxito à cero. Error à -1 y se establece el errno apropiado.

ERRORES EFAULT à buf no es válido.

CONFORME A

No hay ninguna llamada uname en BSD 4.3.

El miembro domainname (el nombre de dominio NIS o YP) es una extensión de GNU.

OBSERVACIONES

Cuatro de los campos de la estructura son relevantes (sysname, relase, versión y machine). Por otra parte, el campo nodename carece de importancia: da el nombre de la máquina actual en alguna red indefinida, pero normalmente las máquinas se encuentran en más de una red y tienen muchos nombres.

Además, el núcleo no tiene manera de conocer estas situaciones, por lo que hay que decirle cómo actuar en este caso. Lo mismo vale para el campo adicional domainname. Para este propósito Linux utiliza las llamadas al sistema sethostname(2) y setdomainname(2).

La longitud de los campos en la estructura varía. Algunos sistemas operativos o bibliotecas usan valores fijos como 9, 33, 65 o 257. Otros sistemas usan SYS_NMLN o _SYS_NMLN o UTSLEN o _UTSNAME_LENGTH. Claramente, es una mala idea usar cualquiera de estas constantes - tan sólo utilice sizeof(...). A menudo se elige 257 con el fin de tener espacio para un nombre de host en internet.

Ha habido tres llamadas al sistema uname() en Linux. La primera usaba longitud 9, la segunda usaba 65, la tercera también usa 65 pero añade el campo domainname.

Parte de la información de utsname también puede ser accedida vía sysctl y vía /proc/sys/kernel/{ostype, hostname, osrelease, version, domainname}.

SELECT(2)

NOMBRE select, pselect, FD_CLR, FD_ISSET, FD_SET, FD_ZERO - multiplexación de E/S síncrona

SINOPSIS /* Según POSIX 1003.1-2001 */

#include %lt;sys/select.h%gt;

/* Según estándares anteriores */

#include %lt;sys/time.h%gt;

#include %lt;sys/types.h%gt;

#include %lt;unistd.h%gt;

int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

FD_CLR(int fd, fd_set *set);

FD_ISSET(int fd, fd_set *set);

FD_SET(int fd, fd_set *set);

FD_ZERO(fd_set *set);

DESCRIPCIÓN

Las funciones select espera a que un número de descriptores de fichero cambien de estado.

Usa un plazo de espera (timeout) que es de tipo struct timeval (con segundos y microsegundos).

Puede actualizar el parámetro timeout para indicar el tiempo sobrante.

Se miran tres conjuntos independientes de descriptores. Aquéllos listados en readfds serán observados para ver si hay caracteres que llegan a estar disponibles para lectura, aquéllos en writefds serán observados para ver si una operación de escritura no se bloqueará, y aquéllos en exceptfds serán observados para ver si ocurren excepciones. En caso de Éxito, los conjuntos se modifican en marcha para indicar qué descriptores cambiaron realmente su estado.

Cuatro macros para manipular los conjuntos. FD_ZERO limpiará un conjunto. FD_SET y FD_CLR añaden o borran un descriptor dado a o de un conjunto. FD_ISSET mira a ver si un descriptor es parte del conjunto; esto es útil después de que select regrese.

n es el descriptor con el número más alto en cualquiera de los tres conjuntos, más 1.

timeout es un límite superior de la cantidad de tiempo transcurrida antes de que select regrese. Puede ser cero. Si timeout es NULL (no hay tiempo de espera), select puede bloquear indefinidamente.

El plazo de espera o timeout tiene el siguiente aspecto

struct timeval {

long tv_sec; /* segundos */

long tv_usec; /* microsegundos */

};

VALOR DEVUELTO

Éxito à número de descriptores contenidos en los conjuntos de descriptores, que puede ser cero si el tiempo de espera expira antes de que ocurra algo interesante.

Error à -1, y se pone un valor apropiado en errno; los conjuntos y timeout estarán indefinidos, así que no confié en sus contenidos tras un error.

ERRORES

EBADF Se ha dado un descriptor de fichero inválido en uno de los conjuntos.

EINTR Se ha capturado una señal no bloqueante.

EINVAL n es negativo o el valor contenido en timeout no es válido.

ENOMEM select no ha sido capaz de reservar memoria para las tablas internas.

EJEMPLO

#include %lt;stdio.h%gt;

#include %lt;sys/time.h%gt;

#include %lt;sys/types.h%gt;

#include %lt;unistd.h%gt;

int

main(void) {

fd_set rfds;

struct timeval tv;

int valret;

/* Mirar stdin (df 0) para ver si tiene entrada */

FD_ZERO(&rfds);

FD_SET(0, &rfds);

/* Esperar hasta 5 s */

tv.tv_sec = 5;

tv.tv_usec = 0;

valret = select(1, &rfds, NULL, NULL, &tv);

/* ¡No confiar ahora en el valor de tv! */

if (valret)

write(1,"Los datos ya están disponibles.\n", 33);

/* FD_ISSET(0, &rfds) será verdadero */

else

write(1,"Ningún dato en 5 segundos.\n", 27);

return 0;

}

OBSERVACIONES

fd_set es un buffer de tamaño fijo. Ejecutar FD_CLR o FD_SET con un valor de fd que sea negativo o igual o mayor que FD_SETSIZE tendrá un comportamiento indefinido.

Referencia

Manuales: https://launchpad.net/ubuntu/hardy/+package/manpages-es

No hay comentarios:

Publicar un comentario