#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
int main() {
DIR *dp;
struct dirent *dent;
dp = opendir(".");
while ((dent = readdir(dp))) {
printf("Name : %s ", dent->d_name);
printf("Inode : %d\n", (int)dent->d_ino);
}
closedir(dp);
}



์ข์! ์ฌ์ง ์ ์ฝ๋๋ ํ์ฌ ๋๋ ํฐ๋ฆฌ์ ํญ๋ชฉ(ํ์ผ/ํด๋)๋ค์ ์ฝ์ด์ ๊ฐ ํญ๋ชฉ์ ์ด๋ฆ๊ณผ inode ๋ฒํธ๋ฅผ ์ถ๋ ฅํ๋ ๊ฐ๋จํ C ํ๋ก๊ทธ๋จ์ด์ผ. opendir(".")๋ก ๋๋ ํฐ๋ฆฌ๋ฅผ ์ด๊ณ , readdir()๋ก ํญ๋ชฉ์ ํ๋์ฉ ์ฝ์ด ์ค๋ฉฐ, dirent ๊ตฌ์กฐ์ฒด์ d_name(์ด๋ฆ)๊ณผ d_ino(inode ๋ฒํธ)๋ฅผ ์ถ๋ ฅํด.
์๋์ ์ฌ์ง ์ ์ฝ๋ ์ฌ๊ตฌ์ฑ๋ณธ → ๋์ ์ค๋ช → ์๋ฌ ์ฒ๋ฆฌ/์ฌ์ฉ์ฑ ๋ณด๊ฐ ๋ฒ์ ์์๋ก ์ ๋ฆฌํ ๊ฒ.
1) ์ฌ์ง ์ ์ฝ๋ ์ฌ๊ตฌ์ฑ๋ณธ
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
// List directory entries and their inode numbers
int main(void) {
// directory stream pointer
DIR *dp;
// directory entry pointer
struct dirent *dent;
// open current directory
dp = opendir(".");
// read entries until NULL
while ((dent = readdir(dp))) {
// print file/dir name, inode number
printf("Name : %s", dent->d_name);
printf("Inode : %d\n", (int) dent->d_ino);
}
closedir(dp);
return 0;
}
โ ๏ธ ์ ์ฝ๋๋ “๊ทธ๋ฆผ์ ๋ณด์ด๋ ๊ทธ๋๋ก”์ ๊ฐ๊น๊ฒ ์ฎ๊ธด ๊ฒ์ด๊ณ ,
์ค๋ฅ ์ฒ๋ฆฌ(์: opendir ์คํจ, readdir ๋์ค ์ค๋ฅ, closedir ์คํจ) ๊ฐ ์๊ณ ,
inode ํ์ ์ถ๋ ฅ๋ ์์คํ ์ ๋ฐ๋ผ ํ๋ณํ์ด ๋ถ์ ํํ ์ ์์ด(์๋ ๋ณด๊ฐ ๋ฒ์ ์์ ๊ณ ์นจ).
2) ์ฝ๋๊ฐ ํ๋ ์ผ(์์ธ)
- opendir(".")
ํ์ฌ ๋๋ ํฐ๋ฆฌ๋ฅผ ๋๋ ํฐ๋ฆฌ ์คํธ๋ฆผ์ผ๋ก ์ฐ๋ค. ์คํจ ์ NULL์ ๋ฐํํ๋ค. - readdir(dp)
๋๋ ํฐ๋ฆฌ ์คํธ๋ฆผ์์ ๋ค์ ๋๋ ํฐ๋ฆฌ ์ํธ๋ฆฌ๋ฅผ ํ๋ ์ฝ๋๋ค.
์ฑ๊ณต ์ struct dirent*๋ฅผ ๋ฐํํ๊ณ , ๋์ด๋ ์ค๋ฅ ์ NULL์ ๋ฐํํ๋ค.
(๋๊ณผ ์ค๋ฅ๋ฅผ ๊ตฌ๋ถํ๋ ค๋ฉด errno๋ฅผ ํ์ธํด์ผ ํ๋ค.) - dent->d_name
ํญ๋ชฉ ์ด๋ฆ(์: ".", "..", "a.txt", "subdir" …). - dent->d_ino
๊ทธ ํญ๋ชฉ์ inode ๋ฒํธ. ํ์ผ ์์คํ ์์ ํ์ผ/๋๋ ํฐ๋ฆฌ๋ฅผ ์๋ณํ๋ ํต์ฌ ํค. - closedir(dp)
๋๋ ํฐ๋ฆฌ ์คํธ๋ฆผ์ ๋ซ๋๋ค. ์คํจ ์ -1์ ๋ฐํํ๋ค.
3) ๋ณด๊ฐ ๋ฒ์ (์๋ฌ ์ฒ๋ฆฌ + ์ถ๋ ฅ ํ์ ์์ + ๊ฒฝ๋ก ์ธ์ ์ง์)
๊ฐ์ ์
- opendir ์คํจ ์ ์๋ฌ ๋ฉ์์ง์ ์ข ๋ฃ.
- readdir ๋ฃจํ ์ข ๋ฃ ํ errno๋ก ์ค๋ฅ/์ ์ ์ข ๋ฃ ๊ตฌ๋ถ.
- closedir ๋ฐํ๊ฐ ํ์ธ.
- ๊ฒฝ๋ก ์ธ์๋ฅผ ๋ฐ์ ์ํ๋ ๋๋ ํฐ๋ฆฌ๋ฅผ ๋์ด ๊ฐ๋ฅ.
- ino_t ๋ ํ๋ซํผ๋ง๋ค ํฌ๊ธฐ๊ฐ ๋ค๋ฅผ ์ ์์ผ๋ฏ๋ก ์์ ํ ํ์ ์ง์ ์ ์ฌ์ฉ(uintmax_t๋ก ์น๊ฒฉ + %ju).
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <errno.h>
#include <inttypes.h> // for uintmax_t and %ju
#include <string.h>
int main(int argc, char *argv[]) {
const char *path = (argc >= 2) ? argv[1] : ".";
DIR *dp = opendir(path);
if (dp == NULL) {
fprintf(stderr, "opendir failed for '%s': %s\n", path, strerror(errno));
return EXIT_FAILURE;
}
errno = 0; // to distinguish end-of-dir vs error
struct dirent *dent;
while ((dent = readdir(dp)) != NULL) {
// inode (ino_t) -> uintmax_t ๋ก ์น๊ฒฉํด ์์ ํ๊ฒ ์ถ๋ ฅ
uintmax_t ino = (uintmax_t) dent->d_ino;
printf("Name : %s\n", dent->d_name);
printf("Inode: %ju\n", ino);
}
if (errno != 0) { // readdir๊ฐ NULL์ ๋ฐํํ๋๋ฐ errno๊ฐ 0์ด ์๋๋ฉด ์ค๋ฅ
fprintf(stderr, "readdir error on '%s': %s\n", path, strerror(errno));
closedir(dp); // ์๋๋ ํด๋ณธ๋ค
return EXIT_FAILURE;
}
if (closedir(dp) == -1) {
fprintf(stderr, "closedir failed for '%s': %s\n", path, strerror(errno));
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
์ ์ด๋ ๊ฒ ๊ณ ์ณค๋?
- opendir/readdir/closedir ์ค๋ฅ ์ฒ๋ฆฌ: ์ค๋ฌด/๊ณผ์ ์์ ํ์.
- ํ์ ์ง์ ์: ino_t๋ ์์คํ
๋ง๋ค unsigned long/unsigned long long ๋ฑ ๋ค๋ฅผ ์ ์์ด %d๋ ์ํ.
๊ฐ์ฅ ๋ณดํธ์ ์ผ๋ก uintmax_t๋ก ์บ์คํ + %ju ๊ฐ ์์ ํ๋ค. - ๊ฒฝ๋ก ์ธ์ ์ง์: ./prog /etc ์ฒ๋ผ ์ํ๋ ๋๋ ํฐ๋ฆฌ๋ฅผ ๋ฐ๋ก ์กฐํ ๊ฐ๋ฅ.
4) ์ปดํ์ผ & ์คํ ๋ฐฉ๋ฒ
# ๊ถ์ฅ(๊ฒฝ๊ณ +์ต์ ํ)
gcc -Wall -Wextra -O2 list_inodes.c -o list_inodes
# ์คํ: ํ์ฌ ๋๋ ํฐ๋ฆฌ
./list_inodes
# ์คํ: ๋ค๋ฅธ ๋๋ ํฐ๋ฆฌ
./list_inodes /etc
์ฐธ๊ณ ์ต์
- -Wall -Wextra : ์ผ๋ฐ/์ถ๊ฐ ๊ฒฝ๊ณ ํ์ฑํ (์ ์ฌ ๋ฒ๊ทธ ์กฐ๊ธฐ ๋ฐ๊ฒฌ)
- -O2 : ๋ณดํธ์ ์ธ ์ต์ ํ
- -g : ๋๋ฒ๊น ์ ๋ณด๋ฅผ ํฌํจํ๋ ค๋ฉด ์ถ๊ฐ
5) ์ถ๋ ฅ ์์(ํ์)
Name : .
Inode: 131073
Name : ..
Inode: 131072
Name : hw-04.c
Inode: 263201
Name : subdir
Inode: 263205
...
์๋๋ ๋๊ฐ ์์ฒญํ “./.. ๊ฑด๋๋ฐ๊ธฐ + ํ์ผ ์ข
๋ฅ(๋๋ ํฐ๋ฆฌ/์ผ๋ฐ ํ์ผ) ํ์ + ๊ถํ·ํฌ๊ธฐ๊น์ง ์ถ๋ ฅ” ๋ฒ์ ์ด์ผ.
์ค๋ฌดํ ๊ณผ์ ์์ค์ผ๋ก ๊ฐ์ ํ๊ณ , ๊ฐ ๋ถ๋ถ์ ์ฃผ์๊ณผ ์ค๋ช
๋ ๋ง๋ถ์์ด.
โ ์์ฑ ์ฝ๋: list_inodes_detailed.c
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <errno.h>
#include <sys/stat.h>
#include <inttypes.h>
#include <string.h>
#include <unistd.h>
// Function to print permission bits in rwx format
void print_permissions(mode_t mode) {
printf("%c", (mode & S_IRUSR) ? 'r' : '-');
printf("%c", (mode & S_IWUSR) ? 'w' : '-');
printf("%c", (mode & S_IXUSR) ? 'x' : '-');
printf("%c", (mode & S_IRGRP) ? 'r' : '-');
printf("%c", (mode & S_IWGRP) ? 'w' : '-');
printf("%c", (mode & S_IXGRP) ? 'x' : '-');
printf("%c", (mode & S_IROTH) ? 'r' : '-');
printf("%c", (mode & S_IWOTH) ? 'w' : '-');
printf("%c", (mode & S_IXOTH) ? 'x' : '-');
}
int main(int argc, char *argv[]) {
const char *path = (argc >= 2) ? argv[1] : ".";
DIR *dp = opendir(path);
if (!dp) {
fprintf(stderr, "โ opendir('%s') ์คํจ: %s\n", path, strerror(errno));
return EXIT_FAILURE;
}
printf("\n๐ Directory: %s\n", path);
printf("-------------------------------------------------------------\n");
printf("%-25s %-10s %-8s %-12s %-10s\n", "Name", "Inode", "Type", "Permissions", "Size");
printf("-------------------------------------------------------------\n");
errno = 0;
struct dirent *dent;
struct stat st;
char fullpath[1024];
while ((dent = readdir(dp)) != NULL) {
// Skip current (.) and parent (..)
if (strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0)
continue;
snprintf(fullpath, sizeof(fullpath), "%s/%s", path, dent->d_name);
if (lstat(fullpath, &st) == -1) {
fprintf(stderr, "โ ๏ธ lstat('%s') ์ค๋ฅ: %s\n", fullpath, strerror(errno));
continue;
}
// Determine file type
char type[16];
if (S_ISDIR(st.st_mode))
strcpy(type, "DIR");
else if (S_ISREG(st.st_mode))
strcpy(type, "FILE");
else if (S_ISLNK(st.st_mode))
strcpy(type, "LINK");
else
strcpy(type, "OTHER");
printf("%-25s %-10ju %-8s ", dent->d_name, (uintmax_t) dent->d_ino, type);
print_permissions(st.st_mode);
printf(" %-10ld\n", (long) st.st_size);
}
if (errno != 0) {
fprintf(stderr, "โ readdir() ์ค๋ฅ: %s\n", strerror(errno));
closedir(dp);
return EXIT_FAILURE;
}
if (closedir(dp) == -1) {
fprintf(stderr, "โ closedir('%s') ์คํจ: %s\n", path, strerror(errno));
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
โ๏ธ ์ปดํ์ผ & ์คํ
gcc -Wall -Wextra -O2 list_inodes_detailed.c -o list_inodes_detailed
./list_inodes_detailed
ํน์ ํน์ ๋๋ ํฐ๋ฆฌ ์ง์ :
./list_inodes_detailed /etc
๐ ์คํ ์์ ์ถ๋ ฅ
๐ Directory: .
-------------------------------------------------------------
Name Inode Type Permissions Size
-------------------------------------------------------------
list_inodes_detailed.c 263201 FILE rw-r--r-- 2496
hw-04 263205 DIR rwxr-xr-x 4096
readme.md 263210 FILE rw-r--r-- 1024
๐ ์ฝ๋ ์ค๋ช ์์ฝ
| opendir() | ์ง์ ํ ๊ฒฝ๋ก์ ๋๋ ํฐ๋ฆฌ๋ฅผ ์ฐ๋ค |
| readdir() | ๋๋ ํฐ๋ฆฌ์ ๊ฐ ์ํธ๋ฆฌ๋ฅผ ์ฐจ๋ก๋ก ์ฝ๋๋ค |
| lstat() | ํ์ผ์ ๋ฉํ๋ฐ์ดํฐ(ํฌ๊ธฐ, ๊ถํ, ์ ํ ๋ฑ)๋ฅผ ์ป๋๋ค |
| S_ISDIR / S_ISREG | ํ์ผ ํ์ ๋งคํฌ๋ก (๋๋ ํฐ๋ฆฌ / ์ผ๋ฐ ํ์ผ ๊ตฌ๋ถ) |
| st_mode | ๊ถํ ๋นํธ ๋ฐ ํ์ผ ์ ํ ์ ์ฅ |
| st_size | ํ์ผ ํฌ๊ธฐ(byte) |
| d_ino | inode ๋ฒํธ |
| print_permissions() | rwx ํ์์ผ๋ก ๊ถํ ๋นํธ ์ถ๋ ฅ |
๐ก ์ฐธ๊ณ : ํ์ฅ ์์ด๋์ด
- ์์ ์ถ๋ ฅ (๋๋ ํฐ๋ฆฌ=ํ๋, ์คํํ์ผ=์ด๋ก)
- ํ์ผ ์์ ์๊ฐ ํ์ (st_mtime ์ด์ฉ)
- ์จ๊นํ์ผ(.์ผ๋ก ์์) ํ์/์ ์ธ ์ต์
- ์ฌ๊ท ํ์ ๊ธฐ๋ฅ (nftw() ์ฌ์ฉ)
'6. CS ๊ธฐ์ด ๐ > Linux & Unix ๐ง' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [Linux/Unix][5-2] ํ๋ ๋งํฌ vs ์ฌ๋ณผ๋ฆญ ๋งํฌ (0) | 2025.10.21 |
|---|---|
| [Linux/Unix][5-1] stat ๊ตฌ์กฐ์ฒด์ ๋ฉค๋ฒ // st_mode (0) | 2025.10.21 |
| [Linux/Unix][4-2] inode์ ์ ๋ณด (0) | 2025.10.21 |
| [Linux/Unix][4-1] UNIX ํ์ผ ์ข ๋ฅ (0) | 2025.10.21 |
| [Linux/Unix][3-5] shift ๋ช ๋ น ํ๋ก๊ทธ๋จ (0) | 2025.10.21 |