사용함수-3

hyenam·2021년 12월 6일
0

minishell

목록 보기
4/6

getcwd

#include <unistd.h>

char *getcwd(char *buf, size_t size);

현재 작업 디렉토리를 가져오는 함수

첫번째 인자는 경로가 저장되는 버퍼
버퍼가 NULL이면 getcwd는 malloc후 디렉토리 리턴
NULL이면 free필수
두번째 인자는 버퍼에 할당된 바이트 수

반환값

  • 디렉토리 리턴
  • NULL을 리턴하는 경우는 errno에 상세 오류 내용이 저장됨
#include <stdio.h>
#include <unistd.h>

int main(void)
{
	char path[1024];

	printf("%s\n",getcwd(path, 1024));
}

실행하면 본인의 현재 디렉토리 경로가 출력된다.

chdir

현재 작업 디렉토리를 변경하는 함수

#include <unistd.h>

int	 chdir(const char *);

반환값

  • 성공시 0
  • 실패서 -1
#include <stdio.h>
#include <unistd.h>
#include <readline/readline.h>

int main(void)
{
	char n_path[1024];

	printf("%d\n",chdir(readline("change dir route")));
	printf("%s\n",getcwd(n_path, 1024));
}

실행결과
change dir name$a
0
/Users/{user}/Desktop/test/a

change dir name$..
0
/Users/{user}/Desktop

stat, lstat, fstat

파일 정보를 읽어오는 함수들

fstat는 현재 열려진 파일의 정보를 읽어온다. (open함수를 써서 연 파일같은 거)

#include <sys/stat.h>

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는
첫번째 인자로 절대경로를 넘겨주어야 하고
두번째 인자는 stat구조체를 넘겨주어야 한다.

fstat은 첫번째 인자로 fd번호를 인자로 받고 stat와 동일한 기능을 수행한다.

stat구조체는 아래와 같이 되어있다.

#define __DARWIN_STRUCT_STAT64 { \
	dev_t		st_dev;                 /* [XSI] ID of device containing file */ \
	mode_t		st_mode;                /* [XSI] Mode of file (see below) */ \
	nlink_t		st_nlink;               /* [XSI] Number of hard links */ \
	__darwin_ino64_t st_ino;                /* [XSI] File serial number */ \
	uid_t		st_uid;                 /* [XSI] User ID of the file */ \
	gid_t		st_gid;                 /* [XSI] Group ID of the file */ \
	dev_t		st_rdev;                /* [XSI] Device ID */ \
	__DARWIN_STRUCT_STAT64_TIMES \
	off_t		st_size;                /* [XSI] file size, in bytes */ \
	blkcnt_t	st_blocks;              /* [XSI] blocks allocated for file */ \
	blksize_t	st_blksize;             /* [XSI] optimal blocksize for I/O */ \
	__uint32_t	st_flags;               /* user defined flags for file */ \
	__uint32_t	st_gen;                 /* file generation number */ \
	__int32_t	st_lspare;              /* RESERVED: DO NOT USE! */ \
	__int64_t	st_qspare[2];           /* RESERVED: DO NOT USE! */ \
}

세 함수 모두 읽은 파일을 구조체로 저장하지만

심볼릭 링크 파일일 경우
lstat는 심볼릭 링크 파일에 대한 정보를 채우고
stat는 원본 정보를 채운다.

반환값은

  • 성공시 0
  • 실패시 -1
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>

int main(void)
{
	struct stat *s;

	stat("/Users/hyenam/Desktop/test/a", s);
	printf("stat: %lld\n",s->st_size);
	lstat("/Users/hyenam/Desktop/test/a", s);
	printf("lstat:%lld\n",s->st_size);
	fstat(1, s);
	printf("fstat:%lld\n",s->st_size);
}

실행결과
stat: 4983531781430967689
lstat:4983531781430967689
fstat:4983531781430967689

#include <unistd.h>

int	 unlink(const char *path);

