'IT'에 해당되는 글 24건

setsid() 함수를 호출 하는 이유.

IT/개발 노트


setsid를 하는 이유!

-fork로  생성된 자식 프로세스를 현재 세션과 무관하게 동작시키기 위함이다.



세션(session)이란? 

-프로세스 그룹들의 모임, 프로세스 그룹을 일종의 작업이라 하고, 세션은 일종의 작업 공간이다.



그 외 setsid()

- setsid를 호출한 프로세스는 새로운 하나의 세션을 만들고, 세션 리더가 된다.

  또한 세로운 세션 그룹을 만들고 그룹의 리더가 된다.


- setsid를 호출하여 새롭게 만든 세션은 제어 터미널을 가지고 있지 않다.


- 이미 프로세스의 그룹 리더인 프로세스는 호출 할 수 없다.



데몬프로세스를 만들때, while을 넣어주는 이유.

IT/개발 노트


데몬프로세스 만들때,


while을 넣어주는 이유는 프로세스를 계속해서 유지해주어야 하기 때문이다.


하지만 데몬프로세스를 만들때 while문을 넣지 않아도 $ps -ajx로 확인하면 

프로세스가 계속 목록에 남아 있는 것을 확인 할 수 있는데, 이유는 애초에 데몬프로세스는 부모를 죽이고 생성된 프로세스라, init에 연결되어 있어 죽지 않고 계속 떠있는것이다. 떠있지만, 아무일도 하지 못하는 프로세스가 된다.




IPC 선택

IT/개발 노트



※프로세스 동기화를 위한 것이라면


시그널


※동일한 시스템 내에서 메세지를 주고 받는 것이라면 


파이프


※ 서롣 라느 시스템에서 프로세스 끼리 메세지를 주고 받는 것이라면 


소켓



ls 명령어 구현 2단계, ls -alR 구현, 디렉토리 정보 출력-3

IT/프로그래밍 과제



2013/05/10 - [Programming/프로그래밍 과제] - ls 명령어 구현 2단계, ls -alR 구현, 디렉토리 정보 출력-2


2013/05/05 - [Programming/프로그래밍 과제] - ls 명령어 구현 2단계, ls -alR 구현, 디렉토리 정보 출력-1


지난 포스팅에서 간략하게 필요한 알고리즘과 동작 방식에 대해

대충 알아보았었는데, 이번 포스팅에선 직접 살펴보고 구현해 볼 것이다.

(아래 파일 다운로드를 할 수 있다.)


먼저 하위 디렉토리를 탐색하기 위해선, 

우선 디렉토리인자 판별하는 구문이 필요하다.


디렉토리 오픈 후, readdir 함수와 lstat 함수를 통해 파일들을 읽어 저장 한 뒤에

stat 구조체의 st_mode로 구별하면 쉽게 디렉토리인지 판별이 가능하다.


하지만, 지난 ls 명령어 구현에서 Info_st라는 사용자 구조체에 이미 파일에 대한 정보가 저장 하도록 구현했으니, 구조체에 저장된 정보로 판별하도록 코딩을 해 볼 것이다.


구조체에 저장된 정보로 디렉토리 인지 판별은 파일 퍼미션의 첫자리가 'd'이면 디렉토리이다. 그리고 현재와 상위 디렉토리를 제외하기 위해서 "." ".."을 제외시켜야 한다. 이유는 현재 디렉토리에서 하위 디렉토리를 찾기 위함이다.


이를 간단히 코딩해 보면, 

이 if문을 해석해 보면 사용자 구조체의 퍼미션 첫째자리가 'd'이고

사용자 구조체 파일이름이 ".." "."이 아니면 이다.


즉, 디렉토리 일때만 실행되게 한 것이다.


이제 사용자 구조체에 정의되어 있는 파일이름에 해당하는 path를

디렉토리를 탐색하는 함수에 인자로 넣어주어 호출하기면 하면 재귀적으로 동작 할 것이다.


하지만, 이 path를 만드는데 고민이 필요했었는데. 이유는 lstat으로 불러온 정보는

파일 이름만 있었기 때문에 파일 이름만 넘겨주면 path가 완성되지 않았었다.


이를 고치기 위해서 생각한 방법이 디렉토리 탐색 함수의 인자로 받은 path 뒤에

lstat으로 불러온 파일 이름을 이어 붙여주면 된다.


