본문 바로가기
대외활동/시스템프로그래밍

0826 리눅스 시스템 프로그래밍

by hoshi03 2024. 8. 26.

• 시스템 콜과 라이브러리 함수 차이

 

 

시스템 콜은 사용자가 malloc 등으로 메모리 할당하는게 필요

라이브러리 함수는 라이브러리 함수에서 메모리 할당해서 malloc 없이도 사용 가능

 

• perror

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

int main(){
    int fd = 3;
    if(write(fd, "hello", 5) == -1){
        perror("write");
        exit(1);
    }

    close(fd);
    return 0;
}

 

일부러 오류가 나게 작성한 코드

시스템 콜을 사용했을때 -1이 리턴되면 오류가 생긴 것

perror을 이용해서 오류를 출력한다

perror에 인자로 전달한 write: Bad file descriptor가 리턴된다

 

• 환경 변수

ppt 보고 복습

 

• open 메서드

 

파일 입출력을 위해서 사용하는 메서드, open 메서드를 이용해서 파일을 열거나 생성한다

open.c

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

int main(int argc, char*argv[]){
    int fd;

    if(argc!=2){
        fprintf(stderr, "Usage: %s filename\n", argv[0]);
        exit(1);
    }

    if((fd=open(argv[1], O_RDONLY)) == -1){
        perror("open");
        exit(1);
    }
    printf("fd: %d\n", fd);
    close(fd);

    return 0;
}

 

read.c

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

int main(int argc, char*argv[]){
    int fd;

    if(argc!=2){
        fprintf(stderr, "Usage: %s filename\n", argv[0]);
        exit(1);
    }

    if((fd=open(argv[1], O_RDONLY)) == -1){
        perror("open");
        exit(1);
    }
    printf("fd: %d\n", fd);

    char buf[1024];
    int size;

    if((size=read(fd,buf,1023)) == -1){
        perror("read");
        exit(1);
    }
    buf[size] = '\n';
    printf("buf : %s\n", buf);

    close(fd);

    return 0;
}

 

write.c

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

int main(int argc, char*argv[]){
    int fd;

    if(argc!=2){
        fprintf(stderr, "Usage: %s filename\n", argv[0]);
        exit(1);
    }

    if((fd=open(argv[1], O_RDONLY)) == -1){
        perror("open");
        exit(1);
    }
    printf("fd: %d\n", fd);

    char buf[1024];
    int size;

    if((size=read(fd,buf,1023)) == -1){
        perror("read");
        exit(1);
    }
    buf[size] = '\0';

    int ofd;
    if((ofd = open("test.c", O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1){
        perror("open");
        exit(1);
    }

    write(ofd, buf, size);
    

    close(fd);

    return 0;
}

 

• stty 설정

stty -a <- 모든 특수 문자 설정

 

stty -echo <- 입력하는 모든 게 보이지 않게 된다, 취소하려면 -를 뗀 stty echo

 

• ioctl 로 터미널 모드 전환

정규 모드 터미널을 비정규 모드로 전환

termios 구조체에 현재 터미널 정보를 저장해두고,  새로 설정한 걸 ioctl로 적용, 다시 ioctl로 기존 터미널 속성 원상복구

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <sys/ioctl.h>

int main(){
    char ch;
    struct termios tbuf, oldbuf;

    if (ioctl(STDIN_FILENO, TCGETS, &oldbuf) == -1)
    {
        perror("ioctl TCGETS");
        exit(1);
    }

    tbuf = oldbuf;
    tbuf.c_lflag &= ~ICANON;
    tbuf.c_cc[VMIN] = 1;
    tbuf.c_cc[VTIME] = 0;

    if (ioctl(STDIN_FILENO, TCSETS, &tbuf) == -1)
    {
        perror("ioctl TCSETS");
        exit(1);
    }

    while (1)
    {
        ch = getchar();
        if (ch == 'q') break; 
        printf(" %x\n", ch);
    }

    //원복
    if (ioctl(STDIN_FILENO, TCSETS, &oldbuf) == -1)
    {
        perror("ioctl TCSETS restore");
        exit(1);
    }
    return 0;
}

 

• 파일 중첩

 

파일 디스크립터가 open으로 열린 후 dup로 파일 디스크립터를 지정해줘서 표준 입출력이 파일 디스크립터가 오픈한
dup.txt에 되게 된다

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

int main(){

    printf("hello dump1\n");

    int fd;
    fd = open("dup.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (fd == -1)
    {
        perror("open");
        exit(1);
    }

    close(1);
    dup(fd);

    printf("hello dump2\n");

}

 

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

int main(){

    printf("hello dump1\n");

    int fd;
    fd = open("dup.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (fd == -1)
    {
        perror("open");
        exit(1);
    }

    dup2(fd,1);

    printf("hello dump2\n");
}