공부 학습

시스템프로그래밍 - 함수정리

Multitab 2021. 3. 24. 15:11

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함수로 복제하는 것으로 반환되는 newfdoldfd가 된다. 이때 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