합성이벤트

jQuery의 사용자 정의 핸들러로 .toggle()과 .hover() 메서드가 있으며, 합성 이벤트 핸들러라고 부른다.


.toggle() 메서드

두 개 이상의 함수 인자를 가진다.

처음 클릭하면 첫 번째 함수가 실행, 두 번째 클릭하면 두 번째 함수가 실행된다.


.toggleClass() 메서드

클래스의 존재 유무를 검사해 자동으로 추가하거나 제거해준다.

$('#btn').toggleClass('hidden'); // hidden 클래스가 btn에 있으면 제거, 없으면 추가


.hover() 메서드

두 개의 함수를 인자로 가진다.

마우스 커서가 들어가면 첫 번째 함수가 실행, 커서가 벗어나면 두 번째 함수가 실행된다.

$('#btn').hover(function() {

$(this).addClass('hover');

}, function() {

$(this).removeClass('hover');

});


이벤트의 여행

페이지에서 이벤트가 발생하면 DOM 전체 계층에 있는 모든 요소가 이벤트를 처리할 기회를 가진다.

반응에 대한 책임!


- 이벤트 캡처링

모든 것을 감싸고 있는 최상위 요소에게 이벤트가 처음으로 주어지고 그 후 연속해서 하위 요소로 전달된다.


- 이벤트 버블링

가장 낮은 자식 요소에 처음으로 전달되고, 반응 후 부모 요소에게 전파된다.


이벤트는 두 가지 과정 각각에 등록할 수 있다.

jQuery는 버블링 단계에 이벤트 핸들러를 등록한다. -> 첫 번째 이벤트 반응이 항상 최하위 특정 요소임을 보장받음


이벤트 버블링의 부작용

<div> <-  여기에 mouseout 이벤트 핸들러가 걸려 있는데

<a>test</a> <- 여기 커서를 벗어나면 mouseout 이벤트가 보내질 것이고, 버블링되어 div에 걸려있는 mouseout 이벤트 핸들러가 실행 될것이다.

</div>

원치 않는다! .mouseenter과 .mouseleave 이벤트는 개별적으로 연결되고, .hover()메서드로 문제를 방지할 수 있다.


진행 경로 수정하기 : 이벤트 객체

<div> <- 여기에 클릭하면 사라지게 이벤트 핸들러를 걸어놨는데,

<button>btn</button> <- 버튼 클릭하면 div가 사라진다. 이벤트 버블링 때문에!

</div>

이벤트 객체에 접근 할 수 있어야한다. -> 이벤트가 발생할 때 각 요소의 이벤트 핸들러로 넘겨지는 DOM 객체!

$(document).ready(function() {

$('#mydiv').click(function(event) { // 매개변수를 추가하면 된다. 이름은 자유.

if(event.target == this) {

$('.btn').toggleClass('hidden');

}

});

});

event 변수를 추가함으로써 핸들러에서 이벤트 객체를 사용할 수 있다.

event.target 프로러티를 사용하면 어느 이벤트가 처음으로 받은 요소인지(click 이벤트는 실제로 클릭된 요소) 알 수 있다.

this는 현재 이벤트를 처리하고 있는 DOM 요소이다.

이벤트를 받고 있는 애가 지금 처리하고 있는 mydiv일 때만(this) 버튼들을 숨긴다. 버튼을 누르면 안숨긴다.


.stopPropagatin() 메서드를 이용하여 이벤트 객체는 버블링 과정을 완전히 중단 할 수 있다.

기본 동작을 원치 않을 때 이벤트에 .preventDefault() 메서드를 호출하면 이벤트에 의해 기본 동작이 수행되는 일을 방지 할 수 있다. -> 잘 이해가 되지 않는다..ㅜㅜ


이벤트 위임

이 부분 잘 이해되지는 않는데, 버블링을 이용해서 이득을 얻을 수 있는 기법이라는 것 같다.

이벤트 위임을 활용해서 하나의 요소가 다른 여러가지 작업을 수행할 수 있도록 핸들러를 추가할 수 있다.

성능과 관련해서 얘기하는 것 같다...;

.is()는 현재 jQuery 객체가 지정한 선택자 표현식을 만족시키는지 검ㄴ사, 선택자에 해당하는 요소가 하나라도 있으면 true 반환.


이벤트 핸들러 제거하기

.unbind() 메서드를 사용한다.

$('.btn').unbind('click');


