lunes, marzo 07, 2011

Algunas fotos de Ávila

Hace algunos días, estuve pasando el medio día y la tarde en Ávila. A pesar del frío y del cielo plomizo, justo al atardecer, y paseando por el paseo del Rastro, que discurre junto a la muralla en la zona que da hacía la Sierra de Gredos, pude sacar algunas fotografías que me gustaron bastante.

La primera foto que traigo es de la Iglesia de Santiago, de origen románico, y de su particular torre octogonal. Según la tradición, en la misma eran ordenados los caballeros de la Orden de Santiago.


Iglesia de Santiago, Ávila

Desde el mismo mirador, y aprovechando la luz del atardecer, saqué unas fotografías de la Sierra de Gredos que podía contemplarse desde el mismo. Había un poco de neblina, pero me sorprendió la calidez de la luz a esa hora


Gredos, envuelto por la neblina al atardecer

Con el sol casi puesto tras las montañas, saqué la siguiente foto, aunque me quedó algo oscuro el campo.


Gredos desde Ávila

Por último, dando un paso por el recinto amurallado, estuvimos por la plaza de Plaza de Pedro Dávila, donde realicé la siguiente foto. Me entretuve un rato tratándola con el Capture NX, y la verdad, respecto a la original, me gustó más como quedó el color.


Plaza de Pedro Davila

El resto de las fotos que me gustaron están en el álbum Ávila - Febreo 2011

Technorati Tags: ,

viernes, marzo 04, 2011

Sobre el ahorro de petróleo y teletrabajo

Es increible la de tonterías que se han oído durante la última semana respecto a las medidas que ha tomado el actual (des)gobierno para ahorrar combustible. Disminución de la velocidad máxima en autovías y autopistas, cambios de bombillas de alumbrado público, pensar en prohibir la circulación por los centros de las ciudades, con el petróleo a día de hoy a 115 dólares por barril - para los despistados, el barril de petróleo estuvo en el verano del 2008 a cerca de 139 dólares - todas pensadas de prisa y corriendo, sin pensar en las consecuencias.

Sin embargo, no veo a ningún lumbreras ministerial proponer una medida bastante simple: Teletrabajo. ¿Tanto cuesta?. A día de hoy, existe una red de banda ancha bastante decente en muchos sitios, el coste de los ordenadores no es excesivo,hay software de videoconferencias gratuitos, existe software que permiten establecer una VPN y programas que permiten implementar políticas de contra el robo de datos. Y mucho del trabajo que se realiza en el sector servicios en oficinas, puede hacerse desde casa con ayuda de estas herramientas sin ninguna dificultad. Si miramos en Internet, podemos ver como el hay diferentes proyectos de fuentes abiertas que no tienen ningún problema para coordinarse y funcionar con gente trabajando en todo el mundo. ¿Por qué es tan difícil que el teletrabajo se generalice en España?.

Podrían ponerse a hacer algunos cálculos de lo que se ahorraría si más gente teletrabajara: combustible o electricidad , así como de los beneficios para la conciliación de la vida laboral y familiar con la que tanto se le llena la boca a diferentes estamentos.

Technorati Tags: ,

sábado, febrero 12, 2011

Los problemas de readdir_r

Tradicionalmente, cuando se quiere leer un directorio en Unix, se usa las API opendir - para abrir un directorio -,readdir - para obtener una estructura dirent - y closedir - para terminar con el proceso de la estructura DIR - que nos devuelve opendir. Un código sencillo que usa estas función sería tal que así:

DIR *dir;
struct dirent *p;
if ((dir = opendir ("path_directorio"))!=NULL"){
        while ((p = readdir (dir))!=NULL){
                /*
                 Haz lo que quieras con las entradas
                 del directorio d->d_name
                */
                
        }
        closedir (dir);
}

Si nos fijamos en el código anterior, readir nos está devolviendo un puntero a una estructura que reserva el sistema y que es estática, es decir, que no podemos usar esa llamada en programas multihilos sin usar las correspondientes primitivas de sincronización que nos aseguren que sólo un hilo está está llamando a readdir en un momento determinado. Para evitar estas limitaciones, está la llamada readir_r, a la cual se le va a pasar un puntero a la estructura dirent y de esta manera nos aseguramos que sea reentrante, porque no depende de ningún bloque estático reservado por el sistema. El prototipo de la función para llamarla es tal como sigue

int readdir_r(DIR *restrict dirp, struct dirent *restrict entry, struct dirent **restrict result);