이동작을 수행하기 위해 ls -al 과제1 이후에 새롭게 추가된 함수가 있는데 바로

ReadPathAndFilenameCpy 함수이다. 원형과 내용을 살펴보도록 하자.

디렉토리 탐색함수의 인자인 dirname과 filename이란 char 포인터를 인자로 받는다.

filename은 lstat으로 얻은 파일 이름을 가리키는 포인터 이다.


함수를 살펴보면,

메모리 소비를 줄이기 위해 고정 버퍼를 사용하는게 아니라,

할당을 통해 동적으로 메모리를 할당하는 것을 볼 수가 있다.


만약 처음 지장한 maxPathLen크기보다 path가 커진다면 ExtenMem 함수를 통해서

메모리를 realloc함수를 통해 크기를 늘리게 된다. 


함수에 대해 간단히 설명하자면, 첫번째 while문에서 dirname을 복사하고,

if문을 통해 '/'을 어이 붙여준다. 그런 뒤 filename을 그 뒤에 이어 붙여주어서

절대Path를 반환하는 함수이다.


예를 들어 함수를 호출할 때,

dirname이 /etc이고 filename이 Consolekit이라면

함수를 통해 반환되는 path는 /etc/Consolekit 이라는 path가 만들어 진다.

이 path를 통해 다시 디렉토리탐색 함수의 인자로 넣어주면 반복적인 동작을 통해

하위 디렉토리까지 전부 탐색 출력하는 프로그램을 만들 수 있다.


ReadPathAndFilenameCpy처럼 ls -al 명령어 1단계 이후 새롭게 추가 된 함수가 있는데

ExtenMem 함수와 ReadString이라는 함수가 있다. 

ExtenMem함수는 위에 설명했듯 realloc을 통해 메모리를 재 확장하는 함수이고,

ReadString함수는 처음 디렉토리 path를 고정버퍼가 아닌 동적 할당을 통해 메모리 손실을 없애고자 만든 함수이다. 

함수는 동작원리는 ReadPathAndFilenameCpy와 비슷하니 이해하기가 쉬울 것이다.


작성한 프로그램 실행사진을 살펴보겠다.


명령어를 입력하면, 아래와 같이 하위디렉토리가 출력 되는 것을 볼 수 있다.

아래 작성한 코드를 다운 받을 수 있도록 해 두었습니다.

궁금하신 점이나, 문의가 있으시면 댓글 혹은 메일 주시면 답변 드리겠습니다.


위 코드는 제가 작성한 코드로 프로그램 코딩 및 정보 교환을 목적으로 

공유하니, 상업적인 용도로 사용하지 말아주셨으면 좋겠습니다.


그리고 저 또한 부족한 점이 많으니 좀 더 개선 될 수 있는 방향을 제시해 주신다면,

개선해 나가도록 노력하겠습니다. 감사합니다.


자세한 사항은 파일에 주석 처리 하도록 하겠습니다.



※ 다운로드 file

hw2.c

list.c

list.h

user.h



ls 명령어 구현 2단계, ls -alR 구현, 디렉토리 정보 출력-2

IT/프로그래밍 과제



2013/05/05 - [Programming/프로그래밍 과제] - ls 명령어 구현 2단계, ls -alR 구현, 디렉토리 정보 출력-1


지난번 포스팅에서 터미널에 ls -alR 을 쳐서 출력 결과를 살펴보았었다.

오늘은 동작에 관한 알고리즘을 생각해 볼 것이다.


1차 ls 명령어 구현에서는 단일 Linked List를 사용해서 ls명령어를 구현했었는데,

이번 하위디렉토리 출력도 같은 자료구조를 사용해서 구현할 것이다.


우선 지난 번 ls명령어 구현 동작을 살펴보면,

연결된 리스트 들을 관리하는 List가 있고, 

List에는 head, tail이 각각 Linked List들의  맨 앞과 뒤를 연결하고 있는 자료구조 형태이다. 

그리고 각각의 Listed List들에는 파일의 정보가 담겨있는 구조체 포인터를 가지고 있다.


ls -alR 명렁어는 파일 출력 순서대로 하위 디렉토리를 출력하는데,

이에 따른 알고리즘은 생각해 보면 간단하다.


처음 입력 받은 디렉토리 path값에 함수의 인자로 하위디렉토리 path를 인자로 넘겨주면 또 다시 위와 같은 출력을 할 수 있을 것이다. 


