C: Checar se arquivos de entrada e saída são diferentes

Palavras-chave: C, stdin, stdout, descritor, descriptor, inode, comparar, compare

Ao escrever filtros (programas que processam dados provenientes da entrada padrão e os escrevem na saída padrão) pode-se querer evitar que o arquivo de entrada seja o mesmo arquivo utilizado para saída. Um exemplo de um programa assim seria um conversor de formato: o que fazer caso o filtro seja invocado como

        $ gif2png < tempfile > tempfile

ou ainda

        $ sig2uns tempfile > tempfile

potencialmente corrompendo dados quando eles são lidos e processados em blocos?

Uma solução simples em sistemas que utilizam sistemas de arquivo similares aos do UNIX é comparar o número do inode e o dispositivo dos descritores de entrada e saída, sejam eles arquivos ou stdin/stdout. Isso pode ser implementado em C como:

        fstat(ifd, &st);
        st.st_mode &= S_IFMT;
        if (st.st_mode != S_IFCHR && st.st_mode != S_IFBLK) {
                dev = st.st_dev;
                ino = st.st_ino;
        }

        fstat(ofd, &st);
        st.st_mode &= S_IFMT;
        if (st.st_dev == dev && st.st_ino == ino) {
                /* entrada e saída são iguais */
                return 1;
        }

Isso é exatamente o que o programa “cat” faz. Se você experimentar fazer cat de um arquivo para ele mesmo, o resultado é:

        $ cat a.out > a.out
        cat: a.out: input file is output file

Finalmente, note que isso não vale para dispositivos de caractere ou bloco, como tratado no trecho de código acima.

This entry was posted in C. Bookmark the permalink.