Hard link files

C program which lists all the files of current working directory which contains hard link files - help is required for c program using system calls
Actually I am working on system calls programming on linux environment and need some help on those.

It is possible with stat (2) system call. If result of the call is a regular file and st_nlink field is greater than 1 it is a hard link.

Here an example code for you, just compile it and run with directory argument:

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

int main (int argc, char *argv[])
{
	if (argc != 2) {
		fprintf(stderr, "Usage: ./%s directory\n\n", argv[0]);
		exit(1);
	}
	const char *path = argv[1];
	DIR *dir = opendir(path);
	if (dir == NULL) {
		perror("Couldn't open dir");
		exit(1);
	}
	struct dirent *ent;
	struct stat st;
	char buf[1024];
	while ((ent = readdir(dir)) != NULL) {
		snprintf(buf, sizeof(buf), "%s/%s", path, ent->d_name);
		if (stat(buf, &st) < 0) {
			perror("stat");
			continue;
		}
		if (!S_ISREG(st.st_mode)) continue;
		if (st.st_nlink > 1) {
			printf("%s in %s is a hard link with refcount: %d\n", ent->d_name, path, st.st_nlink);
		}
	}
	closedir(dir); 
	return 0;
}

I agree with the logic. I come across readlink method also will show the links
Function: int readlink (const char *filename, char *buffer, size_t size)
if I am not wrong please suggest which one is best

1 Like

Hard links quite different from soft links.

readlink (2) just reads the path name of the related symbolic link, it is not related with hard links. You must use st_nlink field of the struct stat.

If you want to find hard links which points to same file, you have to analyze st_ino field of struct stat for every file in the whole mounted filesystem which includes your target file. If two files are hard link of the same file, their inode number must be same so st_ino fields must be equal.

Please note that, inode numbers valid only within the same mount point. If you have two partitions which one of them mounted under /home and other one mounted as /var, you can not compare files by inode number.

What happend, if the hard link points to a dev node or symbolic link? I think you should only check whether it is a direcory or not. If no, then check the nlink.