Como os aplicativos do Mac conseguem rastrear a localização de um arquivo?

18

Observo comportamento como este no meu Mac:

  • Abra um PDF com PDF Expert, faça algumas alterações no arquivo, mova o arquivo no Finder, salve-o no PDF Expert e ele será salvo corretamente no novo local.
  • Abra um shell em um diretório como ~/foo , limpe o diretório com outro aplicativo e o pwd do shell exibirá corretamente ~/.Trash/foo .

O que está acontecendo sob o capô? Esses casos parecem indicar que os aplicativos não apenas mantêm um caminho absoluto do arquivo como o emacs (estou certo disso?), Ou é um mecanismo totalmente diferente?

    
por nichijou 08.11.2017 / 08:34

3 respostas

21

macos tem um sistema /.vol/ especial mapeado para o diretório e arquivos reais. Os arquivos e diretórios estão acessíveis via /.vol/<device_id>/<inode_number> , independentemente de onde os arquivos estão no sistema de arquivos.

É um pequeno sistema legal.

Assim, os programas podem, por exemplo, obter o número de inode de /Users/jdoe/someFile.txt e depois abri-lo via /.vol/12345/6789 (neste caso, o id do dispositivo é 12345 e o número do inode 6789). Você então move /Users/jdoe/someFile.txt em qualquer lugar que quiser (no mesmo volume) e tudo simplesmente funciona. Você pode até escrever um script de shell que suporte este magic .

ls -di <file> para obter o número do inode.

$ ls -di /User/jdoe/someFile.txt
6789 /User/jdoe/someFile.txt

EDITAR:

Você usa stat para obter o id do volume e o número do inode, de acordo com a resposta vinculada, conforme destacado pelo IMSoP.

GetFileInfo /.vol/12345/6789 retornaria a localização atual do arquivo localizado anteriormente em /Users/jdoe/someFile.txt .

Veja link para mais informações.

    
por 08.11.2017 / 09:04
1

A resposta abaixo é falsa (ver comentários). Por favor, ignore

Além da boa resposta dada pela thecarpy, é provável que seus programas simplesmente mantenham um arquivo handle , que é independente da localização dos arquivos na árvore de diretórios (e em sistemas Unix até persistem a exclusão do arquivo, pelo menos até você fechá-lo).

Um identificador de arquivo é basicamente o acesso direto ao arquivo, independente de onde ou com que frequência (no caso de hardlinks) ele existe na estrutura de diretórios.

    
por 08.11.2017 / 17:52
0

Embora eu não tenha certeza do porque o macos usa isso em vez da funcionalidade padrão C, assumindo que o que eu li anos atrás em "Mac OS X Unleashed" está correto, descobri que aprendi algo novo.

Por favor, olhe o seguinte programa C simples:

#include <stdio.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
    struct timespec ts;
        ts.tv_sec = 10;
        ts.tv_nsec = 0;
    FILE * fp;

    fp = fopen("file.txt", "a");
    int f = fileno(fp);

    if (fp == NULL)
    {
        printf("Error opening file!\n");
        exit(1);
    }

    struct stat file_stat;
    int ret;
    ret = fstat (f, &file_stat);
    printf("inode number is %d\n", file_stat.st_ino);
    nanosleep(&ts, NULL);

    printf("Finished sleep, writing to file.\n");

/* print some text */
    const char *text = "Write this to the file";
    dprintf(f, "Some text: %s\n", text);

/* print integers and floats */
    int i = 1;
    float py = 3.1415927;
    dprintf(f, "Integer: %d, float: %f\n", i, py);

/* printing single characters */
    char c = 'A';
    dprintf(f, "A character: %c\n", c);

    close(f);
}

Compile o programa, execute-o em segundo plano e rapidamente mv file.txt file2.txt BEFORE o programa imprime "Finished sleep, writing to file". (você tem 10 segundos)

Observe que file2.txt tem a saída do seu programa, embora tenha sido movido antes do texto ser impresso no arquivo (via descritor de arquivo).

$ gcc myfile.c
$ ./a.out &
[1] 21416
$ inode number is 83956
$ ./mv file.txt file2.txt
$ Finished sleep, writing to file.
[1]+  Done                    ./a.out
$ cat file2.txt
Some text: Write this to the file
Integer: 1, float: 3.141593
A character: A

ISENÇÃO DE RESPONSABILIDADE: Eu não cortei a lista "include", que foi rapidamente hackeada para provar um ponto.

    
por 13.11.2017 / 10:11