로봇SW교육원 강의자료

Similar documents
로봇SW교육원 강의자료

슬라이드 1

Microsoft PowerPoint APUE(File InO).ppt

Microsoft PowerPoint APUE(File InO)

제1장 Unix란 무엇인가?

Microsoft PowerPoint APUE(File InO).pptx

제12장 파일 입출력

Microsoft PowerPoint - chap2

제1장 Unix란 무엇인가?

Microsoft PowerPoint - chap12 [호환 모드]

chap7.key

<4D F736F F F696E74202D20B8AEB4AABDBA20BFC0B7F920C3B3B8AEC7CFB1E22E BC8A3C8AF20B8F0B5E55D>

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

歯9장.PDF

2009년 상반기 사업계획

10.

Microsoft PowerPoint - ch09_파이프 [호환 모드]

2009년 상반기 사업계획

Microsoft PowerPoint - chap13-입출력라이브러리.pptx

<4D F736F F F696E74202D FC6C4C0CF20C0D4C3E2B7C2205BC8A3C8AF20B8F0B5E55D>

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

Microsoft PowerPoint - 09-Pipe

<4D F736F F F696E74202D FB8DEB8F0B8AE20B8C5C7CE205BC8A3C8AF20B8F0B5E55D>

2009년 상반기 사업계획

ABC 11장

Microsoft PowerPoint - chap4 [호환 모드]

PowerPoint 프레젠테이션

untitled

슬라이드 1

PowerPoint 프레젠테이션

금오공대 컴퓨터공학전공 강의자료

vi 사용법

6주차.key

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

Microsoft PowerPoint - 09_FileSystem

PowerPoint 프레젠테이션

슬라이드 1

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

Microsoft PowerPoint - Lecture 4-1 Linux File Environment.ppt [호환 모드]

학번 : 이름 : 1. 다음파일트리구조를가진유닉스시스템이있다고가정하자. / /bin/ /home/ /home/taesoo/ /usr/ /usr/lib/ /usr/local/lib /media 모든폴더에파일이하나도없다고가정했을때사용자가터미널에서다음 ls 명령입력시화면출력

Microsoft PowerPoint - 제11강 파일 처리

슬라이드 1

The Pocket Guide to TCP/IP Sockets: C Version

K&R2 Reference Manual 번역본

PowerPoint 프레젠테이션

/chroot/lib/ /chroot/etc/

11장 포인터

Microsoft PowerPoint - lab14.pptx

