๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
์ฒœ์ฒœํžˆ, ๊พธ์ค€ํžˆ../C

[C : ls] C์–ธ์–ด๋กœ ls ๊ตฌํ˜„ํ•˜๊ธฐ #dirent

by MIMI.L 2023. 12. 16.
๋ฐ˜์‘ํ˜•

ls๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ ํ•  dirent์— ๋Œ€ํ•ด ์•Œ์•„๋ด„

 

 

directory ๋ฅผ ์—ด๊ธฐ ์œ„ํ•ด opendir() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๋ฐ,

์–˜๋Š” ๋””๋ ‰ํ„ฐ๋ฆฌ๊ฒฝ๋กœ๋ฅผ ๋ฐ›๊ณ ,

๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์—ด ์ˆ˜ ์žˆ์œผ๋ฉด DIR *, ์—ด ์ˆ˜ ์—†์œผ๋ฉด NULL ๋ฐ˜ํ™˜

/* Open a directory stream on NAME.
Return a DIR stream on the directory, or NULL if it could not be opened.

This function is a possible cancellation point and therefore not marked with __THROW. */
extern DIR *opendir (const char *__name) __nonnull ((1));

 

DIR์€ ๋ญ์ง€ ?

/* This is the data type of directory stream objects.
The actual structure is opaque to users. */
typedef struct __dirstream DIR;

 

๋‹ค๋ฅธ ๋ธ”๋กœ๊ทธ ๊ธ€ ๊ฒ€์ƒ‰ ์‹œ, ํŒŒ์ผ ํฌ์ธํ„ฐ (FILE *) ์ฒ˜๋Ÿผ DIR *์€ ๋””๋ ‰ํ„ฐ๋ฆฌ ํฌ์ธํ„ฐ๋กœ ์ดํ•ดํ•˜๋ฉด ์ข‹์„๊ฒƒ ๊ฐ™๋‹ค๊ณ  ๋˜์–ด ์žˆ์Œ