간단히 예를 들어 그림으로 보자면,

처음 입력 받았던 /etc를 자료구조에 모두 저장 한 뒤, 파일 이름순으로 정렬 후

연결된 리스트들의 맨 처음 부터 디렉토리인지 검사 한 뒤에


순차적인 검사를 통해 파일이 디렉토리이면 그 파일의 절대Path를 디렉토리 자료를 저장 정렬 출력하는 함수의 인자로 넘겨주면 위 그림과 같이 동작 할 수 있을 것이다. 

(자주 형광색이 디렉토리를 검사하고 다시 함수를 호출해서 가는 선이다)


그렇다면 우리가 원했던 재귀적인 동작으로 ls -alR 명령어를 구현 할 수 있다!!

생각보다 간단하다고 생각되지 않는가?


알고리즘과 동작 방법만 본다면 간단하다는 생각이 들 것이다. 

디렉토리 판별구문과 디렉토리Path를 넘겨주기만 한다면 재귀적으로 동작하여,

하위 디렉토리들을 전부 출력할 수 있을 테니 말이다.


하지만, 파일을 판별하는 것과 Path를 넘겨주는 부분에 신경써야할 부분이 있다.

실제로 이 부분이 생각지 못한 복병이 숨어있어 시간이 꽤 지체 되었었다.


다음 포스팅에서 ls -alR 하위디렉토리 정보까지 출력하는 데 

필요한 구문과 방법 및 코딩에 대해 알아 보도록 하자.




C언어 - 파일 정보 struct stat, 구조체

IT/C 언어

파일 정보를 저장하는 구조체


struct stat 구조체를 살펴 보면 다음과 같다.


struct stat {
     dev_t           st_dev;        /*ID of device containing file */

     ino_t            st_ino;          /*inode number*/

     mode_t       st_mode;     /*protection*/

     nlink_t         st_nlink;       /*number of hard links*/

     uid_t            st_uid;          /*user ID of owner*/

     gid_t            st_gid;          /*group ID of owner*/

     dev_t           st_rdev;        /*device ID (if special file)*/

     off_t             st_size;         /*total size, in byte*/

     blksize_t      st_blksize;    /*blocksize for file system I/O*/

     blkcnt_t       st_blocks;     /*number of 512B blocks allocated*/

     time_t;        st_atime;      /*time of last access*/

     time_t;        st_mtime;     /*time of last modification*/

     time_t         st_xtime;       /*time of last status change*/

};


파일 정보를 담는 stat구조체에서 각 필드들은 각각 의미가 있다.


  • st_dev         - 장치 파일의 위치 및 여부를 기술

  • st_ino          - 파일의 inode 번호

  • st_mode     - 파일의 모드를 다룸

  • st_nlink       - 파일의 하드링크 수

  • st_uid          - user ID 

  • st_gid          - group ID

  • st_rdev        - 장치 파일 (inode)를 기술

  • st_size         - 파일의 사이즈 

  • st_blksiez   - 효율적인 I/O 파일 시스템 위한 블럭 사이즈

  • st_blocks    - 파일에 할당한 블럭의 수


stat 구조체에서 각 필드들 주목할 만한 부분은 바로 3번째 필드인 st_mode이다.


st_mode에 따라서 파일의 종류를 알 수 있고, 파일의 퍼미션(permission)도 알 수 있다.



st_mode로 파일 종류를 알 수 있는데, 위의 매크로로 설정 되어 있는 (m)부분에 st_mode 값를 넣어 주기만 하면 된다.


아래 예를 들자면,


이런 형식으로 파일 종류를 알 수 있다.


매크로를 통해 알 수 있는 방법과, 비트 연산 ( |, & )을 통해 파일 종류 및 퍼미션 등을 알 수 있다.


예를 보면,


st_mode와 간단한 비트 연산을 통해서 파일에 대한 정보들을 알 수 있다.


상세한 정보는

#man stat 명령어 시 확인 할 수 있다.


C언어 - 파일 정보 읽기 함수 stat() ,lstat() ,fstat();

IT/C 언어

함수 원형 int stat(const char *path, struct stat * buf);

함수 원형 int lstat(const char *path, struct stat * buf);

함수 원형 int fstat(int fd, struct stat * buf);


stat, lstat, fstat 함수들은 모두 파일 정보를 읽어오는 함수이다.

