- 0x0000007b
- 2차세계대전
- 3.20해킹
- 4대강
- 502 error
- 53빌딩
- 7840hs
- 88체육관 수영장
- ABI
- abortive close
- abortive shutdown
- AHCI
- akmods
- ALC1220
- alma linux
- alternatives
- AM4 메인보드
- AMD
- amd 7840hs
- amd 그래픽 게임용
- amd 내장 그래픽 최적화
- anonymous file
- API
- apple.com
- APT
- apt-get
- Armagnac
- Asrock
- ASTALIFT
- audacious player
- Today / Yesterday
- /
- Total
Linux Programmer
유닉스 표준 IEEE std 1003.1 issue 8 (SUSv5) 개정판 - 2024년 5월 발표 본문
유닉스 표준 IEEE std 1003.1 issue 8 (SUSv5) 개정판 - 2024년 5월 발표
sunyzero 2024. 11. 25. 13:06유닉스 표준 IEEE std 1003.1 issue 8 (SUSv5) 개정판 소개
(부제 : C언어 표준과 리눅스와의 관계)
참고 링크
📌 온라인문서 - https://pubs.opengroup.org/onlinepubs/9799919799/
📌 뉴스 https://ieeexplore.ieee.org/document/10555529
유닉스 표준인 IEEE std 1003.1은 셸(shell)과 명령어, 유닉스 파일 이름 및 경로, 소스 레벨의 함수 호환성 등을 정의하는 문서다. 유닉스 표준이기도 하지만 리눅스도 이 표준을 준수하기 때문에 리눅스 개발자도 필수로 알아둬야 한다.🔔
원래 유닉스 표준 문서📒란 새로운 기능을 만드는 것이 아니라 기존의 기능 중에 공통으로 지원해야 하는 것들을 정의하고 문서화 한다. 다만 공통의 기능 중에는 필수(mandatory)로 제공해야 하는 기능이 있고, 해도 되고 안해도 되는 선택적(optional) 기능이 있다. 그리고 과거의 기능 중에 표준화에 충돌이 생기는 기능은 대체된(replaced) 기능을 제공한다. 여기서 제일 중요한게 바로 대체 기능을 명확하게 아는 것이다.
다시 말하지만 표준이란 새로운 기능에 중점을 둔게 아니라 과거의 문제된 기능을 대체하는 것임을 명심해야 한다.
1. 유닉스 표준 스펙이란?
2024년 새롭게 릴리즈 된 유닉스 표준 문서의 정식 명칭은 IEEE std 1003.1-2024 issue 8이다. 한글(콩글리쉬)로 말할 때는 "아이트리플리 스탠다드 일공공삼 쩜 일 이천이십사년 이슈 팔"이라 부른다. 참고로 POSIX는 "포식스"가 아니라 "파직스"로 발음한다.
참고 - IT용어 발음하기 - 스카시? 포식스? - https://sunyzero.tistory.com/257
표준 문서는 SUSv8 (Single UNIX Specification version 8)이라고도 부르며, 혹은 XPG 8 (X/Open Portablity Guide)이라고 부를 수도 있다. 이름이 여러 개인 이유는 조직의 합병과 상표권 주인이 이리저리 바뀌면서 생긴 역사 때문이다.(집에서 부르는 이름, 회사에서 부르는 이름, 연인끼리 애칭이 다른거라고 이해하면 될 듯 싶다) 따라서 POSIX 1003.1-2024로도 부를 수 있고, 더 줄여서 POSIX.1-2024라고 쓸 수도 있는데 원래 POSIX.1은 서브 카테고리의 문서를 의미하므로 정확하게 동일하지는 않지만 다 알아듣는다. (UNIX 역사를 잘 아는 분들은 어떻게 말해도 다 알아듣는 편이다)
IEEE std 1003.1 == SUS == XPG ~= POSIX 1003.1(== POSIX.1)
1.1. SUS 표준 문서의 중요성
SUS 표준에는 프로그래밍에 사용되는 C언어 함수 정의가 포함되어 있다. 그리고 개념 충돌이 발생하여 사용하면 위험한 행동이거나 그로인해 제거된 함수들도 알려주기 때문에 시스템 프로그래머가 필히 읽어야 하는 문서이다. 실제로 몇몇 사이트에 교육을 가보면 표준에서 되도록이면 쓰지 말라고하는 gettimeofday나 usleep, bzero, gets, signal 같은 함수를 쓰는 곳이 여전히 많다. 네트워크 프로그래밍에서도 gethostbyname, inet_addr 같은 함수도 이제 제거된 함수이다. 게다가 C99의 restrict pointer 영향으로 함수 원형이 바뀐 memcpy나 memmove도 사용법을 잘못알고 마구잡이로 쓰면 묘한 버그가 발생할 수도 있다. 그래서 표준 문서를 봐두는게 좋다는 것이다. 게다가 표준 문서가 그렇게 자주 나오는게 아니라 거의 10년마다 한번 나오는 정도니까 시간은 충분하다.
표준 문서에는 함수 이외에 Base definition과 Rationale에 용어 정의(terminology)도 포함되어있기 때문에 매뉴얼을 읽을 때 명확한 의미를 이해하는데 도움을 준다.
참고로 man page도 SUS 표준 문서를 기반으로 하고 있고, 표준 문서에 첨언하여 만들어진다. 따라서 리눅스 맨페이지들을 보면 맨 아래 Confirming to와 Notes에 표준 문서에 관련된 부분이 있다.
1.2. SUS 표준 문서의 역사
SUS를 제대로 이해하려면 유닉스 역사를 알아야만 한다. 초기 UNIX는 AT&T 벨 연구소에서 켄 탐슨(Ken Thompson)에 의해 만들어졌다. AT&T는 당시 유닉스의 잠재성을 몰랐기 때문에 실비 수준에 소스 코드까지 제공했다. 그러나 이후 시장이 커졌고 AT&T는 따로 회사를 만들어서 비즈니스를 하기 원했고, 이에 따라 소유권(라이선스)을 주장했다. 그러나 이미 소스코드가 많이 퍼져서 다른 회사나 대학에서도 변종들이 많이 만들어져있었다. 그 중에서 버클리 대학에서는 켄 탐슨이 교수로 있으면서 유닉스를 개량해서 BSD라는 걸출한 유닉스 분파를 만들어냈다. 이 후 BSD를 사용하는 대학과 기업체는 AT&T와 소송을 할 수 밖에 없었다.😣
각 진영은 지리하게 싸웠고, 그 과정에서 AT&T를 대장으로 삼은 SysV(System V, 시스템파이브)계열과 BSD계열은 서로 호환성을 없애는데 열중했다. 누가보면 철천지 원수처럼 보였다. 시간이 흘러 법적 문제는 대충 봉합되었는데, 마침 Microsoft가 서버 시장에 진출하면서 충격을 받은 유닉스 진영은 급하게 화해를 할 수 밖에 없었다.
그래서 1995년 SUS(Single UNIX Spec., 단일 유닉스 상세)가 탄생할 수 있었다. 참고로 마이크로소프트의 윈도NT는 1994년에 발표되었었다. 유닉스 진영은 과거의 라이선스 분쟁의 재발을 막기 위해 문서의 권리와 상표권은 비상업 단체인 OpenGroup으로 넘겨졌다. 현재 OpenGroup에서는 유닉스 뿐만 아니라 다양한 네트워크 및 관련 표준도 관리하고 있다.
최초의 IEEE std 1003.1 표준 문서는 1995년에 나왔으며, 그 이후로 1998년, 2022년, 2008년, 2017년... 등을 거치면서 개정을 해왔다. 원래 2008년 issue 7 (SUSv4)에 이르러 완성형이 되었고, 2013, 2017년에 세세한 개정이 있었다. 그리고 마침내 2008년으로부터 16년이 흘러, 2024년 issue 8, SUSv5가 릴리즈되었다.
1.3. 리눅스와 유닉스 표준과의 관계
유닉스 표준화 전쟁이 발발했던 80~90년대초까지 약 10년은 악몽의 시간이었지만 후일 리눅스를 탄생시키는 계기가 되었다는 점에서 새옹지마라고 할 수 있다.🎉 원래 리누즈 토발즈(리눅스 창시자)는 90년대초 대학원생 시절 자신의 PC에 유닉스를 설치하고 싶었다. 그러나 후보였던 미닉스는 별로였고, 상용 유닉스는 비싸고 호환성도 부족했다. 그리고 BSD유닉스는 90~91년도 당시에는 라이선스 전쟁 때문에 제대로 개발, 배포되지 못했다. 후일 토발즈는 당시 자신의 인텔 호환 PC에 BSD유닉스가 설치될 수만 있었다면 굳이 리눅스를 만들지 않았을거라고 이야기 했다.
그리하여 20세기말 컴퓨터 공학 최고의 역작이라는 리눅스의 탄생 계기는 AT&T의 탐욕으로 라이선스 전쟁을 일으킨 것이 원인이라는 점이 참 아이러니하다. 2024년 우리가 사용하는 현대 과학 시스템은 대부분 리눅스로 작동하고, 리눅스 때문에 과학 발전이 빨라진 것도 사실이다. 공학자들은 대체로 리눅스가 과학을 최소 20년 이상 앞당겼다고 평가한다. 우리가 타는 비행기✈️, 선박 🛥️ , 자동차 🚗 대부분은 리눅스로 구동되고 있고, 인터넷 서버의 대부분도 다 리눅스이다. 일반인들은 모르겠지만 정부 시스템, 은행, 증권, 보험 회사 등도 리눅스로 작동된다. 게다가 현대인은 전기없이 살 수는 없을텐데, 그 전력망🌩️ 조차도 리눅스로 관리된다. 스마트폰 운영체제인 안드로이드도 리눅스 기반이다. 또한 요새 아주 핫한 인공지능도 리눅스 위에서 구동된다. 온세계가 리눅스 세상이고, 심지어 마이크로소프트조차 "MS loves Linux"라고 발표하면서 애저 클라우드에서 리눅스로 돈을 쓸어담고 있다.
1.4. 표준 문서 연도별 목록
표준 문서의 역사에 대해 약간 더 알아보도록 하자. 원래 첫 SUS문서가 발표된 1995년도에는 시간이 촉박해서 XPG(X/Open Portablity Guide) 4.20을 그대로 SUSv1 초안으로 발표했다.(겉장만 뜯어냈다는 소문이...) 이 후 본격적인 표준화 작업을 하게되었고, 1998년도에 실질적인 유닉스 통합 표준으로 SUSv2가 만들어졌다. 발표된 해인 1998년도를 붙여 UNIX98이라고도 부른다. 대부분 UNIX98이 실질적인 유닉스 통합의 첫 문서로 보는 경향이 짙다.
그리고 2002년도에 C언어 국제표준인 C99의 영향과 리눅스의 영향, 리얼타임 시스템, 쓰레드 기법의 영향을 받아 SUSv3가 나왔다. 여기에는 POSIX 쓰레드(POSIX.1c)라든지 리얼타임 기법(POSIX.1c)이라든지 여러가지 상세가 통합되었다.
2008년도에는 여러가지 명확하지 못한 용어나 기술들을 제거하고 SUSv4가 나왔다. 현재 리눅스와 유닉스는 대부분 SUSv4 기준에 맞춰서 개정되었다. 그래서 SUSv4는 거의 완성형에 가깝다고 평가받는다. 각 문서의 역사를 정리하면 아래와 같다.
1995년 - IEEE std 1003.1-1995 issue 4.2 (SUSv1, UNIX95, XPG 4.20, _POSIX_C_SOURCE 199506L)
1998년 - IEEE std 1003.1-1998 issue 5 (SUSv2, UNIX98, XPG 5.00)
2002년 - IEEE std 1003.1-2002 issue 6 (SUSv3, UNIX98, XPG 6.00, _POSIX_C_SOURCE 200112L)
2008년 - IEEE std 1003.1-2008 issue 7 (SUSv4, XPG 7.00, _POSIX_C_SOURCE 200809L)
2017년 - IEEE std 1003.1-2017 issue 7 (SUSv4, minor reversion of issue 7)
2024년 - IEEE std 1003.1-2024 issue 8 (SUSv5, XPG 8.00, _POSIX_C_SOURCE 202405L)
SUS의 issue번호는 XPG의 major version을 의미하므로 issue 6는 XPG 6.00이고 C언어 헤더에서 '#define _XOPEN_SOURCE 600' 혹은 '#define _POSIX_C_SOURCE 200112L' 선언을 의미한다.(SUSv3의 POSIX C 표준은 2001년 12월 버전을 포함) 2008년 표준은 issue 7이므로 '#define _XOPEN_SOURCE 700' 혹은 '#define _POSIX_C_SOURCE 200809L'과 같다. 간혹 man page에 _XOPEN_SOURCE나 _POSIX_C_SOURCE를 define하라고 나오는 것은 이 표준 버전에 근거한다.
따라서 2024년의 issue 8은 '#define _XOPEN_SOURCE 800'로 표시할 수 있다. 만일 시스템이 issue 7까지 지원하는 시스템이라면 features test macro에서 자동으로 _XOPEN_SOURCE 700 으로 간주한다. 앞으로 최신의 기능을 전부 사용하고자 한다면 '#define _XOPEN_SOURCE 800'으로 선언하고 시스템 프로그래밍을 하면 된다. 앞서 설명한 feature test macro와 연도별 유닉스 표준만 다시 정리하면 다음과 같다.
표준 | Feature test macro (C언어) |
SUSv1(XPG4.20) | _XOPEN_SOURCE = 420 or POSIX_C_SOURCE = 199506L |
SUSv2(XPG5.00) | _XOPEN_SOURCE = 500 |
SUSv3(XPG6.00) | _XOPEN_SOURCE = 600 or POSIX_C_SOURCE = 200112L |
SUSv4(XPG7.00) | _XOPEN_SOURCE = 700 or POSIX_C_SOURCE = 200809L |
SUSv5(XPG8.00) | _XOPEN_SOURCE = 800 or POSIX_C_SOURCE = 202405L |
1.5. 유닉스 역사에 관한 만화
일련의 유닉스 역사는 "UNIX의 역사"라는 책에 자세히 언급되어있지만, 책 앨러지가 있어서 금방 잠이 오거나 졸린 분은 https://joone.net/ 에서 F/OSS story 만화로도 볼 수 있다. 특히 8화 유닉스와 C언어, 9화 유닉스 철학, 10화 C언어의 아버지, 11~16화 BSD 유닉스 부분은 필독을 권한다.
📌F/OSS Story 8화 유닉스와 C언어 링크 - https://joone.net/2017/02/18/%ec%9c%a0%eb%8b%89%ec%8a%a4%ec%99%80-c%ec%96%b8%ec%96%b4/
2. C언어 표준과의 관계
애초에 유닉스를 잘 만들기 위해 탄생한 언어가 C언어이다보니, 유닉스와 C언어는 매우 긴밀한 관계를 가지고 있다. C언어 함수의 일부는 유닉스 환경에서 작동하게 만들어졌으나, C언어가 여러 운영체제에 포팅되다보니 공통으로 사용가능한 함수들이 C언어 표준으로 정해졌고, 나머지 유닉스 전용 C언어 함수들은 유닉스 표준에만 들어갔다. 따라서 유닉스 표준에는 C언어 표준 함수 + 유닉스 전용함수가 모두 포함된다.
그런데 시간이 흐르면서 C언어 표준도 개정되어 왔는데, 크게 보면 ANSI-C 혹은 C89 (1989년, 1990년), C99 (1999년), C11(2011년), C17/C18(2018년) 정도가 있다. 그리고 유닉스 표준도 C언어 표준을 포함한다고 언급했듯이, 표준안 연도에 따라 포함하는 C언어 표준 개정판이 조금씩 다르다. 참고로 C언어 표준에서 큰 변화는 C99때였고, C11은 기능 확장, C17/C18은 결함 수정이다. 따라서 대부분의 실무는 C99에 준하거나 C99에 C17/C18의 기능 일부를 도입하는 수준이 제일 많다. 그러면 유닉스 표준은 C언어 표준을 어디까지 도입했을까?
SUSv4-2017년까지는 C99 표준 사용 (C99는 실로 업계 표준이라고 생각하면 된다)
SUSv5-2024년부터는 C17/C18을 사용
C18 2018 - https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2310.pdf
가장 최근까지만 하더라도 유닉스, 리눅스에서 가장 많이 사용하는 표준은 C99였다. 대부분의 C컴파일러는 C99를 기본값으로 삼기도 했다. 따라서 SUS도 issue 7(2017년)까지는 C99 표준을 참조하여 유닉스 표준을 제정했다. 하지만 2024년도 개정판에서는 C17 표준을 참조하였다. 따라서 C17의 각종 기능들이 들어왔다. 주요 신기능은 restrict, stdalign.h, unicode, C standard theads, C standard atomic operations, C memory-order (acquire, consume, release의 모델) 등이 있다. 이들 기능의 대부분은 C11, C14부터 제공되던 기능이다. 그러나 threads.h는 pthread가 더 좋고, 기능도 더 많기 때문에 유닉스/리눅스쪽에서는 잘 사용되지는 않는다.(리눅스에서 threads.h는 pthread의 단순 wrapper이다)
그리고 atomic operation이나 memory-order의 경우는 gcc extensions를 대체하여 사용된다. 원래 GCC 확장 기능으로 많이 사용했던 기능인데, 표준화가 되었다고 생각하면 된다. 물론 표준화를 통해 함수명은 밑줄이 빠지게 되었다. 예를 들어 atomic_fetch_add라든지 atomic_fetch_sub 같은 atomic 기능들이 대표적이며, atomic_thread_fence, atomic_signal_fence, atomic_flag_test_and_set_explicit 등에 적용하는 memory_order등도 있다.
3. SUSv5의 신기능 or 제거된 기능
가장 궁금한 것은 그래서 SUSv5가 뭐가 다른건데라고 물을 수 있는데🤷♂️, 자세한 것은 표준안 rationale에서 볼 수 있다. 하지만 다 읽기 귀찮은 분들을 위해 주요 변경점만 빠르게 요약해 보겠다.
3.1. sh (셸)
bash셸의 일부 기능이 표준에 포함되었다. 대표적으로 pipelines의 pipefail이 있다. 이 기능은 shell script를 작성하는데 있어서 필수 기능으로 이를 잘 사용하지 못하면 초짜 취급을 받는다.
3.2. 추가된 기능
새롭게 추가되거나 변경된 C함수의 주요 목록은 다음과 같다.(모든 기능을 나열하기엔 너무 길기 때문에 일부 중요한 기능만 적는다)
일반적으로 signal의 개입이나 flag에 따라서 제어할 수 있는 기능들이 포함된 함수가 추가되었다. 기존함수와 차별을 두기 위해 숫자를 늘렸다.
accept4() dup3() getentropy() pipe2() secure_getenv() reallocarray() quick_exit() |
그리고 C18의 stdalign.h에 포함된 alignas와 alignof가 POSIX.1-2024에 도입되었다. (기존에 제공된 _Alignas, _Alignof도 당연히 사용할 수 있으며 alias로 제공된다) stdatomic.h도 표준으로 포함되어 atomic_... 으로 시작하는 메모리 변경이나 테스트 기능을 사용할 수 있다. 스레드 환경에서 전역변수 flag 값을 변경할 때는 되도록이면 atomic 기능을 사용하는 것이 유리하다. C11의 aligned_alloc도 제공되지만, posix_memalign이 더 나은 방법이다. 하지만 일반적인 GCC 환경에서는 그냥 malloc을 쓰는게 낫다.
3.3. 제거된 기능
먼저 구식(obsolescent status) 함수로 지정되었거나 제거(removed)된 기능은 다음과 같다.
= 주: obsolescent status로 지정된 함수는 유예기간을 거쳐서 표준에서 제거된다. 보통 10여년 정도 유예를 둔다.
😰 Obsolescent status 로 지정 : inet_addr, inet_ntoa, encrypt, setkey
제거된 주요 함수 (리눅스에서 지원하지 않는 fattach나 ulimit 같은 함수는 적지 않았다)
ftw - nftw를 대신 사용 getitimer, setitimer gets gettimeofday isascii, toascii rand_r utime |
시그널 관련 다음 함수들도 모두 제거되었다.
sighold() sigignore() siginterrupt() sigpause() sigrelse() sigset() |
표준에서 제거된(removed) 함수는 유닉스 표준을 지키는 운영체제에서 필수로 제공할 의무가 없는 함수들이다. 그래도 과거와의 호환성을 위해 계속 제공될 가능성이 높다.
의무가 없는 함수들은 2가지 측면에서 조심해야 한다. 첫번째는 기능적인 문제 때문에 새로운 함수가 제안된 경우이고, 둘째는 이식성이 없어서 다른 여러 유닉스 혹은 UNIX-like 운영체제로 포팅하는 경우에는 제대로 작동을 보장하지 않는 것이다. 특히 첫번째 이유로서 제거된 대표적인 함수는 gettimeofday로 이는 윤초로 인해 흐른 시간을 구할 때 마이너스 값이 나올 수 있음을 유의해야 하기 때문에 제거되었다. 대신에 clock_gettime이 제공된다. 이미 과거부터 계속해서 경고를 했었던터라 이제는 사용이 많이 줄어들었다. 제거된 함수는 사용해도 당분간 문제는 없지만, 마구잡이로 쓰다간 잠재적 버그를 만들 가능성이 높다. 하지만 이식성을 생각하지 않는 경우라면 사용해도 무방한 경우도 있다.
어떤 removed 함수가 사용해도 무방한지 아닌지는 SUS의 previouse 버전의 man 표준 문서의 application usage나 rationale, future directions 부분을 참고해야만 한다.
4. 결론
온라인 문서(https://pubs.opengroup.org/onlinepubs/9799919799/)라도 한번 살펴보자. 끝.
* 히스토리
2024-11-25 초안
'컴퓨터 관련 > 리눅스(유닉스) 일반' 카테고리의 다른 글
페도라 리눅스 nvidia 드라이버 설치 (RPM Fusion akmods, 24년 10월 기준) (0) | 2024.10.19 |
---|---|
썬더볼트 장치 스캔 방법 - Fedora Linux / Windows (2) | 2024.02.26 |
[CentOS7] vim 7.4의 python3 지원 (0) | 2022.11.23 |
Fedora 35 : Thunderbolt 4 Maple ridge 인식 실패 문제 (0) | 2022.05.09 |
Failed to initialize NVML (Fedora 리눅스) (0) | 2020.11.28 |
리눅스 배포판 순위 : distrowatch에 대한 오해 (10) | 2019.12.05 |
bash : 기초 : 셸의 역사, 종류 (0) | 2019.10.13 |
파일(file)에 대한 토막글 : 파일이란 무엇인가? (18) | 2019.03.08 |