(์ฐธ๊ณ  : https://eteo.tistory.com/180 )

 

๋””๋ ‰ํ„ฐ๋ฆฌ์˜ ์ •๋ณด๋“ค์„ ๋ฐ˜ํ™˜ํ•ด์ฃผ๋Š” ๊ฑธ๋กœ ์ดํ•ด์ค‘ !

๊ทธ๋Ÿผ ์ด๋ ‡๊ฒŒ ๋ฐ›์€ DIR *๋ฅผ ์–ด๋””์„œ ์“ฐ๋Š”์ง€ ?

dirent.h ํŒŒ์ผ์—์„œ ์ฐพ์•„๋ณด๋‹ˆ.. ์ด๋Ÿฐ๋ฐ์„œ ์“ฐ์ธ๋‹ค...

mimi@mimi:/usr/include$ grep -n "(DIR \*" dirent.h 
149:extern int closedir (DIR *__dirp) __nonnull ((1));
162:extern struct dirent *readdir (DIR *__dirp) __nonnull ((1));
165:extern struct dirent *__REDIRECT (readdir, (DIR *__dirp), readdir64)
173:extern struct dirent64 *readdir64 (DIR *__dirp) __nonnull ((1));
183:extern int readdir_r (DIR *__restrict __dirp,
190:                   (DIR *__restrict __dirp,
201:extern int readdir64_r (DIR *__restrict __dirp,
209:extern void rewinddir (DIR *__dirp) __THROW __nonnull ((1));
215:extern void seekdir (DIR *__dirp, long int __pos) __THROW __nonnull ((1));
218:extern long int telldir (DIR *__dirp) __THROW __nonnull ((1));
224:extern int dirfd (DIR *__dirp) __THROW __nonnull ((1));

 

๊ทธ๋ž˜์„œ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์ฝ์œผ๋ ค๋ฉด ? readdir() ์‚ฌ์šฉํ•˜๊ธฐ !

extern struct dirent *readdir (DIR *__dirp) __nonnull ((1));

 

readdir()์˜ ์ธ์ž๋กœ ์œ„์—์„œ opendir()์—์„œ ๋ฐ˜ํ™˜ํ•ด์ค€ DIR * ๊ฐ’์„ ๋„ฃ์œผ๋ฉด dirent ๊ตฌ์กฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ด์คŒ ! 

 

๊ทธ๋Ÿผ dirent๊ตฌ์กฐ์ฒด๋Š” ์–ด๋–ป๊ฒŒ ์ƒ๊ฒผ๋Š”๊ฐ€..

struct dirent
  {
#ifndef __USE_FILE_OFFSET64
    __ino_t d_ino;
    __off_t d_off;
#else
    __ino64_t d_ino;
    __off64_t d_off;
#endif
    unsigned short int d_reclen;
    unsigned char d_type;
    char d_name[256];		/* We must not include limits.h! */
  };

 

์ด๊ฑธ๋ณด๋‹ˆ.. d_type์€ ํŒŒ์ผ์˜ ํƒ€์ž…์ธ ๊ฒƒ ๊ฐ™๊ณ ,

d_name์€ ํŒŒ์ผ๋ช…์ธ ๊ฒƒ ๊ฐ™์Œ

 

while()์€ NULL์ด ๋‚˜์˜ค๊ธฐ ์ „๊นŒ์ง€๋งŒ ๋ฐ˜๋ณตํ•œ๋‹ค๊ณ  ํ•จ

readdir()์€ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ๋‹ค ์ฝ์œผ๋ฉด NULL์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค๊ณ  ํ•จ

๊ทธ๋ž˜์„œ while()์— ๋„ฃ์–ด๋‘๋ฉด ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ๋‹ค ์ฝ์„๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณตํ•˜๊ณ ,

๋ฐ˜๋ณตํ•˜๋ฉด์„œ d_name์„ ์ถœ๋ ฅํ•˜๋„๋ก ์•„๋ž˜์™€ ๊ฐ™์ด ๊ตฌํ˜„ํ•ด๋ดค์Œ 

#include <stdio.h>
#include <dirent.h>

int main() {
    
    struct dirent *dir;

    DIR *dp = opendir(".");
    if (dp == NULL) {
        return -1;
    }
    
    while (dir = readdir(dp)) {
        printf("%s  ", dir->d_name);
    }

    printf("\n");

    closedir(dp);
    
    return 0;
}

 

์ด๋ ‡๊ฒŒ ๊ตฌํ˜„ํ•˜๋ฉด ์ˆจ๊น€ํŒŒ์ผ๋„ ๊ฐ™์ด ์ถœ๋ ฅ๋จ

mimi@mimi:~/Mimi/lang/c$ ./ls
.vscode  ls.c  ..  .  .ls.c.swp  echo.c  clean  clean.c  TDL.c  ls

 

๊ทธ๋ž˜์„œ argv[1]์— a ์ž…๋ ฅ๋˜๋ฉด ์ˆจ๊น€ํŒŒ์ผ๋„ ์ถœ๋ ฅ๋˜๋„๋ก ์ˆ˜์ •ํ–ˆ์Œ !

#include <stdio.h>
#include <string.h>
#include <dirent.h>

int main(int argc, char* argv[]) {
    
    struct dirent *dir;

    DIR *dp = opendir(".");
    if (dp == NULL) {
        return -1;
    }
    
    while (dir = readdir(dp)) {
        if (argc == 1) {
            if (dir->d_name[0] == '.')
                continue;
            else
                printf("%s  ", dir->d_name);
        }
        else if (strchr(argv[1], 'a')) {
            printf("%s  ", dir->d_name);
        }
    }

    printf("\n");

    closedir(dp);
    
    return 0;
}

 

 

์‹คํ–‰ !

 

mimi@mimi:~/Mimi/lang/c$ ./ls
ls.c  echo.c  clean  clean.c  TDL.c  ls  

mimi@mimi:~/Mimi/lang/c$ ./ls -a
.vscode  ls.c  ..  .  .ls.c.swp  echo.c  clean  clean.c  TDL.c  ls
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€