Here is a string representation of a path. But tell me, is it a directory? is it a file? maybe it's a symlink? perhaps there is nothing there at all.
Well below is a helper method to find out exactly what it is.
get_inode_type
and uses a struct called inode_type
. inode
stands for Index Node.
An Index Node is used to store information about a file, directory, etc.. at a certain path.
The get_inode_type
method below will return a struct inode_type
if the path points to an existing inode. If
not it will return NULL
. As you will see in the test cases the inode_type
struct describes whether or not
the path points to a directory, file, or symlink. It also tells you if the symlink points to a directory or
file. Which is good to know.
Header
#ifndef INODE_TYPE_H
#define INODE_TYPE_H
#include <stddef.h>
typedef const char *Path;
typedef struct {
int is_file;
int is_dir;
int is_link;
} inode_type;
inode_type *get_inode_type(Path path);
#define INODE_TYPE_H
Implementation
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include "inode_type.h"
inode_type *get_inode_type(Path path) {
inode_type *type = malloc(sizeof(inode_type));
if(type == NULL) {
perror("malloc");
return NULL;
}
struct stat link_stat;
if(lstat(path, &link_stat) == -1) {
perror("lstat");
free(type);
return NULL;
}
type->is_link = S_ISLNK(link_stat.st_mode);
struct stat st;
if(stat(path, &st) == -1) {
perror("stat");
free(type);
return NULL;
}
type->is_dir = S_ISDIR(st.st_mode);
type->is_file = S_ISREG(st.st_mode);
return type;
}
Usage
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "inode_type.h"
int main() {
inode_type *test_dir = get_inode_type("./example_files");
inode_type *test_file = get_inode_type("./example_files/hello_world.txt");
inode_type *test_link = get_inode_type("./example_files/slink");
inode_type *test_empty = get_inode_type("/does/not/exist");
assert(test_dir->is_dir == 1);
assert(test_dir->is_file == 0);
assert(test_dir->is_link == 0);
assert(test_file->is_dir == 0);
assert(test_file->is_file == 1);
assert(test_file->is_link == 0);
assert(test_link->is_dir == 0);
assert(test_link->is_file == 1);
assert(test_link->is_link == 1);
assert(test_empty == NULL);
free(test_dir);
free(test_file);
free(test_link);
free(test_empty);
return 0;
}