파일을 삭제하는 system call함수
하드링크를 생성하지 않은 파일은 바로 삭제되지만, 하드 링크가 있는 파일은 이름을 삭제하고 하드링크가 참조하는 카운트를 1감소시킨다. (하드링크의 카운트가 0이 되면 삭제)

하지만 open으로 파일을 연 경우 unlink를 사용해도 정보는 삭제되도 disk space는 해제되지 않음

즉, 하드 링크 참조 카운트와 파일 open카운트가 0일때에만 disk space를 해제한다.

인자는 상대경로 값을 입력

#include <stdio.h>
#include <unistd.h>
#include <readline/readline.h>
#include <sys/stat.h>

int main(void)
{
	unlink(readline("Delete file path:"));
	printf("Done\n");
}

파일이 잘 삭제된다

execve

다른 프로그램을 실행시키는 함수

#include <unistd.h>

int execve(const char *pathname, char *const argv[], char *const envp[]);

현재 실행중이던 걸 종료시키고 새로운 프로그램을 실행시킴

//test.c
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    printf("Hello World!\n");
    exit(EXIT_SUCCESS);
}
// main.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <readline/readline.h>

int main(void)
{
	execve(readline("file path:"), NULL, NULL);
	exit(EXIT_FAILURE);
}

실행
file path:./a.out
Hello World!

인자를 넣어줄때는

/* myecho.c */

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    for (int j = 0; j < argc; j++)
        printf("argv[%d]: %s\n", j, argv[j]);

    exit(EXIT_SUCCESS);
}
/* execve.c */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    char *newargv[] = {NULL, "hello", "world", NULL};
    char *newenviron[] = {NULL};

    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s <file-to-exec>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    newargv[0] = argv[1];

    execve(argv[1], newargv, newenviron);
    perror("execve"); /* execve() returns only on error */
    exit(EXIT_FAILURE);
}

이런식으로 해주면 된다
코드 출처

dup, dup2

파일 복제 함수

#include <unistd.h>

int	 dup(int fd);
int	 dup2(int fd, int fd2);

둘의 차이점은 dup는 사용하지 않는 fd가 자동 지정되지만
dup2는 원하는걸로 지정 가능

fd값을 얻어야하기 때문에 파일을 오픈해서 써야함

#include <stdio.h>
#include <unistd.h>
#include <sys/fcntl.h>

int main(void)
{
	int fd1;
	int fd2;
	int fd3;

	fd1 = open("a",O_RDONLY);
	fd2 = dup(fd1);
	fd3 = dup2(fd2, 5);
	printf("fd1:%d fd2:%d\n", fd1, fd2);
	printf("fd3:%d\n", fd3);
	close(fd1);
	close(fd2);
}

실행결과
fd1:3 fd2:4
fd3:5

pipe

프로그램내에서 프로세스들끼리 ipc통신을 할 수 있게 해주는 함수

하나의 파이프 혹은 2개의 fd 생성
하나의 파이프를 프로세스들이 공유한다

#include <unistd.h>

int	 pipe(int [2]);

인자
[0]:데이터 입력을 받을 수 있는 파일 디스크립터
[1]:데이터 출력을 할 수 있는 파일 디스크립터

반환값

  • 성공시 0
  • 실패시 -1

파이프는 fork함수에 의해 복사가 되지 않는다
방향성이 존재하지 않는다
단방향통신이라 한쪽에서 읽기만 가능하고 한쪽에서는 쓰기만 가능하다

#include <stdio.h>
#include <unistd.h>
#include <sys/fcntl.h>

#define BUFFER 1024

int main(void)
{
	pid_t pid;
	int fd[2];
	char buffer[BUFFER];

	pipe(fd);
	pid = fork();
	if (pid > 0)
	{
		read(fd[0], buffer, BUFFER);
		printf("parent buffer:%s\n", buffer);
		write(fd[1], "parent test\n", 11);
		usleep(100);

	}
	else if (pid == 0)
	{
		write(fd[1], "child test\n", 11);
		usleep(100);
		read(fd[0], buffer, BUFFER);
		printf("child buffer:%s\n",buffer);
	}
}

