[완료]C 언어. write 함수로 파일에 내용 쓰기....

heodh의 이미지

리눅스(우분투 9.04)에서 책을 보면서 공부를 하고 있습니다.

프로그램 내용은 file(data.txt)를 만들고, 열어서 buf에 담긴 내용을 넣는 것인데, 오류는 나지 않고 실행은 되는데 data.txt 파일은 내용이 없습니다.

코드는 아래와 같고, 리눅스에서 ls -al한 결과는 아래 그림으로 첨부합니다.

 1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4 #include <sys/types.h>
  5 #include <sys/stat.h>
  6 #include <fcntl.h>
  7
  8 void error_handling (char* message);
  9
 10 int main (void)
 11 {
 12     int fildes;
 13     char buf[]="Let's Go\n";
 14
 15     fildes=open("data.txt", O_CREAT | O_WRONLY | O_TRUNC);
 16     if (fildes== -1)
 17         error_handling("open() error\n");
 18     printf("File descriptor: %d\n", fildes);
 19     printf("buf: %s", buf);
 20
 21     if(write(fildes, buf, sizeof(buf) == -1))
 22         error_handling("write() ERROR\n");
 23
 24     close(fildes);
 25     return 0;
 26 }
 27
 28 void error_handling(char* message)
 29 {
 30     fputs(message, stdout);
 31     fputc('\n', stdout);
 32     exit(1);
 33 }
 34

그리고 ls -al결과를 보면 data.txt화일이 빨간색으로 하이라이팅(?)이 되어있는 것도 이상하고 소유자의 실행 퍼미션이 S로 되어 있는 것도 이상합니다. umask는 0022로 되어있습니다.

초보입니다. 조금은 자세한 설명 부탁드립니다.

File attachments: 
첨부파일 크기
Image icon ls.jpg5.98 KB
grimnir의 이미지

if(write(fildes, buf, sizeof(buf) == -1))

이 문장을 보면 sizeof(buf) == -1 이라는 것이 write의 3번째 인수로 들어갑니다
문장은 false 이므로 결국 0바이트를 쓰라는 명령이 되지요
if 문 안에서 에러 처리를 하다보면 이런 버그가 만들어지기 쉽습니다

res = write(fildes, buf, sizeof(buf));
if(res == -1)

이런식으로 쓰는 것이 좋을 듯 합니다

퍼미션 문제

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

플래그 뒤에 0666 같은 퍼미션이 써있지 않아서 임의로 만들어 진 듯 합니다.
위와 같은 방식으로 반복해서 실행해 보면 퍼미션이 계속 바뀌는 것을 확인할 수 있습니다
생성되는 파일의 퍼미션은 (mode & ~umask) 인데 mode가 입력되지 않아서
임의의 값이 계산된 결과인 것 같습니다

[root@hpml argo]# ./a.out
[root@hpml argo]# ls -al data.txt
-rwS--x--T 1 root root 0 Mar 21 23:49 data.txt
[root@hpml argo]# rm -f data.txt
[root@hpml argo]# ./a.out
[root@hpml argo]# ls -al data.txt
-rws--x--T 1 root root 0 Mar 21 23:49 data.txt
[root@hpml argo]# rm -f data.txt
[root@hpml argo]# ./a.out
[root@hpml argo]# ls -al data.txt
--wsr-x--T 1 root root 0 Mar 21 23:49 data.txt
[root@hpml argo]# rm -f data.txt
[root@hpml argo]# ./a.out
[root@hpml argo]# ls -al data.txt
------s--T 1 root root 0 Mar 21 23:49 data.txt
[root@hpml argo]# rm -f data.txt
[root@hpml argo]# ./a.out
[root@hpml argo]# ls -al data.txt
---s--x--T 1 root root 0 Mar 21 23:49 data.txt

heodh의 이미지

결국 '== -1'의 위치가 바뀌어서 생긴 '교묘한 오류'였군요......

차근차근 살펴봤으면 찾을 수 있었겠지만, 그렇게 못했습니다. 예전에 fflush관련 예제를 리눅스에서 해보면서 예상대로 나오지 않아서 찾아보니 리눅스에서는 정상 작동이 안한다(?)는 내용을 찾아 봤던 기억이 있어서, 이 것도 그런건가하고 생각하고 그냥 지나쳤었는데..... 이건 그런 경우도 아니었군요......

감사합니다. 많이 배웠습니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.