이벤트 네임스페이스 -> 잘 모르겠으나, 함수를 나중에 쓰기 위함인듯.. bind('식별하고자하는 이벤트이름', function()');


이벤트 다시 바인딩하기

funciton 함수가 변수에 할당된 경우를 종종봤는데, 이게 도대체 다른 점이 무엇인가 생각했었는데, 핸들러에 함수에 이름을 부여하는 것이었다.

var myfun = function(event) { ... };

나중에 이 함수를 다시 바인딩하고 싶을 때는 .bind('click', myfun); 이렇게 사용한다.

.one() 메서드는 이벤트 핸들러가 한 번만 호출된 후 바로 해제되기를 원하는 상황에서 사용한다.

$('.btn').one('click',myfun);


사용자 상호작용 흉내 내기

실제 이벤트가 발생하지 않았지만, 이벤트 핸들러 코드를 실행하고 싶을 때!

예로 페이지 로드할 때 원하는 객체에 click 이벤트가 실행된 상태에서 로드되길 원할 때!

$('.btn').trigger('click'); = $('.btn').click();


키보드 이벤트

종류 1. 키보드에 직접 반응하는 이벤트(keyup, keydown) - 어떤 키를 눌렀는지 알고 싶으면

종류 2. 텍스트 입력에 반응하는 이벤트(keypress) - 어떤 글자가 입력됐는지 알고 싶다면

키보드 이벤트 대상은 포커스를 가진 요소!

어떤 키를 눌렀는지 알기 위해 event 객체를 조사한다.

event.keyCode 프로퍼티는 눌려진 키에 대한 식별 값이 있 으며, 알파벳 키에 대해서 이 값은 대문자 ASCII 값이다.

그러므로 글자가 눌릴 때 매핑시키는 맵 또는 문자 객체를 만들어서 맵에 있는 확인하고, 그 값에 따라 이벤트 실행.

p.80

'개발 > Web' 카테고리의 다른 글

크롬확장프로그램 개발  (0) 2013.01.12
2012. 12. 03. 학습일지(3장-01)  (0) 2012.12.03
2012. 11. 30. 학습일지(2장-02)  (0) 2012.11.30
2012. 11. 29. 학습일지(2장-01)  (0) 2012.11.30
2012. 11. 28. 학습일지(1장)  (0) 2012.11.29

3장은 이벤트 처리와 관련된 내용을 학습합니당.

이벤트 처리란 jQuery 코드가 원하는 시점에 수행되게 하는 것!


페이지 로드 시점에 작업 수행하기


페이지가 로드될 때 작업을 수행하게 하는 이벤트에는

  1. $(document).ready() : DOM이 로드돼 사용할 준비가 끝나는 시점에 바로 호출. DOM 트리로 파싱되자마자 되기 때문에 다른 관련 파일(이미지 등)을 내려 받은 완료 상태와 상관없이 실행. (이미지와 높이와 너비 같은 속성을 항상 사용할 수 있는 건 아니라는!)
  2. window.onload : 모든 도큐먼트를 브라우저로 완전히 내려받은 뒤 발생. 모든 요소에 접근 가능.

가 있습니다.


한 페이지에 여러 스크립트 사용하기

  • window.onload = doStuff; 하고 또 window.onload = doStuff2; 하면 처음 줄은 제거됨.
  • .onload 속성은 오로지 하나의 함수만 저장 가능
  • $(document).ready() : 여기에서 호출해 추가한 함수는 모두 내부의 큐에 추가되어 페이지가 로드될 때 등록된 모든 함수를 순서대로 실행

※ 함수의 참조 vs 호출

  • 함수를 핸들러에 할당할 때 괄호는 제외하고 함수 이름만 사용해야 함.
  • 괄호가 있으면 함수가 즉각 호출
  • 괄호가 없으면 참조만 하고 나중에 이 참조를 통해 사용 가능
※ 아래 두 코드는 같은 코드

 $(document).ready(function() {

     // ...

});

 $(function() {

     // ...

});


.ready() 콜백 함수에 인자 넘기기

  • 여러 라이브러리 사용시 $ 식별자 충돌 막으려면
  • jQuery.noConflict(); 을 호출하여 $에 대한 제어권을 놓아줌
  • 그러면 이제 $(document).ready() 가 아니라 jQuery(document).ready()라고 써야함
  • 하지만 콜백 함수는 jQuuery 객체 자체를 인자로 받을 수 있음
  • jQuery(document).ready(function($) { ... }); = jQuery(function($) { ... });
  • 이러면 내부에서도 $ 사용 가능!! 꺄!!

기본 이벤트


.bind() 메서드

  • DOM 이벤트에 행위자를 할당하는 역할
$(document).ready(function() {
   $('#switcher-large').bind('click', function() {
      $('body').addClass('large');
   });
});
  • 이러면 click 이벤트에 해당 function 할당ㅋ

이벤트 핸들러 컨텍스트

  • 이벤트 핸들러가 실행되는 동안 사용할 수 있는 키워드 this
  • 핸들러가 연결된 DOM 요소를 가리킴!!
  • $() 함수가 DOM 요소를 인자로 받을 수 있다는 사실 -> $(this)를 사용하여 핸들러 연결된 DOM 요소에 이벤트 추가ㅋ
※ 리팩토링
  • 기존 코드와 같은 작업을 수행하면서 좀 더 효과적인 방식으로 수행되게 코드를 개선하는 것을 의미
  • 리팩토링 잘하고 싶다 ㅎㅎㅎ
간소화된 이벤트
  • bind()와 같은 기능을 하면서도 짧게 기술!
  • .bind('click',function() { ... }); = .click(function() { ... } );
  • 그 외 : blur, change, dbclick, error, focus, keydown, keypress, keyup, load, mousedown, mousemove, resize, scroll, select .... 등등ㅋ


'개발 > Web' 카테고리의 다른 글

크롬확장프로그램 개발  (0) 2013.01.12
2012.12.07 학습일지(3장-02)  (0) 2012.12.07
2012. 11. 30. 학습일지(2장-02)  (0) 2012.11.30
2012. 11. 29. 학습일지(2장-01)  (0) 2012.11.30
2012. 11. 28. 학습일지(1장)  (0) 2012.11.29

DOM 순회 메서드


부모나 조상 요소를 선택하고자 할 때, 위로 혹은 아래로, 모든 DOM 트리 전체를 쉽게 검색할 수 있는 DOM 순회 메서드!


▶ .filter() 메서드 : 인자로 함수(function)를 지정할 수 있는 강력한 메서드!

예로 모든 외부 링크에 클래스 추가하려고 할 때..

$('a').filter(function() {

return this.hostname && this.hostname != location.hostname;

}).addClass('myClass');

href 속성 값이 도메인 네임을 포함하고, 링크된 도메인 네임과 일치하지 않을 때 addClass()!



▶ 특정 셀 선택하기

1) .next() : 바로 뒤의 형제요소를 반환한다.