모두 인트형 정수를 반환하며, fstat함수는 구조체 포인터 buf와 인수형 정수 fd를 인자로 받으며,

stat와 lstat 함수는 문자열 포인터, 구조체 포인터 buf를 인자로 받는다.


각 함수들의 두번째 인자 struct stat를 살펴보면

struct stat {
     dev_t           st_dev;        /*ID of device containing file */

     ino_t            st_ino;          /*inode number*/

     mode_t       st_mode;     /*protection*/

     nlink_t         st_nlink;       /*number of hard links*/

     uid_t            st_uid;          /*user ID of owner*/

     gid_t            st_gid;          /*group ID of owner*/

     dev_t           st_rdev;        /*device ID (if special file)*/

     off_t             st_size;         /*total size, in byte*/

     blksize_t      st_blksize;    /*blocksize for file system I/O*/

     blkcnt_t       st_blocks;     /*number of 512B blocks allocated*/

     time_t;        st_atime;      /*time of last access*/

     time_t;        st_mtime;     /*time of last modification*/

     time_t         st_xtime;       /*time of last status change*/

};

위와 같은 파일 정보들을 담은 구조체 임을 알 수 있다.


위 함수들은 헤더를 선언해 줘야 사용 할 수있는데, 헤더는 다음과 같다.

#include <sys/types.h>

#include <sys/stat.h>

#include <unistd.h>


반환값

-각 함수들의 호출 성공시 0을 반환하며 두번째 인자인 stat 구조체에 파일 정보들로 채워진다.

실패 혹은 에러시 -1을 리턴하고 에러시에 errno 변수에 에러 상태가 set된다.


사용법

함수 각 함수들의 사용법은,


stat과 lstat함수는 첫번째 인자로, 절대경로를 넘겨주어야 하고, 두번째 인자로 stat구조체 주소를 넘겨 주어야 한다.

위와 같이 ""를 사용하여 절대경로를 주어도 되고 문자열을 만들어 주소를 넘겨주어도 된다.


stat, lstat, fstat 함수는 모두 stat함수처럼 파일의 정보를 stat구조체에 채우는 것으로 동일하지만,

lstat함수는 stat와 다르게 한가지 경우를 제외한다.


lstat함수는 path가 심볼릭 링크 파일 경우, 심볼릭 링크 파일에 대한 정보를 구조제체 채운다.

(stat함수는  원본의 정보를 채운다.)


fstat함수는 stat, lstat와 첫 번째 인자가 다른데,

fstat함수는 첫번째 인자로 파일 디스크립터 번호를 인자로 받고 stat와 동일한 기능을 수행한다.