학번 : 이름 : 1. 다음파일트리구조를가진유닉스시스템이있다. / /bin/ /home/ /home/taesoo/ /home/taesoo/downloads /usr/ /usr/lib/ /usr/local/lib /media 모든폴더에파일이하나도없다고가정했을때사용자 (t

제1장 Unix란 무엇인가?

2009년 상반기 사업계획

0. 표지에이름과학번을적으시오. (6) 1. 변수 x, y 가 integer type 이라가정하고다음빈칸에 x 와 y 의계산결과값을적으시오. (5) x = (3 + 7) * 6; x = 60 x = (12 + 6) / 2 * 3; x = 27 x = 3 * (8 / 4

쉽게 풀어쓴 C 프로그래밍

금오공대 컴퓨터공학전공 강의자료

PowerPoint 프레젠테이션

BMP 파일 처리

Microsoft PowerPoint - chap11.ppt [호환 모드]

Microsoft PowerPoint - Lecture_Note_7.ppt [Compatibility Mode]

Chapter #01 Subject

좀비프로세스 2

untitled

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx

Microsoft PowerPoint APUE(Intro).ppt

PowerPoint Template

PowerPoint 프레젠테이션

이번장에서학습할내용 동적메모리란? malloc() 와 calloc() 연결리스트 파일을이용하면보다많은데이터를유용하고지속적으로사용및관리할수있습니다. 2

PowerPoint 프레젠테이션

Microsoft PowerPoint - chap10-함수의활용.pptx

제9장 프로세스 제어

3. 다음그림은프로세스의 file table 과 v-node 테이블의연결관계예제이다. 위그림을참고하여두개의서로다른프로세스가같은파일을 open 명령을사용하여열었을때의연결관계를도시하시오. 4. 메모리영역은 low-address 부터 high-adress 까지순서대로나열했을

Microsoft PowerPoint - [2009] 02.pptx

Microsoft PowerPoint - IOControl [호환 모드]

제 14 장포인터활용 유준범 (JUNBEOM YOO) Ver 본강의자료는생능출판사의 PPT 강의자료 를기반으로제작되었습니다.

UI TASK & KEY EVENT

<4D F736F F F696E74202D FC7C1B7CEBCBCBDBA20BBFDBCBAB0FA20BDC7C7E0205BC8A3C8AF20B8F0B5E55D>

2009년 상반기 사업계획

제1장 Unix란 무엇인가?

Microsoft PowerPoint - 09_(C_Programming)_(Korean)_File_Processing

Microsoft PowerPoint - Lecture_Note_5.ppt [Compatibility Mode]

Microsoft PowerPoint - chap12-고급기능.pptx

1장. 유닉스 시스템 프로그래밍 개요

Microsoft PowerPoint - chap11-1.ppt [호환 모드]

임베디드시스템설계강의자료 6 system call 2/2 (2014 년도 1 학기 ) 김영진 아주대학교전자공학과

Lab 3. 실습문제 (Single linked list)_해답.hwp

The OSI Model

The Pocket Guide to TCP/IP Sockets: C Version

고급 프로그래밍 설계

1장. 유닉스 시스템 프로그래밍 개요

본 강의에 들어가기 전

KEY 디바이스 드라이버

<4D F736F F F696E74202D2034C5D8BDBAC6AEC6C4C0CFC0D4C3E2B7C2312E505054>

À©µµ³×Æ®¿÷ÇÁ·Î±×·¡¹Ö4Àå_ÃÖÁ¾

PowerPoint 프레젠테이션

Microsoft PowerPoint - chap6 [호환 모드]

< E20C6DFBFFEBEEE20C0DBBCBAC0BB20C0A7C7D12043BEF0BEEE20492E707074>

Transcription:

UNIT 06 저수준파일입출력 로봇 SW 교육원 최상훈 (shchoi82@gmail.com)

학습목표 2 저수준파일입출력함수 리눅스파일시스템의이해 다양한파일입출력실습을통한프로그램능력향상

파일시스템 3 리눅스파일시스템의특징 / 로시작하는트리구조 / (root) usr home bin local bin lib

열린파일에대한커널내부자료구조 4 프로세스테이블 파일테이블 v 노드테이블 fd 0: fd 1: fd 2: fd 3: fd 4: fd 플래그들 파일포인터 파일상태플래그들 현재파일오프셋 V 노드포인터 v 노드정보 i 노드정보 현재파일크기 파일디스크립터테이블 파일상태플래그들 현재파일오프셋 V 노드포인터 v 노드정보 i 노드정보 현재파일크기

프로세스테이블과파일테이블 5 프로세스테이블 시스템에현재실행중인모든프로세스에대한정보를저장하고있음 프로세스 ID, 프로세스권한정보, 프로세스의상태등프로세스에대한모든정보들이저장됨 파일디스크립터테이블 프로세스는자신이작업중인모든파일에대한파일디스크립터테이블저장 파일디스크립터 (file descriptor) 의구성요소 상태플래그 : FD_CLOEXEC 옵션 파일포인터 : 파일테이블의항목을가리키는포인터 파일테이블 현재시스템상에열린모든파일에대한정보 ( 시스템전역 ) 각항목의구성 파일의상태를나타내는플래그 (R, W, RW) 현재파일오프셋 v-node를가리키는포인터

v-node 테이블 6 v-node 테이블 각항은하나의파일과대응 파일에관련된모든정보저장 파일의종류 파일의소유정보 파일의크기 파일의실제데이터위치 ( 예 : 디스크상의위치 ) 파일의접근권한 (rwxrwxrwx) 파일의시간정보 (a, m, c) 파일의하드링크수 파일과연관된함수포인터 Linux 에는 v-node 가없고일반적 i-node 가사용됨 v-node 는하나의컴퓨터시스템에서여러종류의파일시스템을지원하기위해고안됨

파일디스크립터 7 파일식별자 파일디스크립터를통해파일관과련된작업 (I/O처리등 ) 을수행 음이아닌정수 open,creat 시스템콜등을통해얻을수있음 표준파일디스크립터 표준입력, 표준출력, 표준에러의파일서술자 unistd.h에정의되어있음 표준입력 : STDIN_FILENO 표준출력 : STDOUT_FILENO 표준에러 : STDERR_FILENO 표준 I/O 라이브러리의표준스트림 표준파일디스크립터와연결 stdio.h 표준입력 - 표준입력스트림 : stdin 표준출력 - 표준출력스트림 : stdout 표준에러 - 표준에러스트림 : stderr

open 8 #include <fcntl.h> int open ( const char *path, int oflag, /* mode_t mode */ ); Returns : file descriptor if OK, -1 on error 기능 : 존재하는파일을열거나, 새로운파일을생성 리턴값 : 성공하면파일디스크립터, 실패하면 -1 path : 열거나생성하고자하는파일 oflag : 플래그 mode : 새로운파일을만드는경우, 접근권한 (permission)

open flag 9 O_RDONLY - 읽기만가능 O_WRONLY - 쓰기만가능 O_RDWR - 읽기와쓰기모두가능 O_EXEC -? O_SEARCH -? 위의다섯가지모드중반드시하나선택해야함 (mutual exclusive) O_APPEND 모든쓰기작업 (write) 을파일의끝에서수행 O_CLOEXEC file descriptor flag 에 FD_CLOEXEC 를설정함 O_CREAT 파일이없을경우파일을생성 ( 세번째인자필요 ) O_DIRECTORY 디렉토리가아니면 error 를발생시킴

open flag 10 O_EXCL O_CREAT 와같이쓰이며, 파일이있는경우에 error 를발생 O_TRUNC 파일이있는경우에기존파일의내용을지움 기타 O_NOCTTY O_NOFOLLOW O_NONBLOCK O_SYNC O_TTY_INIT O_DYSNC O_RSYNC

open 11 open 에사용가능한옵션 /usr/include/bits/fcntl.h #define O_ACCMODE 0003 #define O_RDONLY 00 #define O_WRONLY 01 #define O_RDWR 02 #define O_CREAT 0100 #define O_EXCL 0200 #define O_NOCTTY 0400 #define O_TRUNC 01000 #define O_APPEND 02000 #define O_NONBLOCK 04000 #define O_NDELAY O_NONBLOCK #define O_SYNC 04010000 #define O_FSYNC O_SYNC #define O_ASYNC 020000

close 12 #include <unistd.h> int close ( int filedes ); Returns : 0 if OK, -1 on error 기능 : 열려진파일을닫음 리턴값 : 성공하면 0, 실패하면 -1 filedes : 닫고자하는파일의파일디스크립터 파일을닫지않더라도프로세스가종료되면모든열린파일들을자동적으로닫음

실습 1:open 13 open 함수를이용한파일생성 파일명 : openex1.c #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #define PERM 0644 int main() int fd; char *sznewfilepath = "./newfile"; if((fd = open(sznewfilepath, O_WRONLY O_CREAT, PERM)) == -1) fprintf(stderr, "Couldn't open... : filepath:%s", sznewfilepath); exit(1); close(fd); return 0;

실습 2:open 14 open 함수를이용한파일생성 (with O_EXCL) 파일명 : openex2.c #include<stdio.h> #include<fcntl.h> #include<stdlib.h> #include<unistd.h> int main() int fd; char *sznewfilepath = "./newfile"; if((fd = open(sznewfilepath, O_RDWR O_CREAT O_EXCL O_TRUNC, 0644)) == -1) fprintf(stderr, "Couldn't open.. : filepath=%s\n", sznewfilepath); exit(1); close(fd); return 0;

실습 3:open 15 open 함수의 O_TRUNC 파일명 : openex3.c #include<stdio.h> #include<fcntl.h> #include<unistd.h> int main(void) int fd; if((fd = open("./file1", O_RDONLY O_TRUNC)) == -1) fprintf(stderr, "Couldn't open.. : filepath=%s\n", szfilepath); exit(1); printf("fd:%d\n", fd); close(fd); return 0;

creat 16 #include <fcntl.h> int creat ( const char *path, mode_t mode ); Returns : file descriptor opened for write-only if OK, -1 on error 기능 : 새로운파일을생성 리턴값 : 성공하면파일디스크립터, 실패하면 -1 path : 생성하고자하는파일의이름 mode : 접근권한 open 함수와비교 O_WRONLY O_CREAT O_TRUNC 플래그적용한것과동일함

실습 4:creat 17 creat 함수를이용한파일생성 파일명 : createx1.c #include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<fcntl.h> #define PERM 0644 int main() int fd; char* sznewfilepath = "./newfile"; if((fd = creat(sznewfilepath, PERM)) == -1) fprintf(stderr, "Couldn't creat : filepath=%s", sznewfilepath); exit(1); close(fd); return 0;

read 18 #include <unistd.h> ssize_t read (int filedes, void *buf, size_t nbytes); 기능 : 파일로부터데이터를읽어들이는함수 ( 파일 offset 증가 ) 리턴값 : 성공하면, 버퍼로읽어들인데이터의바이트수 파일의끝을만나면, 0 실패하면, -1 buff : 읽어들인데이터를저장하는버퍼공간 nbytes : 읽어들일데이터의최대바이트의수

write 19 #include <unistd.h> ssize_t write (int filedes, const void *buf, size_t nbytes); 기능 : 지정된파일에데이터를쓰는함수 ( 파일 offset 증가 ) 리턴값 : 성공하면, 파일에쓴데이터의바이트수 실패하면, -1 buff : 쓸데이터를저장하고있는버퍼공간 nbytes : 쓸데이터의바이트의수 write 수행시에러가발생하는경우 파일시스템이가득찬경우 파일의크기가한계값을초과하는경우

lseek 20 모든열린파일에는 현재파일오프셋 이존재 파일테이블에저장됨 파일의처음부터 byte 단위로계산한정수값 파일이열릴때, 0 으로초기화됨 lseek #include <unistd.h> off_t lseek (int filedes, off_t offset, int whence ); 기능 : 파일의현재파일오프셋을명시적으로변경 리턴값 : 성공하면이동한지점의오프셋, 실패하면 -1 whence : 오프셋을옮기기위한기준점 SEEK_SET : 파일의처음시작부분 SEEK_CUR : 현재파일오프셋 SEEK_END : 파일의재일마지막부분 offset : 기준점에서의상대적인거리 (byte 단위 ) SEEK_CUR, SEEK_END 와같이쓰일때는음수도허용

실습 5: 표준파일디스크립터 21 표준파일디스크립터입출력 파일명 : stdfd.c #include<stdio.h> #include<unistd.h> #define BUFFSIZE 4096 int main(void) int n; char buf[buffsize]; while ((n = read(stdin_fileno, buf, BUFFSIZE)) > 0) if (write(stdout_fileno, buf, n)!= n) printf("write error\n"); return 1; if (n < 0) printf("read error\n"); return 1; return 0; $./stdfd.out > data2 hello world[ctrl+d][ctrl+d] $ cat data2 hello world $./stdfd.out < data2 > data2.copy $ cat data2 hello world $

실습 6:read 22 read 함수기본예제 파일명 : readex1.c #include<stdio.h> #include<unistd.h> #include<fcntl.h> int main() int fd; ssize_t nread; char *szfilepath = "./test2.txt"; char buf[1024]; if((fd = open(szfilepath, O_RDONLY)) == -1) printf("couldn't open.. : FilePath=%s\n", szfilepath); return 1; nread = read(fd, buf, sizeof(buf)); if(nread == -1) printf("couldn't read..."); return 1; printf("nread = %ud\n", nread); close(fd); return 0;

실습 7: 파일복사 23 파일복사 파일명 : mycp.c #include<stdio.h> #include<stdlib.h> #include<fcntl.h> #include<string.h> #include<unistd.h> #define PERM 0644 int main(int argc, char* argv[]) int nsrcfd,ndstfd; ssize_t nread = 0; ssize_t nwrite = 0; char buf[1024] = 0; char* szsrcfilepath = argv[1]; char* szdstfilepath = argv[2]; if((nsrcfd = open(szsrcfilepath, O_RDONLY)) == -1) printf("couldn't open : filepath=%s", szsrcfilepath); exit(0);

실습 8: 파일복사 24 if((ndstfd = creat(szdstfilepath, PERM)) == -1) printf("couldn't creat : filepath=%s", szdstfilepath); exit(0); while((nread = read(nsrcfd, buf, 1024)) > 0) if(write(ndstfd,buf,nread) < nread) printf("couldn't write"); close(ndstfd); close(nsrcfd); exit(0); nwrite += nread; memset(buf,0,sizeof buf); close(ndstfd); close(nsrcfd); if(nread == -1) printf("couldn't read"); exit(0); printf("nwrite = %d", nwrite); return 1;

실습 9:lseek 25 lseek 함수를이용해파일의크기구하기 파일명 : lseekex1.c #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <fcntl.h> int main(void) char *fname = "test.txt"; int fd; off_t fsize; if((fd = open(fname, O_RDONLY)) == -1) printf("open error\n"); return 1; fsize = lseek(fd, 0, SEEK_END); printf("the size of <%s> is %lu bytes.\n", fname, fsize); return 0; $./lseekex1 The size of <test.txt> is 10 bytes.

실습 10:lseek 26 파일의구멍 파일명 : lseekex2.c #include<stdio.h> #include<fcntl.h> #include<unistd.h> char buf1[] = "abcdefghij"; char buf2[] = "ABCDEFGHIJ"; int main(void) int fd; if((fd = creat("file.hole", 0622)) < 0) fprintf(stderr, "creat error"); if(write(fd, buf1, 10)!= 10) fprintf(stderr, "buf1 write error"); if(lseek(fd, 16384, SEEK_SET) == -1) fprintf(stderr, "lseek error"); if(write(fd, buf2, 10)!= 10) fprintf(stderr, "buf2 write error"); $./lseekex2 $ ls -l file.hole -rw------- 1 advc advc 16394 2011-07-31 21:01 file.hole $ od -c file.hole 0000000 a b c d e f g h i j \0 \0 \0 \0 \0 \0 0000020 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 * 0040000 A B C D E F G H I J 0040012 $ cat < file.hole > file.hole.copy $ ls -ls file.hole file.hole.copy 8 -rw------- 1 advc advc 16394 2011-07-31 21:01 file.hole 20 -rw------- 1 advc advc 16394 2011-07-31 21:03 file.hole.copy return 0;

실습 11-1:read 27 같은파일읽기예제 파일명 : readex2.c #include <stdio.h> #include <fcntl.h> #include <unistd.h> int main(void) char *fname = "data"; int fd1, fd2, cnt; char buf[30]; fd1 = open(fname, O_RDONLY); fd2 = open(fname, O_RDONLY); if(fd1 == -1 fd2 == -1) printf("open error\n"); return 1; cnt = read(fd1, buf, 12); buf[cnt] = '\0'; printf("fd1's first printf : %s\n", buf);

실습 11-2:read 28 lseek(fd1, 1, SEEK_CUR); cnt = read(fd1, buf, 12); buf[cnt] = '\0'; printf("fd1's second printf : %s\n", buf); cnt = read(fd2, buf, 12); buf[cnt] = '\0'; printf("fd2's first printf : %s\n", buf); lseek(fd2, 1, SEEK_CUR); cnt = read(fd2, buf, 12); buf[cnt] = '\0'; printf("fd2's second printf : %s\n", buf); return 0; < 실습하기전 data 파일생성 > $ cat > data Hello, UNIX! How are you? [Ctrl + D] $ cat data Hello, UNIX! How are you? $ $./readex2 fd1's first printf : Hello, UNIX! fd1's second printf : How are you? fd2's first printf : Hello, UNIX! fd2's second printf : How are you?

파일오프셋과파일 I/O 29 write 호출시동작 기록된바이트수만큼현재파일오프셋증가 현재파일오프셋이파일크기를넘게되면 i-node 테이블항목의파일크기에설정됨 open 함수호출시 O_APPEND 를지정한경우 ' 파일테이블 ' 의 ' 파일상태플래그 ' 에설정됨 write 호출시 ' 현재파일오프셋 ' 이 i-node 테이블항목의파일크기에설정됨 lseek 함수호출로파일의끝으로이동 현재파일오프셋을단순히 i-node 테이블항목의파일크기로설정 I/O 연산이일어나지않음

실습 12: 파일오프셋 30 O_APPEND 플래그 파일명 : openex4.c #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<fcntl.h> int main(void) int fd; long offset; if((fd = open("./data", O_WRONLY O_APPEND)) == -1) fprintf(stderr, "open error\n"); exit(1); offset = lseek(fd, 0, SEEK_CUR); printf("before write offset:%ld\n", offset); if(write(fd, "7777", 4)!= 4) fprintf(stderr, "write error\n"); exit(1); offset = lseek(fd, 0, SEEK_CUR); printf("after write offset:%ld\n", offset); offset = lseek(fd, 0, SEEK_END); printf("file size:%ld\n", offset); close(fd); exit(0); $ cat > data 1234567890[Ctrl+d][Ctrl+d]$./openEx4 before write offset:0 after write offset:14 file size:14 $

파일의공유 31 UNIX 는 multi-user/multi-tasking 시스템이기때문에다른프로세스에의해같은파일을동시에접근할있음 프로세스 A 테이블항목 파일테이블 v 노드테이블 fd 0: fd 1: fd 2: fd 3: fd 플래그들 파일포인터 파일상태플래그들 현재파일오프셋 V 노드포인터 v 노드정보 프로세스 B 테이블항목 i 노드정보 현재파일크기 fd 0: fd 1: fd 2: fd 3: fd 4: fd 플래그들 파일포인터 파일상태플래그들 현재파일오프셋 V 노드포인터

원자적연산 32 원자적 (atomic) 연산 연산수행중에다른연산에의해가로채지지않는것 모두수행되거나또는모두수행되지않거나 open 시 O_APPEND 플래그지원되지않는다면? if (lseek(fd, 0L, SEEK_END) == -1) /* position to EOF */ fprintf(stderr, "lseek error\n"); exit(1); <<<<<<<<<<<<<<< >>>>>>>>>>>>>>>> if (write(fd, buf, 100)!= 100) /*...and write */ fprintf(stderr, "write error\n"); exit(1); lseek 와 write 사이에다른프로세스가실행될가능성이있음 semaphore, mutex 등을사용해야함

실습 13: 원자적연산 33 원자적연산 파일명 : atomicex1.c #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <fcntl.h> #include <stdlib.h> int main(void) char *fname = "shared"; int fd; off_t curoffset; long i; if((fd = open(fname, O_WRONLY)) == -1) printf("open error\n"); return 1; for(i = 0 ; i < 100000 ; i++) curoffset = lseek(fd, 0, SEEK_END); if(write(fd, "0", 1)!= 1) exit(1); printf("%ld\r", i); return 0;

실습 14: 원자적연산 34 원자적연산 파일명 : atomicex2.c #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <fcntl.h> #include <stdlib.h> int main(void) char *fname = "shared"; int fd; off_t curoffset; long i; if((fd = open(fname, O_WRONLY O_APPEND)) == -1) printf("open error\n"); return 1; for(i = 0 ; i < 100000 ; i++) if(write(fd, "0", 1)!= 1) exit(1); printf("%ld\r", i); return 0;

실습 15-1: 구조체파일출력 35 구조체파일 write 파일명 : structurewrite.c #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <fcntl.h> #include <stdlib.h> typedef struct TAG_GPIOCTL_DATA int pinno; int ontime; int offtime; int repeat; GPIOCTL_DATA; int main(void) char *fname = "gpio_data"; int fd; const int DATA_SIZE = sizeof(gpioctl_data); GPIOCTL_DATA data;

실습 15-2: 구조체파일출력 36 printf("pinno:"); scanf("%d", &data.pinno); printf("ontime:"); scanf("%d", &data.ontime); printf("offtime:"); scanf("%d", &data.offtime); printf("repeat:"); scanf("%d", &data.repeat); if((fd = open(fname, O_WRONLY O_CREAT O_TRUNC, 0644)) == -1) fprintf(stderr, "open error\n"); return 1; if(write(fd, &data, DATA_SIZE)!= DATA_SIZE) fprintf(stderr, "write error\n"); exit(1); return 0;

실습 16-1: 구조체파일입력 37 구조체파일 read 파일명 : structureread.c #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <fcntl.h> #include <stdlib.h> typedef struct TAG_GPIOCTL_DATA int pinno; int ontime; int offtime; int repeat; GPIOCTL_DATA; int main(void) char *fname = "gpio_data"; int fd; const int DATA_SIZE = sizeof(gpioctl_data); GPIOCTL_DATA data;

실습 16-2: 구조체파일입력 38 if((fd = open(fname, O_RDONLY)) == -1) fprintf(stderr, "open error\n"); return 1; if(read(fd, &data, DATA_SIZE)!= DATA_SIZE) fprintf(stderr, "read error\n"); exit(1); printf("pinno:%d\n", data.pinno); printf("ontime:%d\n", data.ontime); printf("offtime:%d\n", data.offtime); printf("repeat:%d\n", data.repeat); return 0;

dup, dup2 39 #include <unistd.h> int dup (int filedes); int dup2 (int filedes, int filedes2); 기능 : 사용중인파일디스크립터를복사 리턴값 : 성공하면할당받은파일디스크립터번호, 실패하면 -1 dup( ) 함수는할당가능한가장작은번호를리턴 dup2( ) 함수는 filedes2를리턴, fd1를 fd2로복사함 파일디스크립터항목의플래그 (FD_CLOEXEC) 는초기값 (0) 설정됨

dup, dup2 40 동일한 ' 파일테이블 ' 항목을공유 ex) newfd = dup(1); newfd = dup2(1,3); 프로세스테이블 fd 0: fd 1: fd 2: fd 3: fd 플래그들 파일포인터 파일테이블 파일상태플래그들현재파일오프셋 v 노드테이블 v노드정보 i노드정보 V 노드포인터 현재파일크기

실습 17:dup 41 파일명 : dupex1.c #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <string.h> #include <unistd.h> int main(void) char *fname = "data2"; int fd1, fd2, cnt; char buf[30]; $ cat > data2 abcd0123[ctrl + D][Ctrl + D] $./dupex1 fd1's printf : abcd current file offeset:4 fd2's printf : 0123 $ if((fd1 = open(fname, O_RDONLY)) == -1) printf("open error/n"); return 1; fd2 = dup(fd1); cnt = read(fd1, buf, 4); buf[cnt] = '\0'; printf("fd1's printf : %s\n", buf); printf("current file offeset:%ld\n", lseek(fd1, 0, SEEK_CUR)); cnt = read(fd2, buf, 4); buf[cnt] = '\0'; printf("fd2's printf : %s\n", buf); return 0;

실습 18:dup 42 파일명 : dupex2.c #include<stdio.h> #include<fcntl.h> #include<unistd.h> int main(void) char *fname = "data3"; int fd1, fd2; if((fd1 = creat(fname, 0666)) < 0) printf("creat error\n"); return 1; printf("first printf is on the screen.\n"); fd2 = dup2(fd1,1); printf("second printf is in this file.\n"); printf("fd2:%d\n", fd2); return 0; $./dupex2 First printf is on the screen. $ cat data3 Second printf is in this file. fd2:1

fcntl 43 #include <fcntl.h> int fcntl (int filedes, int cmd, /* int arg */ ); 기능 : 이미열려져있는파일에대한속성을알아내거나변경함 cmd 에따라기능이달라짐 리턴값 : 성공인경우에 cmd 값에따라다름 ( 다음슬라이드참고 ), 실패하면 -1

fcntl 명령의종류 44 명령의종류 (cmds) F_DUPFD : 파일디스크립터를복사. 세번째인수보다크거나같은값중가장작은미사용의값을리턴한다. F_GETFD : 파일디스크립터의플래그를반환 (FD_CLOEXEC) F_SETFD : 파일디스크립터의플래그를설정 F_GETFL : 파일테이블에저장되어있는파일상태플래그를반환 F_SETFL : 파일상태플래그의설정 (O_APPEND, O_NONBLOCK, O_SYNC 등을지정 ) F_GETLK/F_SEKLK : 레코드자물쇠를조회 / 설정함 (14 장고급 I/O)

실습 19-1:fcntl ( 파일명 : fcntlex.c) 45 #include <stdio.h> #include <stdlib.h> #include <fcntl.h> int main(void) char *fname = "data"; int fd; int flag; if((fd = open(fname, O_RDWR O_APPEND)) < 0) printf("open error\n"); return 1; flag = fcntl(fd, F_GETFL, 0); switch(flag & O_ACCMODE) case O_RDONLY: printf("o_rdonly flag is set.\n"); break; case O_WRONLY: printf("o_wronly flag is set.\n"); break; case O_RDWR: printf("o_rdwr flag is set.\n"); break; default: printf("unknown accemode"); break;

실습 19-2:fcntl 46 if (flag & O_APPEND) printf("fd: O_APPEND flag is set. \n"); else printf("fd: O_APPEND flag is NOT set. \n"); flag = fcntl(fd, F_GETFD, 0); if (flag & FD_CLOEXEC) printf("fd: FD_CLOEXEC flag is set. \n"); else printf("fd: FD_CLOEXEC flag is NOT set. \n"); fcntl(fd, F_SETFD, FD_CLOEXEC); flag = fcntl(fd, F_GETFD, 0); if (flag & FD_CLOEXEC) printf("fd: FD_CLOEXEC flag is set. \n"); else printf("fd: FD_CLOEXEC flag is NOT set. \n"); return 0; $./fcntlex.out O_RDWR flag is set. fd: O_APPEND flag is set. fd: FD_CLOEXEC flag is NOT set. fd: FD_CLOEXEC flag is set. $

참고자료 : 열수있는파일의개수 47 프로세스가열수있는파일의최대개수 파일명 : maxopen.c #include<stdio.h> #include<unistd.h> int main(void) printf("open_max:%ld\n", sysconf(_sc_open_max)); return 1;

참고자료 : 파일명과경로명의최대길이 파일의경로최대길이 : PATH_MAX 파일의이름최대길이 : NAME_MAX #include<stdio.h> #include<unistd.h> #include<limits.h> int main(void) printf("path_max:%ld\n", pathconf("/",_pc_path_max)); printf("name_max:%ld\n", pathconf("/",_pc_name_max)); 48 printf("path_max:%d\n", PATH_MAX); printf("name_max:%d\n", NAME_MAX); return 0;

참고자료 : 파일명과경로명의최대길이 파일의경로최대길이 : PATH_MAX 파일의이름최대길이 : NAME_MAX #include<stdio.h> #include<errno.h> #include<unistd.h> #include<fcntl.h> extern int errno; int main(void) if(_posix_no_trunc) printf("path_max:%ld\n", pathconf("/",_pc_path_max)); printf("name_max:%ld\n", pathconf("/",_pc_name_max)); if(open("0123456789012345678901234567890123456789012345678901234567890123456789012345678 901234567890123456789\ 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 890123456789\ 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 890123456789.data",O_RDWR O_CREAT, 0777) == -1) if(errno == ENAMETOOLONG) perror(""); return 1; 49

미션 50 실습 15 프로그램은 gpio_data 파일을읽고내용을출력한다. gpio_data 파일을읽어실제 LED 를제어하도록프로그램을수정하시오. (wiringpi 라이브러리사용 ) - pinno : GPIO 핀번호 - ontime : GPIO 핀이 On 상태인시간 ( 초 ) - offtime : GPIO 핀이 Off 상태인시간 ( 초 ) - repeat : 반복회수