2) .nextAll() : 바로 뒤의 모든 셀 선택

3) .prev() : 바로 앞의 형제 요소 반환

4) .prev() : 바로 앞의 모든 셀 선택

5) .silblings() : 같은 DOM 레벨 요소 선택

6) .andSelf() : 자신 요소 선택

7) .parent() : DOM 레벨상에서 한 단계 위로 이동

8) .children() : 그 행의 모든 셀 선택


DOM 요소 접근하기


jQuery 객체가 감싸고 있는 DOM 요소에 직접 접근하고자 할 경우!


.get(n) : n+1번째 DOM 요소 접근


$('#element').get(0).tagName : jQuery 객체가 참조하고 있는 첫 번째 DOM 요소에 접근. 아이디가 element인 요소의 태그 이름 알아오기

= $('#element')[0].tagName : 간단한 표기법

'개발 > Web' 카테고리의 다른 글

크롬확장프로그램 개발  (0) 2013.01.12
2012.12.07 학습일지(3장-02)  (0) 2012.12.07
2012. 12. 03. 학습일지(3장-01)  (0) 2012.12.03
2012. 11. 29. 학습일지(2장-01)  (0) 2012.11.30
2012. 11. 28. 학습일지(1장)  (0) 2012.11.29

02. 요소 선택


jQuery의 가장 강력한 특징 중 하나는 DOM 요소를 쉽게 선택할 수 있는 능력입니다.

다양한 선택자와 메서드로부터 얻는 결과는 항상 jQuery 객체입니다.


선택자 종류


▶ $() 함수

CSS에서 사용할 수 있는 표현이라면 무엇이든 문자열 형태로 $() 함수에 넘겨주면 해당 요소에 jQuery 메서드를 적용할 수 있습니다.

$(달러표시)는 jQuery의 줄인 표현입니다.


선택자의 세 가지 구성요소는 다음과 같습니다.

1. 태그명 (ex : $('div'))

2. ID (ex : $'#some-id'))

3. 클래스 (ex : $('myclass'))


$() 함수를 사용하면 요소의 집합에 접근하기 위해 직접 for 반복문을 사용할 필요가 없습니다.


▶ CSS 선택자

$('#selected-plays > li').addClass 등등 ........ : 최상위 항목에만 추가할 수 있게 자식 콤비네이터(>)를 사용. 자식요소 중에서 li를 찾음!

$('#selectd-play li : not(.horizontal') : horizontal 클래스를 가지고 있지 않은 #select-play의 자손 li 선택!


▶ 속성 선택자

 속성 선택자는 정규 표현식과 유사한 문법 지원합니다.


1. ^=a : a로 시작하는

2. $=b : b로 끝나는

3. *=c : c를 포함하는


$('a[href^="mailto:") : a 태그의 href 속성이 mailto로 시작할 때

$('a[herf$=".pdf") : a 태그의 href 속성이 pdf로 끝날 때

$('a[href^="http"][href*="henry"]) : a 태그의 href 속성이 http로 시작하며 henry를 포함할 때


▶ 사용자 정의 선택자 (성능이 굉장히 중요할 때는 자주 이용하지 않는 편이 좋습니당!)

CSS의 의사 클래스 구문처럼 선택자의 구문은 콜론(")으로 시작합니다.


1. :eq(n) : n+1 번째 (n은 0부터 시작하기 때문!)

2. :odd, :even : 홀수, 짝수

3. :nth-child(n) : n번째 (1부터 시작하는 유일한 jQuery 선택자!)

4. :contains(text) : text를 포함하는


$('div.myclass:eq(1)') : myclass를 가지는 2번째 div

$('tr:even') : 홀수 번째 tr (홀수인데 even을 사용한 이유는 첫 번째 행은 0, 두번 째 행은 1로 표현하기 때문!)

$('tr:nth-child(odd)') : 홀수 번째 tr

$('td:contains(Henry)') : Henry라는 텍스트를 포함한 td (대소문자를 구분합니다!)


▶ 폼 선택자

위치 기반 요소 검색에 한정되어 있지 않고, 폼 선택자로 원하는 요소만 간단하게 뽑아낼 수 있습니다.


1. :input : 입력, 텍스트영역, 셀렉트, 버튼 요소

2. :button : 버튼 요소와 type 속성이 button인 input 요소

3. enabled : 활성화된 폼 요소

4. disabled : 비활성화된 폼 요소

5. :checked : 선택된 라디오 버튼 혹은 체크박스

6. :selected : 선택된 옵션 요소


$('input[type="radio"]:checked) : 선택된 라디오 입력 요소

$('input[type="password"] : 모든 비밀번호 입력 요소

$('input[type="text"]:disabled') : 모든 비활성화된 입력 요소


'개발 > Web' 카테고리의 다른 글

크롬확장프로그램 개발  (0) 2013.01.12
2012.12.07 학습일지(3장-02)  (0) 2012.12.07
2012. 12. 03. 학습일지(3장-01)  (0) 2012.12.03
2012. 11. 30. 학습일지(2장-02)  (0) 2012.11.30
2012. 11. 28. 학습일지(1장)  (0) 2012.11.29

오늘부터 jQuery를 제대로! 공부해보려고 해요.

마침 jQuery 온라인 스터디가 있길래 함께 참여하면서 제 블로그에도 같이 포스팅하도록 할게요.

그럼 jQuery를 정복하는 그 때를 위하여 화이팅!ㅎㅎㅎ


01. jQuery 시작하기


jQuery의 개념 대부분은 HTML 구조와 CSS(Cascading Style Sheets)로부터 나왔습니다.


jQuery 핵심 기능

  1. 도큐먼트 요소에 접근 : 선택자 메커니즘을 이용하여 문서 객체 모델(DOM) 트리에 접근할 수 있습니다.
  2. 페이지의 스타일 변경 : 페이지가 렌더링 된 이후에도 CSS 스타일을 따로 변경할 수 있습니다.
  3. 도큐먼트 내용 변경 : 도큐먼트 내용 자체도 변경할 수 있습니다.
  4. 페이지와 사용자 간 상호작용 처리 : 사용자 링크 클릭 등을 포함한 다양한 이벤트를 가로채 처리하는 방식으로 이벤트 핸들러를 추가할 수 있습니다.
  5. 도큐먼트의 변화를 표시하는 애니메이션 추가 : 페이드(fade), 와이프(wipe)와 같은 시각적인 효과를 제공합니다.
  6. 페이지를 새로고침하지 않고 서버에서 정보 가져오기 : Ajax 기능을 제공합니다.
  7. 일반적인 자바스크립트 작업을 단순화
jQuery가 좋은 이유
  1. CSS 지식을 최대한 활용 : CSS 선택자 사용
  2. 확장 지원 : 피처 크리프를 피하기 위해 플러그인으로 사용
  3. 브라우저의 차이로부터 해방 : 추상화된 레이어를 제공함
  4. 언제나 집합으로 작업 : 묵시적 반복 기법
  5. 여러 동작을 한 줄에 작성 : 객체에 대한 메서드가 객체 자신을 반환값으로 반환함으로써 다시 새로운 동작을 해당 객체에 적용할 수 있게 해줌
  6. 매우 작은 크기의 패키지
  7. 모든 사람에게 무료로 제공
jQuery 사용하기


- 공식 jQuery 웹사이트(http://jquery.com/)에서 JS파일을 다운로드하여 HTML 도큐먼트에서 <script> 요소로 jQuery 파일을 포함하기만 하면됩니다.

- 혹은 자체 콘텐트 전송 네트워크(CDN)으로도 이용할 수 있습니다.

- 다른 스크립트를 로드하기 전에 jQuery 라이브러리를 로드해야합니다.


연습


▶ CSS Class 변경하기

$(document).ready(function() {

$('div#mydiv').removeClass('nomal'); // 원래 적용되어있던 nomal Class 를 지우고

$('div#mydiv').addClass('highlight'); // highlight Class를 추가한다.

});

  • $() 함수를 호출하면 jQuery 객체 인스턴스를 반환합니다.
  • $(document).ready() 함수를 사용하여, DOM이 로드되는 즉시 함수를 호출합니다.
  • 위의 예제는 익명함수(람다함수)로, 익명함수 기능은 메서드가 함수를 인자로 받지만 이 함수를 다시 사용하지 않을 때 편리하게 사용할 수 있습니다.
▶ console.log()
  • 보통 값을 확인하기 위하여 alert() 함수를 사용했지만, 이 함수의 대안으로 console.log()를 사용할 수 있습니다.
  • colsole.log() 메서드에 어떤 종류의 표현식도 넣을 수 있으며, 크롬에서는 F12를 눌러 Colsole 항목에서 값을 확인할 수 있습니다.

'개발 > Web' 카테고리의 다른 글

크롬확장프로그램 개발  (0) 2013.01.12
2012.12.07 학습일지(3장-02)  (0) 2012.12.07
2012. 12. 03. 학습일지(3장-01)  (0) 2012.12.03
2012. 11. 30. 학습일지(2장-02)  (0) 2012.11.30
2012. 11. 29. 학습일지(2장-01)  (0) 2012.11.30

디렉토리


  • ● 디렉토리란? 파일 이름들의 집합으로, 파일들을 논리적으로 관련 그룹별로 나누어주는 수단을 제공한다. 디렉토리는 파일뿐 아니라 다른 디렉토리를 토함할 수 있으며, 계층적인 트리 구조를 거꾸로 놓은 것과 같이 묘사될 수 있다.

어떤 디렉토리이든 맨 위에는 루트 디렉토리라 불리는 하나의 디렉토리가 있다. 

이것은 '/' 라는 기호를 사용하여 표현하며, 트리의 단말 노드들은 보통 파일, 특수 파일, 빈 디렉토리이다.

  • ● 현재 작업 디렉토리란? 로그인한 사용자는 현재 작업 디렉토리라고 불리는 파일 구조의 특정한 장소에서 작업을 하게 되는데, 초기 설정 값은 그 사용자의 홈 디렉토리이다.

디렉토리 구조

구조적으로 디렉토리는 일련의 디렉토리 항으로 구성된다.

각 디렉토리항은 최소한 다음과 같이 구성된다.



 i-node 번호


파일 이름을장하는 문자 필드 


i-node 번호는 한 파일을 유일하게 식별한다. 

i-node 번호는 i-node 구조라 불리는 파일에 대한 모든 정보를 저장하고 있는 자료구조를 찾기 위해 운영체제에 의해 사용된다.


점(.)과 이중점(..)


모든 디렉토리 안에는 점(.)과 이중점(..)이라는 이상한 파일이름이 들어가있다.


사실 점(.)현재 디렉토리를 의미하고, 이중점(..)은 현재 디렉토리의 부모 디렉토리를 가리키는 표준 표기법이다.

즉, 현재 디렉토리와 부모 디렉토리에 대한 링크인 것이다!


디렉토리 허가


보통 파일과 같이 디렉토리도 소유자, 소유자와 같은 그룹의 사용자들, 그 외 사용자들에 대한 접근 허가를 가진다.

표기법도 보통 파일과 같이 표현하지만, 조금은 다르게 해석된다.

  • ● 디렉토리에 대한 읽기 허가 : 디렉토리 내에 있는 파일이나 부디렉토리의 이름을 리스트할 수 있음을 뜻한다. 그러나 각 파일 자체에 저장된 정보를 읽을 수 있다는 것은 아니다. 즉, 디렉토리내 각 파일은 각 파일의 독립된 접근 허가에 의해 제어된다!
  • ● 디렉토리에 대한 쓰기 허가 : 디렉토리 내 기존의 파일을 제거하고 같은 이름의 새로운 파일을 만들 수 있음을 뜻한다. 그러나 파일의 내용을 변경시킬 수 있다는 것을 뜻하지는 않는다.
  • ● 디렉토리에 대한 실행 허가 : 탐색 허가로도 불리며, chdir 시스템 호출을 사용하여 사용자가 디렉토리 내부로 들어가는 것을 허용한다. 파일을 열거나 프로그램을 실행시키기 위해서는 각 파일의 독립된 접근 허가에 따른다.

디렉토리와 시스템 호출

디렉토리를 조작하기 위해서서는 앞서 배운 보통 파일과는 다른 시스템 호출을 이용해야 한다.
즉, creat나 open 시스템 호출의 사용이 불가능하다.
이러한 제약 조건은 write를 사용해서 디렉토리를 변경하는 것을 막기 위해서이다.

  • ● 디렉토리의 생성
#include <sys/types.h>
#include <sys/stat.h>

int mkdir(const char *pathname, mode_t mode);


첫 번째 인수는 생성될 디렉토리의 경로이름이고, 두 번째 인수는 접근 허가 집합이다.


int retval;

retval = mkdir("/tmp/dir", 0777);


디렉토리의 생성에 성공하면 0을 반환하고, 실패시 -1을 반환한다.


mkdir은 새로 생성된 디렉토리에 두 개의 링크 '.'(점)과 '..'(이중점)을 넣는다.

만약 이 두 개의 링크가 존재하지 않으면 그 항은 디렉토리로 사용할 수 없을 것이다!


  • ● 디렉토리 제거
#include <unistd.h>

int rmdir(const char *pathname);


디렉토리를 제거하고 싶을 경우 rmdir 시스템 호출에 파라미터로 제거할 디렉토리 경로를 입력하여 주면 된다.

이 호출은 디렉토리가 비어있을 경우(단지 .과 ..만을 포함할 경우를 말한다!!)에만 성공적이다!


● 디렉토리 열기

#include <sys/types.h>

#include <dirent.h>


DIR *opendir(const char *dirname);


opendir의 인수는 개방할 디렉토리의 경로이름이다.

만약 성공적으로 개방한다면, 이 호출은 DIR 유형에 대한 포인터를 반환한다.

헤더파일 <dirent.h>에 하나의 디렉토리 스트림을 나타내는 DIR 유형에 대해 정의되어있다.


열려고 하는 것이 디렉토리이기 때문에 처음 open하면(성공시) 디렉토리 스트림에 대한 포인터가 디렉토리의 첫 항에 위치한다.

만약 호출에 실패하면 시스템은 널(null) 포인터를 반환한다!

그러므로 오류 검사코드는 널 포인터인지 아닌지를 검사해야할 것이다!


● 디렉토리 닫기

#include <dirent.h>


int closedir(DIR *dirptr);


closedir 시스템 호출은 인수가 가리키는 디렉토리 스트림을 닫는다.


● 디렉토리 읽기

#include <sys/types.h>

#include <dirent.h>


struct dirent *readdir(DIR *dirptr);


readdir 시스템 호출은 opendir을 통해 얻은 디렉토리 스트림 포인터를 파라미터로 받는다.

이렇게 개방된 디렉토리를 readdir을 통해 읽으면 첫 호출에 의해 디렉토리의 첫 항이 struct dirent로 읽혀 들여진다.

호출이 끝나면, 디렉토리 포인터는 다음 항으로 이동해 있을 것이다.

그렇게 읽고 난 후 디렉토리의 끝 항에 도달하면 널 포인터를 반환하게 된다.


여기서, 디렉토리를 처음부터 다시 읽고 싶다면 다음과 같은 시스템 호출을 사용하면 된다.


#include <sys/types.h>

#include <dirent.h>


void reinddir(DIR *dirptr);


rewinddir 호출은 첫 항으로 돌아가길 원하는 디렉토리 스트림 포인터를 파라미터로 받는다!


다음 예는 개방한 디렉토리 내의 모든 디렉토리항 이름을 출력한다. (i-node 번호가 유효한지 검사하면 된다.)


..

...

while( d = readdir(dp) ) { // opendir로 dp를 얻었다고 가정

if( d->d_no != 0 )

printf("%s \n", d->d_name);

}

...

..






'개발 > System' 카테고리의 다른 글

임베디드 스케치 공부  (0) 2019.11.19
특정 파일 UTF8 ↔ ANSI 변환  (0) 2013.08.24
파일 정보의 획득  (0) 2012.10.29
다수의 이름을 갖는 파일  (0) 2012.10.29
access, chmod, chown 시스템 호출  (0) 2012.10.29

stat와 fstat 시스템 호출


파일에 대한 정보를 알고 싶을 떄에는 stat와 fstat를 이용한다.


#include <sys/types.h>

#include <sys/stat.h>


int stat(const char *pathname, struct stat *buf);

int fstat(int filedes, struct stat *buf);


먼저 stat에 대해서!

첫 번째 인수는 정보를 알고 싶은 파일 경로이름이다.

두 번째 인수는 이 호출이 성공하면 정보들이 저장될 구조체이다.


다음으로 fstat에 대해서!

첫 번째 인수는 정보를 알고 싶은 파일 경로이름이 아니라, 개방되어있는 파일 기술자이다.

두 번째 인수는 stat와 동일하다.


..

...

struct stat s;

int fd;


fd = open("/tmp/myfile", O_RDWR);


stat("/tmp/myfile", &s);


fstat(fd, &s);


stat 구조에 대한 정의는 헤더파일 <sys/stat.h>에서 찾을 수 있으며, 이 구조에서 사용되는 자료형은 헤더파일 <sys/types.h>에 있다.

다음은 stat의 구조에 대한 설명이당.


자료형 

변수명 

의미 

dev_t 

st_dev 

파일이 들어 있는 논리적 장치를 기술함 

ino_t 

st_ino 

inode 번호

mode_t

st_mode 

파일 모드, 요걸 이용하여 허가 계산할 수 있음

nlink_t 

st_nlink

하드링크 계수(비심볼형 링크의 수) 

uid_t 

st_uid 

파일의 사용자 식별번호 

gid_t

st_gid 

파일의 그룹 식별번호 

dev_t 

st_rdev 

파일 엔트리가 장치를 기술하는 데 사용될때 의미를 가짐..(당분간 무시 ㅠㅠ) 

off_t 

st_size 

파일의 현재 논리적 크기를 바이트 수로 표시 

time_t 

st_atime 

마지막으로 읽혔던 시간, open이나 creat할 때 

time_t 

st_mtime 

변경된 시간 기록 

time_t

st_ctime 

stat 구조 자체가 변경될 때의 시간(link, chmod, write 등) 

long 

st_blksize 

파일 시스템 고유의 I/O 블록 크기 기록 

long 

st_blocks 

특정 파일에 할당된 물리적 파일 시스템 블록의 수 기록 




'개발 > System' 카테고리의 다른 글

특정 파일 UTF8 ↔ ANSI 변환  (0) 2013.08.24
UNIX의 디렉토리  (0) 2012.10.29
다수의 이름을 갖는 파일  (0) 2012.10.29
access, chmod, chown 시스템 호출  (0) 2012.10.29
다중 사용자 환경에서의 파일  (0) 2012.10.28

바로가기 아이콘을 만드는 것처럼 UNIX 파일은, 물리적 집합은 중복해서 메모리에 저장되어 있지 않아도 여러 경로이름과 연관될 수 있다.

이러한 것들의 각 이름은 하나의 하드링크라고 하고, 한 파일과 연관된 링크의 수는 그 파일의 링크 계수라고 부른다.

경로이름은 다르게, 아이노드 번호는 같게! (원본 파일의 아이노드 번호를 참조한당 :D)


link 시스템 호출


#include <unistd.h>


int link(const char *orginal_path, const char *new_path);


새 하드링크는 link 시스템 호출로 생성할 수 있다.

첫 번째 인수는 기존 파일 이름의 문자형 포인터이다.

두 번째 인수는 그 파일에 대한 새로운 이름 또는 링크를 가리킨다. new_path는 이미 존재하는 파일이 아니여야한다!


새로운 링크 생성이 성공하면 link 시스템 호출은 0을 반환하고, 오류가 발생하면 -1을 반환한다.


link("/tmp/one/orginal_myfile", "/tmp/two/new_myfile");


link 호출에는 두 가지 중요한 제한이 있는데, 다음과 같다.

  • 디렉토리는 참조할 수 없다.
  • 다른 파일 시스템에 있는 파일을 참조할 수 없다.


앞서 파일을 제거하는 방법 중 하나로 unlink 시스템 호출이 있었다.

unlink 호출은 지명된 링크를 제거하고, 파일의 링크 계수를 하나 줄인다.

만약 링크 계수가 0이되고, 그 파일을 개방한 프로그램이 하나도 없으면, 파일은 시스템으로부터 제거된 것이다!



symlink 시스템 호출


#include <unistd.h>


int symlink(const char *realname, const char *symname);


앞서 link의 두 가지 제한을 보았다. 심볼릭 링크는 특수한 파일의 종류로, 그 내용물인 문자열이 링크가 가리키는 또 다른 파일의 경로이름이다.

link 호출을 이용하면 아이노드 블록을 같이 참조하지만, symlink는 자신만의 아이노드 블록을 가지며, 데이터 블록이 원본 파일 경로를 가리키고 있다.

즉, 심볼릭 링크는 다른 파일에 대한 포인터라고 할 수 있다.



readlink 시스템 호출


#include <unistd.h>


int readlink(const char *sympath, char *buffer, size_t bufsize);


만약 심볼릭 링크 파일이 open으로 개방되면, open 시스템 호출은 심볼릭 링크 파일이 가리키는 파일의 파일 기술자를 반환한다.

readlink는 링크를 따라가지 않고 심볼릭 링크 자체에서 동작하는 시스템 호출이다.

만일 한 프로그래머가 심볼릭 링크 자체에 들어있는 자료를 보고 싶으면 반드시 readlink를 사용해야 한다.


readlink 시스템 호출은 먼저 sympath를 개방하고, 그 파일 내용을 buffer로 읽어 들인다.

반환 값은 버퍼 내의 문자 수를 나타내거나 오류 발생시 -1이다.

심볼릭 링크에 의해 가리켜지고 있는 원래의 파일이 제거되었는데, 그 파일을 이 심볼릭 링크를 통해 접근하려고 하면 오류가 발생한다.



rename 시스템 호출


rename 시스템 호출은 정규 파일, 디렉토리의 이름을 바꾸는 것이다.


#include <stdio.h>


int rename(const char *old_pathname, const char *new_pathname);


첫 번째 인수 old_pathname이 두 번째 인수 new_pathname으로 개명된다.

만약 new_pathname이 이미 존재하면 이를 먼저 제거한 후 old_pathname을 개명한다!


'개발 > System' 카테고리의 다른 글

UNIX의 디렉토리  (0) 2012.10.29
파일 정보의 획득  (0) 2012.10.29
access, chmod, chown 시스템 호출  (0) 2012.10.29
다중 사용자 환경에서의 파일  (0) 2012.10.28
리눅스의 파일 시스템  (0) 2012.10.28

access 시스템 호출


access 시스템 호출은 소유자가 해당 파일의 읽기, 쓰기, 실행 접근 권한을 가졌는지 조사한다.


#include <unistd.h>


int access(const char *pathname, int amode);


첫 번째 인수는 조사하려는 파일명이다.

두 번째 인수는 접근 방법을 나타내는 값으로 다음과 같다.

  • R_OK : 호출 프로세스가 읽기 접근 권한을 가지고 있는가?
  • W_OK : 호출 프로세스가 쓰기 접근 권한을 가지고 있는가?
  • X_OK : 호출 프로세스가 파일을 실행시킬 수 있는가?
  • F_OK : 파일이 존재하는가?
이 시스템 호출의 반환값은 두 번째 인수에 대한 대답에 YES라면 0을 반환하고, 오류 발생시에는 -1을 반환한다.


chmod 시스템 호출


#include <sys/types.h>

#include <sys/stat.h>


int chmod(const char *pathname, mode_t newmode);


chmod 시스템 호출은 기존 파일의 허가를 변경한다.

이 시스템 호출은 허가를 변경할 수 있는 권한을 가진 경우, 즉 파일 소유자나 수퍼 사용자만이 사용할 수 있다.


첫 번째 인수는 변경하려는 파일명이다.

두 번째 인수는 변경할 새로운 파일 모드이다.


if(chmod(pathname, 0644) == -1)

printf("파일 허가 변경에 실패하였습니다.\n");


위와 같이 변경할 새로운 파일 모드를 입력하면 된다.



chown 시스템 호출


#include <sys/types.h>

#include <unistd.h>


int chown(const char *pathname, uid_t owner_id, gid_t group_id);


chown은 파일의 소유자와 그룹을 함께 변경할 수 있다.


첫 번째 인수는 변경하려는 파일명이다.

두 번째 인수는 새 소유자를 나타낸다.

세 번째 인수는 새 그룹을 나타낸다.


성공 시 0을 반환하고, 오류 발생 시 -1을 반환한다.


uid_t와 gid_t는 <sys/types.h>에 정의된 유형들이다.


chown은 파일의 소유자나 수퍼 사용자만 사용할 수 있고, 한 번 소유권이 바뀌면 원래 사용자의 사용자 식별 번호와 파일의 사용자 식별 번호가 서로 달라지기 때문에 이를 취소할 수 없다.

'개발 > System' 카테고리의 다른 글

파일 정보의 획득  (0) 2012.10.29
다수의 이름을 갖는 파일  (0) 2012.10.29
다중 사용자 환경에서의 파일  (0) 2012.10.28
리눅스의 파일 시스템  (0) 2012.10.28
UNIX 파일 접근 프리미티브 : 파일 제거  (0) 2012.10.28

사용자와 소유권


모든 파일은 시스템의 사용자 중 하나에 의해 소유되는데, 보통 파일을 생성한 사용자이다.

각 파일 소유자의 실제 신원은 사용자 식별 번호(uid)라 불리는 양의 정수값으로 표시된다.


그룹과도 연관되어 있는데, 그룹이란 여러 사용자를 포함하는 프로젝트를 제어하는, 직접적인 수단을 제공하는 사용자들의 단순한 집단이다.

각 사용자는 적어도 한 그룹에 속하고, 여러 그룹에 속할 수도 있다.

양의 정수값인 그룹 식별번호(gid)로 파일의 소유 그룹 실제 신원을 알 수 있다.


파일의 소유자 또는 수퍼 사용자는 파일의 소유권을 변경할 수 있다.

수퍼 사용자의 사용자 이름은 보통 root이고, uid가 항상 0이다.


한 파일이 생성될 때, 생성하는 프로세스와 연관된 그룹 식별번호가 사용자 식별번호와 함께 저장된다.


허가와 파일 모드


소유자는 파일에 대한 허가를 선택할 수 있다.

허가는 서로 다른 유형의 사용자들이 파일에 접근할 수 있는 권한을 결정한다.

다음은 사용자의 세 가지 유형이다.

  • 파일의 소유자
  • 파일에 연관된 그룹과, 같은 그룹에 속하는 사용자
  • 그 외 사용자

파일 허가는 세 가지 기본적인 유형이 있는데, 다음과 같다.
  • 파일의 읽기 권한
  • 파일의 쓰기 권한
  • 파일의 실행 권한

시스템은 이러한 파일 허가를 파일 모드라고 불리는 비트 패턴으로 파일에 저장한다.

팔진수 값 

상징형 모드 

의 미 

0400 

S_IRUSR

소유자에게 읽기를 허가함. 

0200 

S_IWUSR 

소유자에게 쓰기를 허가함. 

0100 

S_IXUSR 

소유자에게 실행을 허가함.

0040 

S_IRGRP 

그룹에 대해 읽기를 허가함. 

0020 

S_IWGRP 

그룹에 대해 쓰기를 허가함. 

0010 

S_IXGRP 

그룹에 대해 실행을 허가함. 

0004 

S_IROTH 

다른 모든 사용자에 대해 읽기를 허가함. 

0002 

S_IWOTH 

다른 모든 사용자에 대해 쓰기를 허가함. 

0001 

S_IXOTH 

다른 모든 사용자에 대해 실행을 허가함. 


헤더파일 <sys/stat.h>에 허가 비트들의 상징형 이름을 수록하고 있다.

파일 모드는 원하는 권한의 팔진수 값을 더하면 된다.

예를 들면 0700 + 050 + 05 = 0755 은 소유자는 읽고, 쓰고, 실행하는 것이 가능하고, 그룹의 구성원과 그 외 사용자는 읽고, 실행만 가능하도록 허락하는 것이다.

또는 상징형 표현에 대해 비트 단위 OR(|)를 수행함으로써 지정할 수도 있다.

예를 들면 세 가지 사용자 유형 모두 읽기 권한만 지정하려면, S_IRUSR | S_IRGRP | S_IROTH 를 하면 된다.

+ Recent posts