리눅스에서 chmod 명렁어를 c언어로 구현중입니다.

yungyuhyun54의 이미지

리눅스에서 chmod 명렁어를 c언어로 구현중입니다.

-v옵션을 구현하고있는데,

변경할 파일을 open으로 열어서 파일디스크립터 fd에 넣고
fstat 함수로 파일디스크립터와 stat구조체 주소를 넣고
변경전의 st_mode를 받아와서 출력해주고
변경후의 st_mode를 받아와서 출력해주는 소스입니다.

그런데 첫번째 파일이 자꾸 고정된 값으로 출력이 됩니다.
파일을 여러개 넣으면 첫번째 파일만 비정상출력, 나머지는 정상적으로 출력됩니다.

여러개 넣은 파일의 순서를 바꿔도 첫번째 파일만 비정상출력됩니다.
(이미지 - 오류1.png)

오류1 그림에서 8진수 100755의 100은 일반파일이고
20620의 20은 문자 장치라는데 이 부분이랑 관련이 있는지 궁금합니다.

chmod-v.png는 해당 부분 소스입니다.
perm.png는 권한을 출력해주는 perm함수 부분의 소스입니다.
이유를 도저히 모르겠어서 질문드립니다.

File attachments: 
첨부파일 크기
Image icon 오류1.png50.69 KB
Image icon chmod-v.png89.01 KB
Image icon perm.png68.95 KB
세벌의 이미지

이미지 대신 텍스트 형식으로 첨부 해주세요.
소스를 복사 붙이기 해서 테스트 해 보게요.

익명 사용자의 이미지

잘못 짠 프로그램은 프로그래머의 예상을 빗나가는 방식으로 잘못 동작할 수 있다는 사실의 교과서적인 예시로군요.

문제의 원인은 fd=(open(argv[i],O_RDWR))==-1가 프로그래머의 의도와 전혀 다른 방식으로 파싱된다는 데 있습니다.
대입을 먼저 하고 비교를 하고 싶으셨겠지만, 그렇게 되지 않지요.

사실 워낙 유구한 문제인지라 경험 있는 프로그래머라면 습관적으로 표현식의 일부분으로 대입문을 쓸 때는 괄호로 감싸게 됩니다.
귀하께서도 그렇게 하려고 하셨던 것 같은데 엉뚱하게도 open function call만 괄호로 감싸셨네요.

문제하고는 별개로, 왜 이렇게 했을 때 "첫 파일만 빼고 잘 동작하는" 결과가 나오는지가 진짜 진국입니다. 아주 어려운 문제는 아니니까 나중에 이 스레드를 보실 분들이 직접 풀어보실 수 있게 스포일러는 하지 않을게요. 그걸 몰라도 질문자의 문제는 해결할 수 있을 테니까요.

종합적으로 볼 때 정말 교과서적인 연습 문제로군요. 그러니까 교훈을 정리하면...

1. 대입문을 부분 표현식에 쓸 때는 괄호를 꼭 쓰세요. 대부분의 경우에 필요합니다. 아니, 일반적으로 그냥 우선순위를 엄격히 따질 자신이 없으면 괄호와 친하게 지내면 됩니다.

2. 컴파일이 잘 되더라도, 그리고 대부분의 경우에 잘 도는 것 같더라도 어처구니 없는 실수가 남아있는 경우가 있지요. 테스트를 엄격히 해 봐야 하는 이유입니다. 예를 들어 이 프로그램의 경우는 open이 -1을 반환하는 경우를 직접 테스트해봤다면 무엇과 관련해서 문제가 있었는지 좀 더 빨리 눈치채실 수 있었을 겁니다.

0. 질문할 때 텍스트 데이터는 텍스트로 올려주세요. 이건 기본적인 예의입니다. 문제가 충분히 재밌지 않았다면 이런 글은 답글도 별로 달고 싶지 않았을 겁니다.

세벌의 이미지

익명의 고수님!

0. 질문할 때 텍스트 데이터는 텍스트로 올려주세요. 이건 기본적인 예의입니다.
제 말이 그말입니다.
문제의 원인은 fd=(open(argv[i],O_RDWR))==-1 가 프로그래머의 의도와 전혀 다른 방식으로 파싱된다는 데 있습니다.
이미지 파일만 보고 문제의 원인을 알아내는 그대는 고수!

저 정도는 컴파일할 때 에러는 아니더라도 경고 뜰텐데, 질문하신 분이 제대로 안 보신 듯.

작성자입니다.의 이미지

아직 학생이라 기본적이고 기초적인 부분이 많이 부족해서 여러가지로 죄송합니다.
오류메세지가 뜨면 좋을텐데 안뜨면 어디서 틀렸는지 감도 안오더군요 ㅠㅠ
소스에 관련해서 질문하는게 처음이라서 소스를 돌려보기위해 복사해서 쓴다는것을 생각을 못했습니다. 그리고 쓰신글을 보면서 코드를 어떤식으로 작성해야 하는지 이것 저것을 깨닫게 되었습니다.
답글 달아주셔서 감사합니다

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.