Sin embargo, buscando información en Internet di con readdir_r considered harmful y empecé a leerlo, el cual me puso sobre la pista de un tema muy curioso de la declaración de struct dirent. Esta estructura tiene un campo, d_name que va a ser rellenado por la función readline_r con el nombre de la entrada de directorio que vaya recorriendo. Pero claro, cada sistema de ficheros tienen una longitud de nombre distinta, y su miramos la especificación del Opengroup, no se especifica cual es la longitud máxima que debe de tener ese campo. Nos encontramos que en algunos sistemas, como por ejemplo Linux o MacOS X está declarado como char d_name[255], pero en otros como Solaris está declarado como d_name[1]. Así el siguiente código funcionará perfectamente en Linux o MacOS X y acabará con la pila sobreescrita en Solaris.
#include <dirent.h>
DIR *dir;
struct dirent dentry;
struct dirent *p;
if ((dir = opendir ("path"))!=NULL){
        while (readdir_r(dir,&dentry,&p)==0 && p!=NULL){
                /* usa la información de dentry */
        }
        closedir (dir);
}
Aparte, el autor de readdir_r considered harmful apunta a una condición de carrera que puede ocurrir si se usa fpathconf o pathconf con el parámetro _PC_NAME_MAX para obtener el tamaño máximo de un nombre en un directorio. Apunta a una posible solución que puede consultarse en el artículo enlazado para determinar cual debe de ser el tamaño de la estructura. Quizás la manera más rápida de obtener la longitud, supuesto que el sistema soporte la llamada dirfd que nos devuelve el descriptor de fichero asociado con el directorio abierto, sea usarla pasándole el valor de DIR * devuelto por opendir y luego llamar a fpathconf, pasando este descriptor y como segundo parámetro _PC_NAME_MAX. Además, hay que tener en cuenta el terminador de cadena y siempre reservar un poco más para estar en el lado seguro. Tal que así:
#include <dirent.h>
struct dirent *alloc_dirent (DIR *dir){
struct dirent *p = NULL;
int desc;long value;
if ((desc = dirfd (dir)!=-1){
        if ((value = fpathconf (desc,_PC_NAME_MAX)) != -1){
                /* Como mínimo 255 bytes*/
                value = max (value,255);
                p = malloc (value+sizeof (struct dirent)+1);
        }
}
return p;
}

Technorati Tags: ,

domingo, febrero 06, 2011

Macros en C con número variable de parámetros

A veces me he encontrado con la necesidad de realizar una macro que tenga un número variable de parámetros. ¿Cómo implementa esta funcionalidad el preprocesador de C?. Pues de la siguiente manera:

  • Usamos la elipsis (...) a la hora de definir en la macro, como si estuviésemos definiendo una función
  • Cuando queremos usar los parámetros libres usamos el identificador __VA_ARGS__, que el preprocesador sustituirá por los parémtros que se le han pasado a la macro.
Un ejemplo del uso de esta construcción puede verse en el siguiente fichero de cabecera:
#ifndef _DEBUG_H
#define _DEBUG_H 1
#ifdef DEBUG
        #define debug(format,...) output_debug (__FUNCTION__,__LINE__,format,__VA_ARGS__);
#else
        #define debug(format,params)
#endif
int output_debug (const char *funcname,unsigned int line,const char *format,...);
#endif

Existe un punto donde la anterior sintaxis puede dar problemas, como es el caso de que no se pase ningún parámetro a la macro: El estándar C obliga a que al menos un parámetro sea pasado a la elipsis para evitar dejar una coma colgada. El gcc tiene varias extensiones para tratar con este problema, mientras que el Visual C++, si no se pasan ningún argumento suprime la coma directamente. En el caso del gcc usa la siguiente construcción, que sólo es válida delante de una coma:

#define  debug  (format,...) output_debug (__FUNCTION__,__LINE__,format,##__VA_ARGS__);
En este caso los símbolos ## hace que se elimine la coma si no se pasan parámetros.

Referencias

  1. Variadic Macrod
  2. Variadic Macros (Visual Studio)

Technorati Tags:

viernes, febrero 04, 2011

¿Cómo se si un descriptor de fichero está conectado a una tty?

Aunque casi siempre que he programado en C lo he hecho bajo Unix, nunca he tocado esa parte que corresponde al uso de las tty. El sistema tiene una llamada que te dice si un sistema la tiene, que es isatty, pero antes de existir esta llamada había una manera más pedreste de conseguirlo, que la vi en una referencia del Advanced Programing in the Unix enviroment, y es intentar obtener las propiedades del descriptor a través de tcgetattr. Teniendo en cuenta que Stevens es un gran escritor, creo que voy a hacerme con el libro, porque el estilo de Stevens es altamente didáctivo. Lástima que nos dejara hace diez años.

#include <stdio.h>
#include <stdlib.h>
#include <termios.h>

int main (int argc,char **argv){
        struct termios ts;
        if (tcgetattr (fileno (stdin),&ts)!=-1){                 printf ("stdin is  a tty\n");
        }else{
                printf ("stdin is not a tty\n");
        }
}

Technorati Tags: