Estos días a varios de mis alumnos les ha surgido la necesidad de probar la existencia de un archivo haciendo la llamada al sistema open(). Es bastante sencillo, sólo hay que probar si éste se ha podido abrir (como lectura, por ejemplo, para no tocar el fichero en la medida de lo posible).
Una vez se abre el fichero pueden ocurrir varias cosas:
- que la llamada a open() no devuelva error. Por tanto el fichero existe
- que la llamada a open() de error:
- si el resultado de errno es ENOENT (constante de error), ENOFILE en algunos sistemas o 2 (valor que generalmente vale dicha constante), el fichero no existe
- si el resultado de errno es distinto, no podemos asegurar que no exista, pero tal vez el nombre de fichero no sea correcto, la ruta no exista, o no tengamos acceso a él.
Para contemplar estos casos creamos la función exists(). Incluyo la función y el código de ejemplo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| /**
*************************************************************
* @file exists.c
* @brief Verifica la existencia o no de un fichero
*
* @author Gaspar Fernández <blakeyed@totaki.com>
* http://totaki.com/poesiabinaria/algoritmos/
*************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
short exists (char *fname )
{
int fd =open (fname , O_RDONLY );
if (fd <0) /* error */
return (errno ==ENOENT )?-1:-2;
/* Si no hemos salido ya, cerramos */
close (fd );
return 0;
}
int main (int argc , char *argv [])
{
int abre =exists ("archivo");
switch (abre )
{
case 0: printf ("El archivo existe\n"); break;
case -1: printf ("El archivo no existe\n"); break;
case -2: printf ("Ocurrió un error al abrir. %d (%s)\n", errno , strerror (errno )); break;
default: printf ("Nunca veremos este mensaje");
}
return EXIT_SUCCESS ;
} |
Descargar: exists (1Kb)
Para ejecutarlo podemos probar:
$ ./exists
El archivo no existe
$ touch archivo
$ ./exists
El archivo existe
$ chmod -r archivo # Eliminamos permiso de lectura al fichero
$ ./exists
Ocurrió un error al abrir. 13 (Permission denied)
Puede que también seas de los que piensan que si hay algún error al abrir el archivo, da igual, lo marcamos como no existente, de todas formas no podemos hacer nada con él. Así, construimos una función exists() más intuitiva que devuelve 1 cuando existe y 0 cuando no existe o hay error:
1 2 3 4 5 6 7 8 9
| short exists(char *fname)
{
int fd=open(fname, O_RDONLY);
if (fd<0) /* error */
return 0;
/* Si no hemos salido ya, cerramos */
close(fd);
return 1;
} |
Categories: C/C++, Clases particulares, algoritmos Tags: close, enoent, enofile, exist, file, Linux, llamada, open, rdonly, sistema, unix
Hace más de un año que se estrenó la película, pero ahora es cuando decido incluirla aquí, que tengo capturas y tiempos concretos:
En el minuto 11 segundo 25 podemos ver el primer regalo… GNU/EMACS !!

y para los que no sepan lo que es capaz de hacer Emacs… ahora lo vemos ejecutando un juego en Emacs lisp: hanoi-unix:

Aunque sólo sale un instante… igual que sólo sale durante un solo frame…

¡ Ubuntu !

Luego, alrededor del minuto 21 y durante casi un minuto podemos disfrutar de un sistema Unix con su terminal, y ejecutando comandos existentes, como top, uname, history, whoami, y dentro de history, se ve kill, ps, cat, vi, en fin… algo que nos suena y no suele salir en una película estadounidense…
Encontráis más información sobre los guiños a GNU/Linux o Unix en la película en estos enlaces:
Tron Legacy, ¿qué sistema operativo usaba Flynn?
La veracidad UNIX de Tron Legacy
En la serie Alias, en el episodio 11 de la segunda temporada “Un Escalón Más Alto”, o “A Higher Echelon”, podemos ver este fotograma (casi en el minuto 17), en el que vemos un escritorio KDE y una terminal abierta.
Por otra parte, a lo largo del capítulo, se pueden ver varias pantallas como esta, en las que de fondo, si entornamos un poco los ojos, se está compilando con cc y con un argumento: “-D_GNU_SOURCE

Fuente: http://groups.google.com/group/comp.windows.x.kde/msg/3100d0f3062fac2a
Categories: General, Linux On Movies/TV Tags: alias, compilación, consola, garner, gnu, jeniffer, kde, serie, television, unix
Muchos medios de comunicación y blogs ( 1, 2, 3, 4, 5 por ejemplo ) ya informaron de la noticia. Es una lástima que una de las grandes mentes del siglo XX y parte del XXI pasara tan desapercibida, y es que nos enteramos de la noticia hace 3 días habiendo sucedido hace una semana. Y es que sin él, este blog no existiría (C / C++ / PHP (hecho en C) / Linux (tipo Unix)), tal vez muchas de las cosas que hacemos en el ordenador no serían posibles, a lo mejor ni tendríamos ordenadores en casa, ni MP3, ni gadgets, ni smartphones, tal vez sea demasiado decir, puede que en un mundo paralelo todo esto exista sin su aportación lo que es seguro es que nada de esto sería como lo conocemos.
Dennis Ritche dejó su huella en el mundo de la informática, y una gran huella, si pudiéramos contar cuánto tiempo invirtió en su vida aprendiendo todo lo que tuvo que aprender y trabajando en su legado a la humanidad y todo el tiempo que el resto de la humanidad ha invertido utilizándolo estaríamos ante una persona situada en el Top 10 de la edad contemporánea. Desde aquí, le doy las gracias.
Después de enterarnos de esta pérdida, es inevitable compararla con la muerte de Steve Jobs, pocos días antes, alguien que sin duda, también ha hecho mucho por la tecnología, aunque se movieron en campos diferentes, uno nos proporcionó la base y las herramientas, otro utilizó esas herramientas para construir algo mayor y ver futuro en cosas que nadie consideraba útiles.
Y pensar que hace unos días estuve hablando de él en otro blog.
¡Descanse en paz Dennis Ritchie!
Cuando queremos representar un directorio; podemos obtenerlo de varias formas: /home/usuario/documentos en *nix o C:\Document and Settings\Usuario\Mis Documentos en Windows. Aunque lo mismo podemos representarlo /home/usuario/documentos/ y C:\Document and Settings\Usuario\Mis Documentos\ (es lo mismo, pero con una barra al final).
El problema en PHP, viene a la hora de llamar archivos de ese directorio, hay ocasiones en las que no sabemos si la variable en donde tenemos almacenado el directorio tiene barra al final o no; entonces debemos hacer alguna función que incluya la barra correspondiente si hace falta.
Estos dos primeros script los he sacado de Jonas John Code Snippets:
1 2 3 4 5 6 7 8 9 10 11 12
| function add_ending_slash ($path){
$slash_type = (strpos($path, '\')===0) ? 'win' : 'unix';
$last_char = substr($path, strlen($path)-1, 1);
if ($last_char != '/' and $last_char != '\') {
// no slash:
$path .= ($slash_type == 'win') ? '\' : '/';
}
return $path;
} |
1 2 3 4 5 6 7 8 9 10 11 12
| function normalize_path ($path){
// DIRECTORY_SEPARATOR is a system variable
// which contains the right slash for the current
// system (windows = \ or linux = /)
$s = DIRECTORY_SEPARATOR ;
$path = preg_replace('/[\/\\\]/', $s, $path);
$path = preg_replace('/'.$s.'$/', '', $path) . $s;
return $path;
} |
Para este último, tenemos que hacer antes:
1
| define("DIRECTORY_SEPARATOR", (PHP_OS=='Windows') ? '\':'/'; |
Otras dos alternativas:
1 2 3 4 5 6
| function ending_slash ($path)
{
$sep = (PHP_OS == 'Windows')? '\':'/';
$path .= (substr($path,-1) == $sep)? '':$sep;
return $path;
} |
1 2 3 4 5 6 7
| function ending_slash2 ($path)
{
$sep = (PHP_OS == 'Windows')? '\':'/';
if ($path)
$path .= ($path[strlen($path)-1] == $sep)? '':$sep;
return $path;
} |
La última no es muy elegante, pero ahí queda. Las dos últimas son muy parecidas entre sí. Y es una función interesante para nuestra biblioteca de funciones particular.
Últimos comentarios