setjmp(3) - wariua/manpages-ko GitHub Wiki

NAME

setjmp, sigsetjmp, longjmp, siglongjmp - 비지역적 goto μˆ˜ν–‰ν•˜κΈ°

SYNOPSIS

#include <setjmp.h>

int setjmp(jmp_buf env);
int sigsetjmp(sigjmp_buf env, int savesigs);

void longjmp(jmp_buf env, int val);
void siglongjmp(sigjmp_buf env, int val);

glibc κΈ°λŠ₯ 확인 맀크둜 μš”κ±΄ (feature_test_macros(7) μ°Έκ³ ):

setjmp():
NOTES μ°Έκ³ .
sigsetjmp():
_POSIX_C_SOURCE

DESCRIPTION

이 νŽ˜μ΄μ§€μ—μ„œ κΈ°μˆ ν•˜λŠ” ν•¨μˆ˜λ“€μ€ "비지역적 goto" μˆ˜ν–‰, 즉 ν•œ ν•¨μˆ˜μ—μ„œ λ‹€λ₯Έ ν•¨μˆ˜ λ‚΄μ˜ 미리 μ •ν•΄ λ‘” μœ„μΉ˜λ‘œ 싀행을 μ΄μ „ν•˜λŠ” 데 μ“΄λ‹€. setjmp() ν•¨μˆ˜λŠ” 이후에 μ œμ–΄λ₯Ό 이전할 λͺ©ν‘œμ μ„ λ™μ μœΌλ‘œ μ„€μ •ν•˜λ©° longjmp()λŠ” μ‹€ν–‰ 이전을 μˆ˜ν–‰ν•œλ‹€.

setjmp() ν•¨μˆ˜λŠ” 호좜 ν™˜κ²½μ— λŒ€ν•œ λ‹€μ–‘ν•œ 정보(보톡은 μŠ€νƒ 포인터와 μΈμŠ€νŠΈλŸ­μ…˜ 포인터, 그리고 μ•„λ§ˆλ„ λ‹€λ₯Έ λ ˆμ§€μŠ€ν„°λ“€μ˜ κ°’κ³Ό μ‹œκ·Έλ„ 마슀크)λ₯Ό 버퍼 env에 μ €μž₯ν•˜μ—¬ 이후에 longjmp()κ°€ μ‚¬μš©ν•  수 있게 ν•œλ‹€. 이 κ²½μš°μ— setjmp()λŠ” 0을 λ°˜ν™˜ν•œλ‹€.

longjmp() ν•¨μˆ˜λŠ” env에 μ €μž₯된 정보λ₯Ό μ΄μš©ν•΄ setjmp()λ₯Ό ν˜ΈμΆœν–ˆλ˜ μ§€μ μœΌλ‘œ μ œμ–΄λ₯Ό μ΄μ „ν•˜κ³  setjmp() 호좜 μ‹œμ μ˜ μƒνƒœλ‘œ μŠ€νƒμ„ 볡원("되감기")ν•œλ‹€. λ”λΆˆμ–΄ κ΅¬ν˜„μ— λ”°λΌμ„œ (NOTES μ°Έκ³ ) λ‹€λ₯Έ λ ˆμ§€μŠ€ν„°λ“€μ˜ κ°’κ³Ό ν”„λ‘œμ„ΈμŠ€ μ‹œκ·Έλ„ λ§ˆμŠ€ν¬κ°€ setjmp() 호좜 μ‹œμ μ˜ μƒνƒœλ‘œ 볡원될 μˆ˜λ„ μžˆλ‹€.

longjmp() 성곡 ν›„μ—λŠ” setjmp()κ°€ 두 번째둜 λ°˜ν™˜λœ κ²ƒμ²˜λŸΌ 싀행이 이어진닀. 이 "κ°€μ§œ" λ°˜ν™˜μ„ μ§„μ§œ setjmp() 호좜과 ꡬ별할 수 μžˆλŠ” 것은 "κ°€μ§œ" λ°˜ν™˜μ—μ„œλŠ” val에 μ œκ³΅ν•œ 값을 λ°˜ν™˜ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€. ν”„λ‘œκ·Έλž˜λ¨Έκ°€ μ‹€μˆ˜λ‘œ val에 0 값을 μ „λ‹¬ν•˜λ©΄ "κ°€μ§œ" λ°˜ν™˜μ—μ„œλŠ” κ·Έ λŒ€μ‹  1을 λ°˜ν™˜ν•˜κ²Œ λœλ‹€.

