2010-02-24 6 views
6

Escribo una herramienta (no) de archivo y la forma en que está diseñada primero crea un archivo regular del archivo antes de examinar los atributos especiales y puede decidir que esto el artículo es un enlace simbólico, de hecho.Cómo convertir un archivo normal en un enlace simbólico en Linux

Nota: Antes de que más personas me malinterpreten por querer hacer un enlace simbólico de un archivo. No, escribo los datos de enlace simbólico, es decir, su ruta, en el archivo, y luego deseo decirle al sistema de archivos que este es un enlace simbólico

Lo he estado desarrollando en OS X, donde es posible convertir un archivo regular en un enlace simbólico simplemente configurando sus códigos de Tipo y Creador en consecuencia.

Ahora me gusta que este código funcione en Linux también. Entonces me gusta encontrar una manera similar allí.

Soy consciente de que la forma normal de crear un enlace simbólico es llamar a la función symlink(), pero me pregunto si también hay una forma de convertir un archivo normal en un enlace simbólico, como es posible en el sistema BSD de OSX , para que no tenga que refactorizar mi código de trabajo demasiado?

Hay lstat(), que devuelve el tipo de archivo en los bits superiores de st_mode. Ahora me pregunto si también hay una función setter análoga para este campo de modo.

+0

Comprobando si lo entiendo: ¿desea transformar un archivo normal en un enlace simbólico que apunte a lo que contenía el archivo? –

Respuesta

4

No creo que haya una forma en Linux para hacer esto como usted lo describe. IIRC, el sistema de archivos almacena información de enlaces simbólicos en la tabla de inode y no en un archivo normal, por lo que no hay una forma directa de convertir un archivo en un enlace.

Si la ruta del enlace simbólico se almacena dentro del archivo, ¿por qué no lee la ruta, elimina el archivo y crea un enlace simbólico en su lugar?

+0

Acepto esta respuesta no por su sugerencia de trabajo bastante obvia, sino por la explicación de por qué no hay una manera de hacer lo que quería hacer. Espero que su explicación sea correcta :) –

1

No, no puede convertir una en la otra. Debes desvincular para eliminar el archivo y luego crear un enlace simbólico para crear un enlace simbólico como reemplazo.

+1

Sería mejor crear un enlace simbólico con un nombre diferente, luego renombrarlo sobre el archivo original. Este es un reemplazo atómico, y no habrá un espacio donde falte el nombre del archivo (como sucede después de su desvinculación). – ephemient

3

demostrando lo que escribí como un comentario a la respuesta de bmarguiles,

#include <fcntl.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <unistd.h> 
int main(int argc, char **argv) { 
    char *buffer = 0, *name = 0; 
    int i; 
    for (i = 1; i < argc; i++) { 
     struct stat st; 
     int fd = open(argv[i], O_RDONLY); 
     fstat(fd, &st); 
     buffer = realloc(buffer, st.st_size + 1); 
     read(fd, buffer, st.st_size); 
     close(fd); 
     buffer[st.st_size] = '\0'; 
     name = realloc(name, strlen(argv[i]) + 2); 
     sprintf(name, "%s~", argv[i]); 
     symlink(buffer, name); 
     rename(name, argv[i]); 
    } 
    free(buffer); 
    free(name); 
    return 0; 
} 
 
$ vi f2s.c 
... 
$ cc -o f2s f2s.c 
$ echo -n/> test 
$ ./f2s test 
$ ls -l test 
lrwxrwxrwx 1 me me 1 Feb 24 23:17 test ->/
$ echo -n/> test2 
$ strace ./f2s test2 
open("test2", O_RDONLY)     = 3 
fstat(3, {st_mode=S_IFREG|0644, st_size=1, ...}) = 0 
read(3, "/", 1)       = 1 
close(3)        = 0 
symlink("/", "test2~")     = 0 
rename("test2~", "test2")    = 0 

Esto es sólo una manifestación; realmente necesita más manejo de errores y tal vez un mejor nombre de archivo temporal.

+0

Tengo curiosidad por el uso de 'realloc()' sobre 'malloc()'? – SiegeX

+0

Principalmente porque soy flojo y solo me apetecía escribir un solo 'libre' al final. Este no es un código de calidad de producción. – ephemient

+0

No eres tan vago como crees, ya tienes dos 'free()' s =) – SiegeX

Cuestiones relacionadas