(여기서 파일 디스크립터 번호란, fileopen 등과 같이 open함수를 호출하면 생기는 번호이다.


자세한 사항은 

$man stat, $man lstat, $man fstat 세 가지 명령어 중 1가지를 통해 볼 수있다.


ls 명령어 구현 2단계, ls -alR 구현, 디렉토리 정보 출력-1

IT/프로그래밍 과제


ls 명령어는 옵션에 따라서 다양한 출력 방법으로 파일 정보를 출력하는데, 

이번 구현에 필요한 옵션은 지난번 -al 옵션에 -R 옵션을 붙인 것이다.


-a 숨김파일 표시

-l 파일의 자세한 정보

-R 하위디렉토리 파일 표시


우선 ls -alR이 어떤 방식으로 표현되는지 보기 위해 터미널에 "ls -alR"를 쳐 보았다.



ls 명령어에 -alR옵션을 주니, 


숨김파일표시, 파일 자세한 정보 표시가 하위디렉토리까지 표시되었다.

정렬에 대한 옵션은 주지 않아 파일 이름순으로 정렬되어 출력이 되었고,

이름순으로 정렬된 디렉토리 내용이 출력되었다.


(직접 터미널에 ls -alR을 쳐보시기 바랍니다.)


또 한가지 이번 구현에 따른 Mission이 주어졌는데,

ls 명령어 구현 2단계 Mission은 재귀적인 동작으로 ls 명령어를 동작하는 것이다.

즉, 자기자신의 함수를 호출하는 방식으로 동작하도록 코딩을 하는 것이다.


얼핏보면 재귀적이란 것에 대해 익숙한 사람이라면

간단해 보일 것 같은 문제일 것 같다.


구현에 있어, 생각만큼 간단하진 않았는데,

그 이유가 자잘한 오류가 많았다. 

차근차근 살펴보며 ls 명령어를 구현해 보기로 한다.


Linux/Ubuntu, ls 명령어 구현 1단계, 디렉토리 파일 정보 출력 code

IT/프로그래밍 과제


구현한 ls 명령어는 정확히 Linux/Unix에서 ls -al옵션을 구현한 것이다.

-a의 옵션은 숨긴파일도 표시하는 옵션이고, -l 옵션은 파일의 상세정보를 보는 옵션이다.


아래 코드는 스크린샷으로 공개하며,

첨부파일에 코드를 업로드를 할 것입니다.


필요하신분은 가져가서 쓰시되, 상업용으로 사용하지 말아주셨으면 좋겠습니다.

프로그래밍 공부를 하시는 분들게 좋은 자료가 되었으면 좋겠습니다.

자료를 퍼가실때 출처와 댓글에 퍼간다는 댓글 남겨주시는 센스 부탁드립니다.


이 코드는 제가 직접 과제를 진행하며 작성한 코드이며 ls 명령어의 정확한 답이 아님을 말씀드립니다.

코드에 대해 잘못된 부분이나 지적 사항등을 남겨주시면, 오히려 제가 더 감사하겠습니다.


궁금한점 있으시면 댓글 or 메일 주시면 답변 드리겠습니다.


 ※다운로드

Homework1.c

list.c

list.h

user.h






※파일 설명


파일은 Homework.c user.h list.c list.h 4가지 입니다.


사용한 자료구조는 단일 링크드 리스트이고, 정렬 방법은 버블정렬 입니다.


list.c list.h는 링크드 리스트 관련 함수 소스와 헤더파일로 mastering algorithm with c 책의 소스입니다.

링크드 리스트 관련 함수는 따로 사진은 올리지 안겠습니다.


user.h는 헤더파일들을 #include하고, 여러 #define 매크로들과 파일정보를 저장할 구조체 선언과

구현한 함수들이 선언되어 있습니다.


Homework.c파일은 메인 함수와 여러 함수들의 code가 있는 파일입니다.


1. user.h 파일


2. Homework.c 파일



 이전 ls 명령어 구현, 포스팅 보기

2013/04/28 - [Programming/프로그래밍 과제] - Linux/Ubuntu, ls 명령어 구현 1단계, 디렉토리 파일 정보 출력 -2


2013/04/27 - [Programming/프로그래밍 과제] - Linux/Ubuntu, ls 명령어 구현 1단계, 디렉토리 파일 정보 출력 -1








C언어 - 디렉토리 읽기 함수 readdir();

IT/C 언어


함수 원형 struct dirent * readdir(DIR * dirp);


디렉토리 포인터를 인자로 받고, 디렉토리의 정보를 읽어와 dirent라는 구조체에 값을 저장 후,

dirent 구조체 포인터를 반환한다.


struct dirent를 살펴보자.

struct dirent {

               ino_t                 d_ino;              /* inode number */

               off_t                 d_off;              /* offset to the next dirent */

               unsigned short  d_reclen;         /* length of this record */

               unsigned char   d_type;            /* type of file; not supported

                                                                    by all file system types */

               char                   d_name[256]; /* filename */

 };

위에서 부터 디렉토리의 아이노트 번호, 다음 dirent까지 옵셋, 레코드의 길이, 파일타입, 파일 이름이다.


Return value로,

 -디렉토리 읽기 성공시, dirent 구조체의 포인터를 반환한다. (따로 free해줄 필요가 없다)

 -디렉토리의 끝에 도달하거나 Error시에 NULL을 반환한다. (Error시에 해당 Error을 errno에 값이 저장된다)


사용 예를 보도록 하자.

readdir 함수는 읽기가 성공시 dirent라는 구조체의 포인터를 반환한다.

이 함수는 호출할 때마다 알아서 입력된 path에 정보들을 읽어온다.

따라서 입력 path의 끝에 도달하면 NULL을 반환하기 때문에, 위처럼 while 반복문에 조건문으로 사용된다.


사용 시 위의 예처럼 struct dirent * 변수를 선언해 주어야 하며,

dirent.h 헤더파일을 include 해주어야 한다.


아래 간단한 실행 예를 보자.


이처럼 파일의 끝에 도달할 때까지 입력 path의 정보를 읽어오는 것을 볼 수 있다.


$man readdir 입력 시 더 자세한 정보를 볼 수 있다.