sigsetjmp()와 siglongjmp()

sigsetjmp()와 siglongjmp() μ—­μ‹œ 비지역적 gotoλ₯Ό μˆ˜ν–‰ν•˜λ˜ ν”„λ‘œμ„ΈμŠ€ μ‹œκ·Έλ„ 마슀크λ₯Ό 예츑 κ°€λŠ₯ν•˜κ²Œ μ²˜λ¦¬ν•΄ μ€€λ‹€.

sigsetjmp()μ—κ²Œ μ€€ savesigs μΈμžκ°€ 0이 μ•„λ‹Œ κ²½μš°μ—λŠ”, 그리고 κ·Έ κ²½μš°μ—λ§Œ ν”„λ‘œμ„ΈμŠ€μ˜ ν˜„μž¬ μ‹œκ·Έλ„ 마슀크λ₯Ό env에 μ €μž₯ν•˜λ©° 이후 이 env둜 siglongjmp()λ₯Ό μˆ˜ν–‰ν•˜λ©΄ λ‹€μ‹œ λ³΅μ›ν•˜κ²Œ λœλ‹€.

RETURN VALUE

setjmp()와 sigsetjmp()λŠ” 직접 호좜 μ‹œ 0을 λ°˜ν™˜ν•œλ‹€. longjmp()λ‚˜ siglongjmp() 후에 μΌμ–΄λ‚˜λŠ” "κ°€μ§œ" λ°˜ν™˜μ—μ„œλŠ” val둜 μ§€μ •ν•œ 0 μ•„λ‹Œ 값을 λ°˜ν™˜ν•œλ‹€.

longjmp() λ‚΄μ§€ siglongjmp() ν•¨μˆ˜λŠ” λ°˜ν™˜ν•˜μ§€ μ•ŠλŠ”λ‹€.

ATTRIBUTES

이 μ ˆμ—μ„œ μ‚¬μš©ν•˜λŠ” μš©μ–΄λ“€μ— λŒ€ν•œ μ„€λͺ…은 attributes(7)λ₯Ό 보라.

μΈν„°νŽ˜μ΄μŠ€ 속성 κ°’
setjmp(), sigsetjmp() μŠ€λ ˆλ“œ μ•ˆμ „μ„± MT-Safe
longjmp(), siglongjmp() μŠ€λ ˆλ“œ μ•ˆμ „μ„± MT-Safe

CONFORMING TO

setjmp(), longjmp(): POSIX.1-2001, POSIX.1-2008, C89, C99.

sigsetjmp(), siglongjmp(): POSIX.1-2001, POSIX.1-2008.

NOTES

POSIXμ—μ„œλŠ” setjmp()κ°€ μ‹œκ·Έλ„ 마슀크λ₯Ό μ €μž₯ν•˜κ²Œ λ˜λŠ”μ§€ (그리고 이후 longjmp() κ³Όμ •μ—μ„œ λ³΅μ›ν•˜κ²Œ λ˜λŠ”μ§€) μ—¬λΆ€λ₯Ό λͺ…μ„Έν•˜κ³  μžˆμ§€ μ•Šλ‹€. μ‹œμŠ€ν…œ Vμ—μ„œλŠ” κ·Έλ ‡κ²Œ λ˜μ§€ μ•ŠλŠ”λ‹€. 4.3BSDμ—μ„œλŠ” κ·Έλ ‡κ²Œ 되며, 또 κ·Έλ ‡κ²Œ λ˜μ§€ μ•ŠλŠ” _setjmp() ν•¨μˆ˜κ°€ μžˆλ‹€. λ¦¬λˆ…μŠ€μ—μ„œμ˜ λ™μž‘ 방식은 glibc 버전과 κΈ°λŠ₯ 확인 맀크둜 섀정에 따라 달라진닀. λ¦¬λˆ…μŠ€μ—μ„œ glibc 버전 2.19 μ „κΉŒμ§€λŠ” setjmp()κ°€ 기본적으둜 μ‹œμŠ€ν…œ V λ™μž‘ 방식을 λ”°λ₯΄λ˜, _BSD_SOURCE κΈ°λŠ₯ 확인 λ§€ν¬λ‘œκ°€ λͺ…μ‹œμ μœΌλ‘œ μ •μ˜λ˜μ–΄ 있으며 _POSIX_SOURCE, _POSIX_C_SOURCE, _XOPEN_SOURCE, _GNU_SOURCE 쀑 μ–΄λŠ 것도 μ •μ˜λ˜μ–΄ μžˆμ§€ μ•ŠμœΌλ©΄ BSD λ™μž‘ 방식을 μ œκ³΅ν•œλ‹€. glibc 2.19λΆ€ν„°λŠ” <setjmp.h>μ—μ„œ μ‹œμŠ€ν…œ V λ²„μ „μ˜ setjmp()만 λ“œλŸ¬λ‚Έλ‹€. BSD λ™μž‘ 방식이 ν•„μš”ν•œ ν”„λ‘œκ·Έλž¨μ—μ„œλŠ” setjmp() ν˜ΈμΆœμ„ savesigs μΈμžκ°€ 0이 μ•„λ‹Œ sigsetjmp() 호좜둜 ꡐ체해야 ν•œλ‹€.

setjmp()와 longjmp()λŠ” 깊이 이어진 ν•¨μˆ˜ 호좜 λ‚΄μ˜ 였λ₯˜λ₯Ό λ‹€λ£¨λŠ” 데 μœ μš©ν•  수 있으며 μ‹œκ·Έλ„ ν•Έλ“€λŸ¬μ—μ„œ μ£Ό ν”„λ‘œκ·Έλž¨μ΄ μ€‘λ‹¨λλ˜ μ§€μ μœΌλ‘œ λŒμ•„κ°€λŠ” λŒ€μ‹  ν”„λ‘œκ·Έλž¨ λ‚΄ νŠΉμ • μœ„μΉ˜λ‘œ μ œμ–΄λ₯Ό 전달할 μˆ˜λ„ μžˆλ‹€. ν›„μžμ—μ„œ μ‹œκ·Έλ„ 마슀크λ₯Ό 이식성 있게 μ €μž₯ 및 λ³΅μ›ν•˜κ³  μ‹Άλ‹€λ©΄ sigsetjmp()와 siglongjmp()λ₯Ό μ‚¬μš©ν•˜λ©΄ λœλ‹€. μ•„λž˜μ˜ ν”„λ‘œκ·Έλž¨ 가독성에 λŒ€ν•œ λ…Όμ˜λ„ μ°Έκ³ ν•˜λΌ.

μ»΄νŒŒμΌλŸ¬κ°€ λ³€μˆ˜λ“€μ„ λ ˆμ§€μŠ€ν„°λ‘œ μ΅œμ ν™”ν•  μˆ˜λ„ μžˆλŠ”λ° longjmp()κ°€ μŠ€νƒ 포인터와 ν”„λ‘œκ·Έλž¨ μΉ΄μš΄ν„°μ— 더해 λ‹€λ₯Έ λ ˆμ§€μŠ€ν„°λ“€μ˜ 값을 볡원할 μˆ˜λ„ μžˆλ‹€. λ”°λΌμ„œ λ‹€μŒ 기쀀듀에 λͺ¨λ‘ ν•΄λ‹Ήν•˜λŠ” κ²½μš°μ—λŠ” longjmp() 호좜 후에 μžλ™ λ³€μˆ˜μ˜ 값이 μ •ν•΄μ Έ μžˆμ§€ μ•Šλ‹€.

  • λ³€μˆ˜κ°€ λŒ€μ‘ν•˜λŠ” setjmp() ν˜ΈμΆœμ„ ν–ˆλ˜ ν•¨μˆ˜μ— λ‘œμ»¬μ΄λ‹€.

  • κ·Έ 값이 setjmp() 호좜과 longjmp() 호좜 μ‚¬μ΄μ—μ„œ 바뀐닀.

  • volatile둜 μ„ μ–Έλ˜μ–΄ μžˆμ§€ μ•Šλ‹€.

μœ μ‚¬ν•œ λ‚΄μš©μ΄ siglongjmp()에도 μ μš©λœλ‹€.

비지역적 goto와 ν”„λ‘œκ·Έλž¨ 가독성

였용 κ°€λŠ₯성이 μžˆκΈ°λŠ” ν•˜μ§€λ§Œ 전톡적인 C의 "goto" λ¬Έμ—λŠ” 적어도 언어적 μ‹ ν˜Έ(goto λ¬Έκ³Ό λŒ€μƒ λ ˆμ΄λΈ”)λ₯Ό 톡해 ν”„λ‘œκ·Έλž˜λ¨Έκ°€ μ‹€ν–‰ 흐름을 μ‰½κ²Œ 인식할 수 μžˆλ‹€λŠ” μž₯점이 μžˆλ‹€. ν•˜μ§€λ§Œ 비지역적 gotoμ—λŠ” 그런 μ‹ ν˜Έκ°€ μ—†λ‹€. μ—¬λŸ¬ setjmp() ν˜ΈμΆœλ“€μ΄ λ™μΌν•œ jmp_buf λ³€μˆ˜λ₯Ό μ΄μš©ν•  μˆ˜λ„ μžˆμ„ ν…Œκ³ , 그러면 κ·Έ λ³€μˆ˜μ˜ λ‚΄μš©μ΄ μ‘μš©μ˜ 수λͺ… λ™μ•ˆ λ°”λ€” μˆ˜λ„ μžˆλ‹€. κ·Έλž˜μ„œ νŠΉμ • longjmp() 호좜의 동적인 λŒ€μƒμ„ μ•Œμ•„λ‚΄κΈ° μœ„ν•΄ ν”„λ‘œκ·Έλž˜λ¨Έκ°€ μ–΄μ©” 수 없이 μ½”λ“œλ₯Ό μžμ„Ένžˆ 읽어야 ν•  μˆ˜λ„ μžˆλ‹€. (κ·Έ ν”„λ‘œκ·Έλž˜λ¨Έλ₯Ό 도와 μ£Όλ €λ©΄ setjmp() ν˜ΈμΆœλ§ˆλ‹€ 각자의 jmp_buf λ³€μˆ˜λ₯Ό μ΄μš©ν•˜λŠ” 게 μ’‹λ‹€.)

더 λ‚œμ΄λ„λ₯Ό 올리자면 setjmp() 호좜과 longjmp() 호좜이 같은 μ†ŒμŠ€ μ½”λ“œ λͺ¨λ“ˆμ— μžˆμ§€ μ•Šμ„ μˆ˜λ„ μžˆλ‹€.

μš”μ•½ν•˜μžλ©΄ 비지역적 gotoλŠ” ν”„λ‘œκ·Έλž¨ 이해과 μœ μ§€ 보수λ₯Ό μ–΄λ ΅κ²Œ λ§Œλ“€λ©° κ°€λŠ₯ν•˜λ‹€λ©΄ λ‹€λ₯Έ λŒ€μ•ˆμ„ μ‚¬μš©ν•˜λŠ” 게 μ’‹λ‹€.

κ²½κ³ 

setjmp()λ₯Ό ν˜ΈμΆœν–ˆλ˜ ν•¨μˆ˜κ°€ longjmp() 호좜 전에 λ°˜ν™˜ν•˜λŠ” 경우의 λ™μž‘ 방식은 κ·œμ •λ˜μ–΄ μžˆμ§€ μ•Šλ‹€. μ–΄λ–€ λ―Έλ¬˜ν•˜κ±°λ‚˜ λ―Έλ¬˜ν•˜μ§€ μ•Šμ€ ν˜Όλž€μ΄ λΆ„λͺ…νžˆ λ°œμƒν•œλ‹€.

닀쀑 μŠ€λ ˆλ“œ ν”„λ‘œκ·Έλž¨μ—μ„œ λ‹€λ₯Έ μŠ€λ ˆλ“œμ—μ„œμ˜ setjmp() 호좜둜 μ΄ˆκΈ°ν™” ν–ˆλ˜ env 버퍼λ₯Ό longjmp() ν˜ΈμΆœμ—μ„œ μ‚¬μš©ν•˜λŠ” 경우 κ·Έ λ™μž‘ 방식은 κ·œμ •λ˜μ–΄ μžˆμ§€ μ•Šλ‹€.

