<joke>
$ cat samefile.c
/* samefile -- decides whether two files given as arguments are the sa
+me.
follows symlinks. both files must be valid and you must have permissio
+n
to read them, and even then it may fail with an error or hang.
exit code 0 is same, 1 if different, higher on an error.
*/
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
int
main(int argc, char *argv[]) {
int d0, d1, sch;
struct flock lk;
pid_t ppa, pch;
if (3 != argc) return 10;
if (-1 == (d0 = open(argv[1], O_WRONLY))) return 4;
if (-1 == (d1 = open(argv[2], O_RDONLY))) return 3;
lk.l_type = F_WRLCK;
lk.l_whence = SEEK_SET;
lk.l_start = 0;
lk.l_len = 1;
if (-1 == fcntl(d0, F_SETLK, &lk)) return 5;
ppa = getpid();
if (-1 == (pch = fork())) return 9;
if (!pch) {
lk.l_type = F_RDLCK;
lk.l_whence = SEEK_SET;
lk.l_start = 0;
lk.l_len = 1;
if (-1 == fcntl(d1, F_GETLK, &lk)) return 4;
return !(F_WRLCK == lk.l_type && ppa == lk.l_pid);
} else {
if (pch != wait(&sch)) return 8;
if (!WIFEXITED(sch)) return 7;
return WEXITSTATUS(sch);
}
}
$ gcc -Wall -O -o samefile samefile.c
$ ./samefile /usr/local/libexec/git-core/git-{diff,pull}; echo $?
1
$ ./samefile /usr/local/libexec/git-core/git-{diff,commit}; echo $?
0
$
</joke>
$ test /usr/local/libexec/git-core/git-diff -ef /usr/local/libexec/git
+-core/git-pull; echo $?
1
$ test /usr/local/libexec/git-core/git-diff -ef /usr/local/libexec/git
+-core/git-commit; echo $?
0
NOTE: test -ef won't follow symlinks
Update: exercise to the reader: explain why the fork is necessary in the above program.