[질문]System Call인 write()함수로 printf()를 흉내내기?
어제 일요일 저녁부터 유닉스 프로그래밍을 짜고 있는데..도저히 감이 안 와서 이렇게 글을 올립니다.
숙제가 모냐하면 cat 명령어를 만들어 보라는 겁니다.
조건이 첫번째 숙제는 stdio.h에 있는 함수만 사용하고,
두번째 숙제는 system call만 이용하라는 겁니다.
C 라이브러리 이용하는 것은 좀 머리에 쥐가 나기 시작하니 풀리던데
system call 이용하는 것은 도저히 모르겠네요.
$ gcc -o command command.c
$ ./command alpha.txt
This is the file, ALPHA.
$ ./command bravo.txt
This is another file, BRAVO.
$ ./command alpha.txt bravo.txt
This is the file, ALPHA.
This is another file, BRAVO.
$ ./command < alpha.txt
This is the file, ALPHA.
$ ./command alpha.txt charlie.txt bravo.txt
This is the file, ALPHA.
./command: charlie.txt: No such file or directory
This is another file, BRAVO.
$
저 빨간 부분에서 막힙니다.
첫번째 거는 stdio.h errno.h를 이용해 쉽게 풀었지만,
write로 저 문장을 쓰려고 하니 머리가 아프네요.
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>#define SIZE 1024
int main(int argc, char *argv[])
{
char buffer[];
char * filename;
size_t nread;
int fd;
int i;
char str[26]="No such file or directory";
char enterkey[1];
enterkey[0] = 10;
...생략...
else
{
for( i=1; i<argc ; i++)
{
filename = argv[i];
if( (fd=open(filename,O_RDONLY)) == -1 )
{
write(2,argv[0],sizeof(argv[0]));
write(2,": ",2);
write(2,filename,sizeof(filename));
write(2,": ",2);
write(2,str,sizeof(str));
write(2,enterkey,sizeof(enterkey));
}
...생략...
printf() 대충 흉내 내본다고 write로 엄청 삽질을 하고 있습니다.
문제를 저걸 실행할경우
$./command alpha.txt charlie.txt bravo.txt
This is the file, ALPHA.
./co: char: No such file or directory
This is another file, BRAVO.
결과 값이 짤려 나옵니다.
그 이유가 궁금해서 알아보니
(gdb) display
2: sizeof filename = 4
1: sizeof argv[0] = 4
4byte 밖에 못 읽네요.ㅡ.ㅡ
힌트 좀 주세요...ㅡ.ㅜ
헉,, sizeof 가 아니라 strlen() 을 쓰셔야죵..size
헉,, sizeof 가 아니라 strlen() 을 쓰셔야죵..
sizeof 파라메터로 character pointer 가 들어가니 당연히
포인터의 크기인 4를 리턴한 거죵..
문자열의 길이를 구하려면 strlen() 을 쓰세요.
[quote="최종호"]헉,, sizeof 가 아니라 strlen() 을
헛 그게 있었군요....
전 그것도 stdio.h에 있는 함수인줄 알고...ㅡ.ㅡ
감사합니다...^^
문근영 너무 귀여워~~
sizeof() == strlen ()?음 묘한 발상을 하셨네요.
sizeof() == strlen ()?
음 묘한 발상을 하셨네요.
strlen()같은 스트링관련 함수도 사용하지 말라고 했다면,
my_strlen()을 만들어서 쓰면 되겠군요.
------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.
[quote="mach"]sizeof() == strlen ()?
컬컬컬....
저두 황당하네요...어제는 왜 그게 생각나지 않았을까?? ㅡ.ㅡ
문근영 너무 귀여워~~
그런데, 제목대로,[quote][질문]System Call인 writ
그런데, 제목대로,
를 만족하는 것이라면,
1. 포매팅(%어쩌구.....)
2. 버퍼링(이게 키포인트인듯)
이 두가지를 만족시키는 것으로 보면 될듯합니다.
sprintf() + write()로 구성하면 될 듯합니다.
------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.
[quote="mach"]sprintf() + write()로 구성하면
stdio.h 쓰면 안되고 오직 시스템 콜만으로 작성해야 하거든요..ㅡ.ㅡ
문근영 너무 귀여워~~
심심풀이 땅콩
sizeof 는 연산자로 알고 있는데, mach님이 쓴 걸 보니
sizeof == strlen() 으로 쓰지 않고 왜 sizeof() == strlen() 으로 썼을까 궁금해졌습니다.
저도 생각해보니 sizeof 쓸때는 항상 () 와 함께 썼었거든요.
찾아봤더니만 sizeof 가 type의 크기를 알아볼 때는
sizeof(type) 식으로 쓰게 되어 있네요.
unary-expression 의 크기를 알아볼 때는 괄호가 필요 없고요.
근데 sizeof 가 unary operator 라서 상당히 우선 순위가 높기 때문에
대부분 괄호를 필요로 할 듯 하네요.
흠...
printf 와 비슷하게 만들기는 그렇게 어렵지 않을텐데요..포맷 스
printf 와 비슷하게 만들기는 그렇게 어렵지 않을텐데요..
포맷 스트링의 내용을 확인하면서
%d 와 같은 directive 가 나올 때마다 포맷 스트링이 저장된
뒤쪽의 스택을 하나씩 쫓아가면서 출력해주면 되니까요...
머 적당히 이정도면 쉽게 짜실 수 있을텐데요..
http://home.postech.ac.kr/~sodomau
댓글 달기