실행결과
parent buffer:child test

child buffer:parent test

opendir, readdir, closedir

#include <dirent.h>

DIR *opendir(const char *);
struct dirent *readdir(DIR *)
int closedir(DIR *)

dirent 구조체

#define __DARWIN_STRUCT_DIRENTRY { \
	__uint64_t  d_ino;      /* file number of entry */ \
	__uint64_t  d_seekoff;  /* seek offset (optional, used by servers) */ \
	__uint16_t  d_reclen;   /* length of this record */ \
	__uint16_t  d_namlen;   /* length of string in d_name */ \
	__uint8_t   d_type;     /* file type, see below */ \
	char      d_name[__DARWIN_MAXPATHLEN]; /* entry name (up to MAXPATHLEN bytes) */ \
}

opendir - 디렉토리 열기
readdir - 디렉토리 안에 있는 목록 읽기
closedir - 디렉토리 닫기

#include <stdio.h>
#include <unistd.h>
#include <dirent.h>
#include <readline/readline.h>


#define BUFFER 1024

int main(void)
{
	DIR *path = NULL;
	struct dirent *file;

	if (!(path = opendir(readline("input dir path:"))))
		printf("paht error\n");
	while(file = readdir(path))
		printf("name:%s\n",file->d_name);
	closedir(path);
}

실행결과
input dir path:a
name:.
name:..
name:a
name:b
name:c

isatty

파일 디스크립가 터미널을 참조하는지 확인하는 함수

#include <unistd.h>

int isatty(int fd);

반환값

  • 성공시 1반환
  • 실패시 0반환

ttyname

터미널 이름을 반환하는 함수

#include <unistd.h>

char *ttyname(int fd);

ttyslot

프로그램이 참조하고 있는 터미널의 index를 반환하는 함수

#include <sys/ioctl.h>

int ioctl(int fd, unsigned long request, ...);

ioctl

디바이스 제어하는 시스템 콜 함수

하드웨어를 제어하거나 상태정보를 확인할 수 있다.

#include <sys/ioctl.h>

int ioctl(int fd, unsigned long request, ...);

getenv

환경변수를 불러오는 함수

#include <stdlib.h>

char *getenv(const char *name);
#include <stdio.h>
#include <stdlib.h>
#include <readline/readline.h>

int main(void)
{
	printf("%s\n", getenv(readline("input env:")));
}

실행결과
input env:USER
hyenam

tcsetattr, tcgetattr

tcsetattr - 터미널 속성값을 변경시켜주는 함수
tcgetattr - 터미널 속성값을 얻는 함수

#include <termios.h>
#include <unistd.h>

int tcgetattr(int fd, struct termios *termios_p);
int tcsetattr(int fd, int optional_actions, const struct termios *termios_p);

tgetent, tgetflag, tgetnum, tgetstr

#include <curses.h>
#include <term.h>

int tgetent(char *bp, const char *name);
int tgetflag(char *id);
int tgetnum(char *id);
char *tgetstr(char *id, char **area);
  • tgetent - name에 해당하는 터미널 엔트리를 불러오는 루틴이다.
  • tgetflag - tgetflag 루틴은 id에 대한 boolean 항목을 가져오거나, 사용할 수 없는 경우 0을 가져옵니다.
  • tgetnum - tgetnum 루틴은 ID에 대한 숫자 항목을 가져오고, 사용할 수 없는 경우 -1을 가져옵니다.
  • tgetstr - tgetstr 루틴은 id에 대한 문자열 항목을 반환하고, 사용할 수 없는 경우 0을 반환합니다. tput을 사용하여 반환된 문자열을 출력합니다. 반환 값도 영역별로 가리키는 버퍼에 복사되고 영역 값이 이 값을 끝내는 null을 가리키도록 업데이트됩니다.

이 함수들은 추가적으로 공부가 필요하다.


학습에 참고한 사이트

getcwd

chdir

stat, lstat, fstat

unlink

execve

pipe

opendir, readdir, closedir

profile
공부한 걸 정리하고 있습니다.

0개의 댓글