POSIX.1-2008 기술 μ •μ˜€ν‘œ 2μ—μ„œ longjmp()와 siglongjmp()λ₯Ό 비동기 μ‹œκ·Έλ„ μ•ˆμ „ ν•¨μˆ˜ λͺ©λ‘μ— μΆ”κ°€ν•˜μ˜€λ‹€. ν•˜μ§€λ§Œ κ·Έ ν‘œμ€€μ—μ„œλŠ” μ‹œκ·Έλ„ ν•Έλ“€λŸ¬μ—μ„œ 이 ν•¨μˆ˜λ“€μ˜ μ‚¬μš©μ„ ν”Όν•˜κΈ°λ₯Ό κΆŒν•˜κ³  있으며 κ³„μ†ν•΄μ„œ μ§€μ ν•˜κΈ°λ₯Ό, 비동기 μ‹œκ·Έλ„ μ•ˆμ „ μ•„λ‹Œ ν•¨μˆ˜μ— λŒ€ν•œ ν˜ΈμΆœμ„ μ€‘λ‹¨μ‹œμΌ°λ˜ μ‹œκ·Έλ„ ν•Έλ“€λŸ¬μ—μ„œ (λ˜λŠ” main()에 λŒ€ν•œ 졜초 ν˜ΈμΆœμ—μ„œ λ°˜ν™˜ μ‹œ μΌμ–΄λ‚˜λŠ” exit(3)에 ν•΄λ‹Ήν•˜λŠ” λ‹¨κ³„λ“€μ²˜λŸΌ λ™λ“±ν•œ λ¬΄μ–Έκ°€μ—μ„œ) 이 ν•¨μˆ˜λ“€μ„ ν˜ΈμΆœν•œλ‹€λ©΄ ν”„λ‘œκ·Έλž¨μ—μ„œ 이후 비동기 μ‹œκ·Έλ„ μ•ˆμ „ μ•„λ‹Œ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λŠ” 경우 κ·Έ λ™μž‘ 방식이 κ·œμ •λ˜μ–΄ μžˆμ§€ μ•Šλ‹€. μ •μ˜ μ•ˆ 된 λ™μž‘μ„ ν”Όν•  μœ μΌν•œ 방법은 λ‹€μŒ 쀑 ν•˜λ‚˜λ₯Ό 보μž₯ν•˜λŠ” 것이닀.

  • μ‹œκ·Έλ„ ν•Έλ“€λŸ¬λ‘œλΆ€ν„° κΈ΄ 점프λ₯Ό ν•œ ν›„μ—λŠ” ν”„λ‘œκ·Έλž¨μ—μ„œ μ–΄λ–€ 비동기 μ‹œκ·Έλ„ μ•ˆμ „ μ•„λ‹Œ ν•¨μˆ˜λ„ ν˜ΈμΆœν•˜μ§€ μ•Šκ³  main()에 λŒ€ν•œ 졜초 ν˜ΈμΆœλ‘œλΆ€ν„° λ°˜ν™˜ν•˜μ§€ μ•ŠλŠ”λ‹€.

  • λͺ¨λ“  비동기 μ‹œκ·Έλ„ μ•ˆμ „ μ•„λ‹Œ ν•¨μˆ˜ 호좜 λ™μ•ˆ ν•Έλ“€λŸ¬μ—μ„œ κΈ΄ 점프λ₯Ό μˆ˜ν–‰ν•˜λŠ” μ‹œκ·Έλ„λ“€μ„ 차단해야 ν•˜λ©° main()에 λŒ€ν•œ 졜초 ν˜ΈμΆœλ‘œλΆ€ν„° λ°˜ν™˜ν•œ 후에 μ–΄λ–€ 비동기 μ‹œκ·Έλ„ μ•ˆμ „ μ•„λ‹Œ ν•¨μˆ˜λ„ ν˜ΈμΆœν•˜μ§€ μ•ŠλŠ”λ‹€.

SEE ALSO

signal(7), signal-safety(7)


2017-03-13

⚠️ **GitHub.com Fallback** ⚠️