Open 함수
int open (const char *pathname, int flag, [mode_t mode]);
파일을 열고 File descriptor를 반환한다.
mode 속성은 새로운 파일을 열때에만 사용된다.
FLAGS
O_RDONLY, O_WRONLY, O_RDWR
O_CREAT : 파일이 없을 경우 생성한다.
O_EXCL: O_CREAT에 의해 파일이 생성될 때 파일이 존재할 경우 에러를 발생한다.
O_TRUNC: 파일이 이미 정해진 경우 버퍼를 덮어 씌운다.
O_APPEND: 처음 파일을 쓸때 파일 포인터를 마지막에 씌운다.
modes
O_CREAT 플래그가 있을 때만 사용되며 새로 만들어진 파일의 권한을 설정한다. 다른 경우엔 사용되지 않는다.
반환값
새로운 File discriptor를 반환하며 -1을 반환하면 오류가 발생한 것이다.
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int fd;
fd = open("/home/teach", O_WRONLY | O_TRUNC);
if(fd = -1) /* error */
Creat 함수
int open (const char *pathname, mode_t mode);
새로운 파일을 생성한다. 이 함수는 다음과 같다.
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open (const char *pathname, mode_t mode){
return open(name, O_WRONLY | O_CREAT | O_TURNC, mode);
}
반환값
open(name, O_WRONLY | O_CREAT | O_TURNC, mode)과 동일한 성질을 가진다.
예시코드
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int fd;
fd = creat(filename, 0664);
Close 함수
#include <unistd.h>
int close(int fd);
- File discriptor를 닫는다.
- 프로세스가 끝날대에는 모든 열려져있는 파일이 커널에 의해 자동으로 닫힌다.
Read 함수
#include <unistd.h>
ssize_t read (int fd, void *buf, size_t count);
- file discriptor로부터 count만큼의 버퍼를 buf에서 부터 읽어오길 시도한다.
- 만약 count가 0이라면 어떠한 값도 반환하지 않음
- 성공하면 몇바이트를 읽었는지 확인한다, 0은 파일의 마지막에 다다른것이고, -1반환시 에러가 발생한거다.
Write 함수
#include <unistd.h>
ssize_t_write(int fd, const void *buf, size_t count);
- 데이터를 쓸 fd 에 쓸 데이터 buffer*데이터를 쓸 데이터의 *count byte 만큼 입력해준다.
- 성공시 얼마의 바이트만큼 입력했는지 반환, 0은 아무것도 안써진 것이고, -1은 에러가 발생한거
EX1) Simple File I/O
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#define BSIZE 1024
#define FPERM 0644
int main(int argc, char *argv[])
{
int fd1, fd2, n;
char buf[BSIZE];
if (argc < 3)
{
fprintf(stderr, "Usage; %s src dest\n", argv[0]);
exit(1);
}
if ((fd1 = open(argv[1], O_RDONLY)) < 0)// 읽는 파일은 Readonly로 열람
{
perror("file open error");
exit(1);
}
if ((fd2 = open(argv[2], FPERM)) < 0)// 쓰는 파일은 쓸수있는 권한으로 열람
{
perror("file creation error");
exit(1);
}
while ((n = read(fd1, buf, BSIZE)) > 0)//fd1을 읽고 fd2에 씀
{
write(fd2, buf, n);
}
close(fd1);
close(fd2);
}
lseek 함수
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
File discriptor에 File pointer를 재위치 시켜준다.
SEEK_SET : 파일 시작위치로분터 얼마나 띄울것인가
SEEK_CUR: 현재 포인터 위치로부터 얼마나 띄울것인가
SEEK_END: 파일 끝에서 부터 얼마나 띄울것인가
Hole: 파일 끝부분보다 더 포인터를 이동시켰을때 비어있는 공간
성공시 처음 파일시작할때 부터 얼마나 띄웠는지 반환, 에러시 -1
EX2) lseek
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
char buf1[] = "abcdefghij";
char buf2[] = "ABCDEFGHIJ";
int main(void){
int fd;
if((fd = creat("file.hole", 0640)) < 0){//읽고 쓸수 있는 형태로 파일 열람
perror("creat error");
exit(1);
}
if(write(fd, buf1, 10) != 10){//buf1 쓰기
perror("buf1 write error");
exit(1);
}
if(lseek(fd, 40, SEEK_SET) == -1){//offset의 처음부터 40만큼 이동
perror("lseek error");
exit(1);
}
if(write(fd, buf2, 10) != 10){// 40에서 10만큼 이동하여 50 위치에 위치
perror("buf2 write error");
exit(1);
}
/*offset result = 50*/
exit(0);
}
Remove 함수
#include <stdio.h>
int remove (const char *path);
- System Call이 아닌 C라이브러리임
- pathname에 있는 파일을 삭제 시켜줌
- 성공시 0을, 에러시 -1을 반환함
fcntl 함수
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct lock *ldata);
File discriptor를 다루는 함수 = 파일의 속성을 바꿔줍니다.
fd에서 작동하는 잡다한 동작을 수행하는 함수
속성 설정에 대한 세부사항은 cmd를 토해 동작합니다.
F_GETFL: Discriptor의 flag를 읽어옵니다.
F_SETFL: 파일의 Flag를 지정된 속성으로 지정합니다., 다른 flag는 무의미 합니다.
성공시 0을 실패시 -1을 반환합니다.
EX3) fcntl
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
int accmode, val;
if (argc != 2)
{
fprintf(stderr, "usage:a.out <descriptor#>");
exit(1);
}
if ((val = fcntl(atoi(argv[1]), F_GETFL, 0)) < 0) //파일 fd1의 속성을 읽어 옵니다.
{
perror("fcntl error for fd");
exit(1);
}
accmode = val & O_ACCMODE; //해당 속성의 마스트를 씌웁니다.
if (accmode == O_RDONLY)//해당 파일이 어떤 속성인지 확인해봅니다.
printf("read only");
else if (accmode == O_WRONLY)
printf("write only");
else if (accmode == O_RDWR)
printf("read write");
else
{
fprintf(stderr, "unknown access mode");
exit(1);
}
if (val & O_APPEND)
printf(", append");
if (val & O_NONBLOCK)
printf(", nonblocking");
if (val & O_SYNC)
printf(". syschronous writes");
putchar('\n');
exit(0);
}
Dup & Dup2 함수
#include <unistd.h>
int dup(int oldfd);
int dup2(int oldfd, int newfd);
- oldfd의 File discriptor를 복사합니다.
- dup 함수는 기존의 fd를 복제하는 함수이다. 그래서 반환된 새로운 fd는 기존의 fd와 같은 파일을 가르키게 된다.
- dup2함수는 newfd함수를 oldfd함수로 복제하는 것으로 반환되는 newfd는 oldfd가 된다. 이때 newfd는 프로그래머가 원하는 번호로 지정 가능하다.
EX4) Dup
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#define BSIZE 80
int main(void){
int fd, newfd, n;
char buf1[BSIZE], buf2[BSIZE];
fd = open("/etc/passwd", O_RDONLY);
newfd = dup(fd);n = read(fd, buf1, BSIZE);
printf("Read from fd:\n\n");
write(STDOUT_FILENO, buf1, n);
n = read(newfd, buf2, BSIZE);
printf(“\n\nRead from newfd:\n\n”);
write(STDOUT_FILENO, buf2, n);
close(fd);
n = read(newfd, buf1, BSIZE);
printf("\n\nRead from newfd after close(fd):\n\n");
write(STDOUT_FILENO, buf1, n);
printf("\n");
close(newfd);
exit(0);
}
umask 함수
#include <sys/types.h>
#include <sys/stat.h>
mode_t unmask(mode_t mask);
- 파일이 생성되거나 관리될 때 파일이나 디렉토리가 불필요하게 많이 생성되지 않도록 통제하는 함수
- 통제가 필요한 권한이 설정되지 않도록 막아주는 역할을 한다.
- 정상적으로 기존에 설정되었었던 umask값을 반환한다 오류는 발생하지 않는다.
- 해당 설정은 프로세스가 생행되는 동안만 유지되며 프로세스가 종료되면 원래 값으로 돌아온다.
EX5) unmask
#include <stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main(void){
umask(0);
if (creat("foo", S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) < 0) {
perror("createrror for foo");
exit(1);
}//-rw-rw-rw-
umask(S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
if (creat("bar", S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) < 0) {
perror("createrror for bar");
exit(1);
}//-rw-------
exit(0);
}
access 함수
#include <unistd.h>
int access(const char *pathname, int mode);
pathname에 있는 접근권한이 가능한지 확인하는 함수
R_OK: 읽기 권한이 있는가
W_OK: 쓰기 권한이 있는가
X_OK: 실행 권한이 있는가
F_OK: 파일이 존재하는가
기능이나 파일이 존재하면 0, mode 사용이 거절되거나 에러 발생시 -1이 반환된다.
만일 Symbolic link가 pathname이라면 링크를 타고 들어가서 함수를 실행한다.
해당 함수는 실 소유자나 실소유 그룹으로 시험되며 effective uid(owner을 제외한 계정)으로는 실행되지 않는다.
EX6) access
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
if (argc != 2)
{
fprintf(stderr, "usage: a. out <pathname>");
exit(1);
}
if (access(argv[1], R_OK) < 0)//읽기 권한 확인
perror("access error");
else
printf("read access OK\n");
if (open(argv[1], O_RDONLY) < 0)//
perror("open error");
else
printf("open for reading OK\n");
exit(0);
}
stat함수 (fstat, lstat)
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *file_name, struct stat *buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *file_name, struct stat *buf);//심볼릭 링크 자체에 대한 정보
파일의 정보를 반환하는 함수이다.
파일 정보를 조회하는 대해 따로 접근 권한이 필요한거는 아니이나, 파일을 따라들어가는 모든 디렉토리에 대한 접근 권한이 필요합니다.
stat와 lstat는 file_name을 통해 정보를 조회하며, fstat는 file discriptor 번호를 통해
struct stat { //stat 함수로부터 받을수 있는 정보의 종류
dev_t st_dev; /* device number */
ino_t st_ino; /* inodenumber */
mode_t st_mode; /* file type, mode (permissions) */
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 type for special files (if inodedevice) */
off_t st_size; /* total size, in bytes */
unsigned long st_blksize; /* blocksizefor I/O */
unsigned long st_blocks; /* # of blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};
/* ST_MODE에서 확인할수 있는 POSIX 메크로
S_ISREG(buf.st_mode) : 일반 파일 여부
S_ISDIR(buf.st_mode) : 디렉토리 여부
S_ISCHR(buf.st_mode) : character device 여부
S_ISBLK(buf.st_mode) : block device 여부
S_ISFIFO(buf.st_mode) : FIFO 여부
S_ISLNK(buf.st_mode) : symbolic link 여부
S_ISSOCK(buf.st_mode) : socket 여부 (주로 AF_UNIX로 socket 생성된 경우)
/특수 권한/
S_ISUID 0004000 set-user-ID bit //일시적으로 소유자 ID권한으로 동작
S_ISGID 0002000 set-group-ID bit//일시적으로 소유그룹 ID권한으로 동작
S_ISVTX 0001000 sticky bit // 소유자만 파일을 삭제할수 있도록 엠바고를 걸어두는 동작
성공시 0을 반환, 에러시 -1을 반환
EX7) lstat
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
intmain(int argc, char *argv[])
{
int i;
struct stat buf;
char *ptr;
for (i = 1; i < argc; i++)
{
printf("%s: ", argv[i]);
if (lstat(argv[i], &buf) < 0)//lstat로 buf에 정보를 받아옴
{
perror("lstaterror");
continue;
}
if (S_ISREG(buf.st_mode))//받아온 정보를 이용하여 상세 정보를 조회함
ptr = "regular";
else if (S_ISDIR(buf.st_mode))
ptr = "directory";
else if (S_ISCHR(buf.st_mode))
ptr = "charactorspecial";
else if (S_ISBLK(buf.st_mode))
ptr = "block special";
else if (S_ISFIFO(buf.st_mode))
ptr = "fifo";
#ifdef S_ISLNK
else if (S_ISLNK(buf.st_mode))
ptr = "symbolic link";
#endif
#ifdef S_ISSOCK
elseif(S_ISSOCK(buf.st_mode)) ptr = "socket";
#endif
else ptr = "** unkownmode **";
printf("%s \n", ptr);
}
exit(0);
}
chmod와 fchmod 함수
#include <sys/types.h>
#include <sys/stat.h>
int chmod(const char *path, mode_t mode);
int fchmod(int fd, mode_t mode);
파일의 접근권한을 변경합니다.
path를 따라 들어간 mode의 fd를 바꿔줍니다.
S_IRUSR: 사용자 읽기 권한
S_IWUSR: 사용자 쓰기 권한
S_IXUSR: 사용자 실행 권한
S_IRXWU: 사용자 읽기, 쓰기, 실행 권한
S_IRGRP: 그룹 읽기 권한
S_IWGRP: 그룹 쓰기 권한
S_IXGRP: 그룹 실행 권한
S_IRWXG: 그룹 읽기, 쓰기, 실행 권한
S_IROTH: 나머지 읽기 권한
S_IWOTH: 나머지 쓰기 권한
S_IXOTH: 나머지 실행 권한
S_IRWXO: 나머지 읽기, 쓰기, 실행 권한
S_ISUID set user id
S_ISGID set group id
S_ISVTX saved sticky bit
성공시 0을 실패시 -1을 반환
EX8) chmod
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
int main(void) {
struct stat statbuf;
if (stat("foo", &statbuf) < 0) {
perror("stat error for foo");
exit(1);}/* turn on set-group-ID and turn off group-execute */
if (chmod("foo", (statbuf.st_mode& ~S_IXGRP) | S_ISGID) < 0) {
perror("chmoderror for foo");
exit(1);
}
if (chmod("bar", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0) {
perror("chmod error for bar");
exit(1);
}
exit(0);
}
chown, fchown, lchown 함수
#include <sys/types.h>
#include <unistd.h>
int chown(const char *path, uid_t owner, gid_y group);
int fchown(int fd, uid_t owner, gid_y group);
int lchown(const char *path, uid_t owner, gid_y group);
- 파일의 소유자를 path나 fd를 통해 바꿔줌
- 절대 권한이나 파일의 실소유자만 chown 함수를 사용할수 있음
- super유저가 아닌 사용자가 실행파일의 소유자를 변경하면 S_ISUID, S_ISGID 비트가 지워짐
- lchown함수는 Symbolic link 파일 자체의 소유자를 변경함
- 성공시 0을 실패시 -1을 반환
'공부 학습' 카테고리의 다른 글
컴퓨터 네트워크 - Application Layer (1) | 2021.04.06 |
---|---|
운영체제 4주차 - 2 (0) | 2021.03.29 |
운영체제 4주차 -1 (0) | 2021.03.22 |
운영체제 3주차 - 2 (1) | 2021.03.16 |
시스템프로그래밍 2주차 (0) | 2021.03.15 |