#include <unistd.h>
char *getcwd(char *buf, size_t size);
현재 작업 디렉토리를 가져오는 함수
첫번째 인자는 경로가 저장되는 버퍼
버퍼가 NULL이면 getcwd는 malloc후 디렉토리 리턴
NULL이면 free필수
두번째 인자는 버퍼에 할당된 바이트 수
반환값
#include <stdio.h>
#include <unistd.h>
int main(void)
{
char path[1024];
printf("%s\n",getcwd(path, 1024));
}
실행하면 본인의 현재 디렉토리 경로가 출력된다.
현재 작업 디렉토리를 변경하는 함수
#include <unistd.h>
int chdir(const char *);
반환값
#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/achange dir name$..
0
/Users/{user}/Desktop
파일 정보를 읽어오는 함수들
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는 원본 정보를 채운다.
반환값은
#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");
}
파일이 잘 삭제된다
다른 프로그램을 실행시키는 함수
#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);
}
이런식으로 해주면 된다
코드 출처
파일 복제 함수
#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
프로그램내에서 프로세스들끼리 ipc통신을 할 수 있게 해주는 함수
하나의 파이프 혹은 2개의 fd 생성
하나의 파이프를 프로세스들이 공유한다
#include <unistd.h>
int pipe(int [2]);
인자
[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 testchild buffer:parent test
#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
파일 디스크립가 터미널을 참조하는지 확인하는 함수
#include <unistd.h>
int isatty(int fd);
반환값
터미널 이름을 반환하는 함수
#include <unistd.h>
char *ttyname(int fd);
프로그램이 참조하고 있는 터미널의 index를 반환하는 함수
#include <sys/ioctl.h>
int ioctl(int fd, unsigned long request, ...);
디바이스 제어하는 시스템 콜 함수
하드웨어를 제어하거나 상태정보를 확인할 수 있다.
#include <sys/ioctl.h>
int ioctl(int fd, unsigned long request, ...);
환경변수를 불러오는 함수
#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 - 터미널 속성값을 얻는 함수
#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);
#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);
이 함수들은 추가적으로 공부가 필요하다.
학습에 참고한 사이트
getcwd
chdir
stat, lstat, fstat
unlink
execve
pipe
opendir, readdir, closedir