UNIX 표준화와 구현들
1980년대 미합중국 정부의 UNIX 표준화 요청으로 인해 시작됨. 아직도 진행중
-> 각 구현이 반드시 정의해야 하는 여러 한계들의 명세
# UNIX 표준화
2.2.1. ISO C
1989년 후반 C 언어에 대한 ANSI 표준 X3.159-1989가 승인됨.
이 표준은 국제 표준인 ISO/IEC 9899:1990에도 채용됨.
ANSI( American National Standards Institue) : 미국 표준 협회
ISO ( International Organization for Standardization ) : 국제 표준 기구
IEC( International Electrotechnical Commission ) : 국제전자기술위원회
현재 C 언어 표준은 ISO/IEC 국제 표준 작업 그룹인 ISO/IEC JTC1/SC22/WG14 에서 관리함.
줄여서 WG14 라고 부름
* ISO C 표준의 목적
- 표준을 준수하는 C 언어로 구현된 UNIX system을 비롯한 광범위한 운영체제들에 대한 이식성 촉진
즉, 여러 Unix 버전들에 대한 상호간 호환성을 높이기 위한 작업?
대충 그렇게 이해하면 됨
모든 Unix 시스템이 C 표준에 명시된 모든 라이브러리(즉, ISO C 표준 라이브러리)를 정의한다.
ISO C 표준 라이브러리는 현재의 모든 Unix 시스템이 C 표준에 명시된 라이브러리 루틴들을 제공한다는 점에서 중요
* ISC C 표준 갱신
- 1999년 ISO/IEC 9899:1999라는 표준으로 승인
(restrict 키워드 추가됨. restrict 키워드는 컴파일러에게 어떤 포인터 참조를 최적화할 수 있는지 알려주는 역할)
* ISO C 표준에 정의된 헤더들(POSIX.1 표준의 필수 헤더들이기도 함)
Header
|
FreeBSD 5.2.1
|
Linux 2.4.22
|
Mac OS X 10.3
|
Solaris 9
|
Description
|
---|---|---|---|---|---|
<assert.h>
|
•
|
•
|
•
|
•
|
verify program assertion
|
<complex.h>
|
•
|
•
|
•
|
complex arithmetic support
| |
<ctype.h>
|
•
|
•
|
•
|
•
|
character types
|
<errno.h>
|
•
|
•
|
•
|
•
|
error codes (Section 1.7)
|
<fenv.h>
|
•
|
•
|
floating-point environment
| ||
<float.h>
|
•
|
•
|
•
|
•
|
floating-point constants
|
<inttypes.h>
|
•
|
•
|
•
|
•
|
integer type format conversion
|
<iso646.h>
|
•
|
•
|
•
|
•
|
alternate relational operator macros
|
<limits.h>
|
•
|
•
|
•
|
•
|
implementation constants (Section 2.5)
|
<locale.h>
|
•
|
•
|
•
|
•
|
locale categories
|
<math.h>
|
•
|
•
|
•
|
•
|
mathematical constants
|
<setjmp.h>
|
•
|
•
|
•
|
•
|
nonlocal goto (Section 7.10)
|
<signal.h>
|
•
|
•
|
•
|
•
|
signals (Chapter 10)
|
<stdarg.h>
|
•
|
•
|
•
|
•
|
variable argument lists
|
<stdbool.h>
|
•
|
•
|
•
|
•
|
boolean type and values
|
<stddef.h>
|
•
|
•
|
•
|
•
|
standard definitions
|
<stdint.h>
|
•
|
•
|
•
|
integer types
| |
<stdio.h>
|
•
|
•
|
•
|
•
|
standard I/O library (Chapter 5)
|
<stdlib.h>
|
•
|
•
|
•
|
•
|
utility functions
|
<string.h>
|
•
|
•
|
•
|
•
|
string operations
|
<tgmath.h>
|
•
|
type-generic math macros
| |||
<time.h>
|
•
|
•
|
•
|
•
|
time and date (Section 6.10)
|
<wchar.h>
|
•
|
•
|
•
|
•
|
extended multibyte and wide character support
|
<wctype.h>
|
•
|
•
|
•
|
•
|
wide character classification and mapping support
|
2.2.2. IEEE POSIX
* POSIX(표준 운영체제 인터페이스 : Portable Operating System Interface)
- IEEE( 전기 전자 기술자 협회 : Institute of Electrical and Electronics Engineers)가 개발한 일련의 표준 모음
- 원래는 운영체제 인터페이스에 대한 명세인 IEEE Standard 1003.1-1998만을 칭하였으나, 이후 Shell과 Utility들에 대한 명세(1003.2)를
포함한 여러 1003번대 표준들과 초안들을 통칭하는 용어로 쓰이게 되었음.
* IEEE Standard 1003.1-1998 표준의 목적
- 다양한 UNIX system 환경들 사이에서의 응용프로그램 이식성 촉진
IEEE Standard 1003.1-1998 표준은 UNIX 운영체제에 기초하고 있긴 하지만, 이 표준이 UNIX와 UNIX류의 시스템들에만 국한된게 아니다.
IEEE Standard 1003.1-1998 표준의 문구가 수정되어 ISO에 제출되었고, 그 결과 공표된 것이 IEEE Standard 1003.1-1990임.
이것은 국제 표준 ISO/IEC 9945-1:1990 임. 이 표준을 흔히 POSIX.1 이라고 칭함
1993년 : IEEE Standard 1003.1-1993 표준 공표 (1003.1-1993 표준 + 1003.1b-1993 실시간 확장 표준)
1996년 : 1003.1-1993 표준이 갱신되어 ISO/IEC 9945-1:1996 표준 공표 ( Multithread 관련 인터페이스인 Pthreads가 포함됨)
1999년 : IEEE Standard 1003.1d-1999 표준 공표 ( 실시간 인터페이스 추가)
2000년 : IEEE Standard 1003.1j-2000 표준 공표( 실시간 인터페이스 추가), IEEE Standard 1003.1q-2000 표준 공표 ( 사건 추적 확장 추가)
2001년 : 여러 1003.1 수정안 + 1003.2 표준, 단일(Single UNIX Specification, SUS) 버전 2의 일부가 결합됨
* POSIX 표준이 정의하는 필수 헤더들
Header
|
FreeBSD 5.2.1
|
Linux 2.4.22
|
Mac OS X 10.3
|
Solaris 9
|
Description
|
---|---|---|---|---|---|
<dirent.h>
|
•
|
•
|
•
|
•
|
directory entries (Section 4.21)
|
<fcntl.h>
|
•
|
•
|
•
|
•
|
file control (Section 3.14)
|
<fnmatch.h>
|
•
|
•
|
•
|
•
|
filename-matching types
|
<glob.h>
|
•
|
•
|
•
|
•
|
pathname pattern-matching types
|
<grp.h>
|
•
|
•
|
•
|
•
|
group file (Section 6.4)
|
<netdb.h>
|
•
|
•
|
•
|
•
|
network database operations
|
<pwd.h>
|
•
|
•
|
•
|
•
|
password file (Section 6.2)
|
<regex.h>
|
•
|
•
|
•
|
•
|
regular expressions
|
<tar.h>
|
•
|
•
|
•
|
•
|
tar archive values
|
<termios.h>
|
•
|
•
|
•
|
•
|
terminal I/O (Chapter 18)
|
<unistd.h>
|
•
|
•
|
•
|
•
|
symbolic constants
|
<utime.h>
|
•
|
•
|
•
|
•
|
file times (Section 4.19)
|
<wordexp.h>
|
•
|
•
|
•
|
word-expansion types
| |
<arpa/inet.h>
|
•
|
•
|
•
|
•
|
Internet definitions (Chapter 16)
|
<net/if.h>
|
•
|
•
|
•
|
•
|
socket local interfaces (Chapter 16)
|
<netinet/in.h>
|
•
|
•
|
•
|
•
|
Internet address family (Section 16.3)
|
<netinet/tcp.h>
|
•
|
•
|
•
|
•
|
Transmission Control Protocol definitions
|
<sys/mman.h>
|
•
|
•
|
•
|
•
|
memory management declarations
|
<sys/select.h>
|
•
|
•
|
•
|
•
|
select function (Section 14.5.1)
|
<sys/socket.h>
|
•
|
•
|
•
|
•
|
sockets interface (Chapter 16)
|
<sys/stat.h>
|
•
|
•
|
•
|
•
|
file status (Chapter 4)
|
<sys/times.h>
|
•
|
•
|
•
|
•
|
process times (Section 8.16)
|
<sys/types.h>
|
•
|
•
|
•
|
•
|
primitive system data types (Section 2.8)
|
<sys/un.h>
|
•
|
•
|
•
|
•
|
UNIX domain socket definitions (Section 17.3)
|
<sys/utsname.h>
|
•
|
•
|
•
|
•
|
system name (Section 6.9)
|
<sys/wait.h>
|
•
|
•
|
•
|
•
|
process control (Section 8.6)
|
현재 POSIX.1 표준은 Austin Group 이라고 하는 개방된 작업 그룹에서 관리함고 있음.
* POSIX 표준이 정의하는 XSI 확정 헤더들
Header
|
FreeBSD 5.2.1
|
Linux 2.4.22
|
Mac OS X 10.3
|
Solaris 9
|
Description
|
---|---|---|---|---|---|
<cpio.h>
|
•
|
•
|
•
|
cpio archive values
| |
<dlfcn.h>
|
•
|
•
|
•
|
•
|
dynamic linking
|
<fmtmsg.h>
|
•
|
•
|
•
|
message display structures
| |
<ftw.h>
|
•
|
•
|
file tree walking (Section 4.21)
| ||
<iconv.h>
|
•
|
•
|
•
|
codeset conversion utility
| |
<langinfo.h>
|
•
|
•
|
•
|
•
|
language information constants
|
<libgen.h>
|
•
|
•
|
•
|
•
|
definitions for pattern-matching function
|
<monetary.h>
|
•
|
•
|
•
|
•
|
monetary types
|
<ndbm.h>
|
•
|
•
|
•
|
database operations
| |
<nl_types.h>
|
•
|
•
|
•
|
•
|
message catalogs
|
<poll.h>
|
•
|
•
|
•
|
•
|
poll function (Section 14.5.2)
|
<search.h>
|
•
|
•
|
•
|
•
|
search tables
|
<strings.h>
|
•
|
•
|
•
|
•
|
string operations
|
<syslog.h>
|
•
|
•
|
•
|
•
|
system error logging (Section 13.4)
|
<ucontext.h>
|
•
|
•
|
•
|
•
|
user context
|
<ulimit.h>
|
•
|
•
|
•
|
•
|
user limits
|
<utmpx.h>
|
•
|
•
|
user accounting database
| ||
<sys/ipc.h>
|
•
|
•
|
•
|
•
|
IPC (Section 15.6)
|
<sys/msg.h>
|
•
|
•
|
•
|
message queues (Section 15.7)
| |
<sys/resource.h>
|
•
|
•
|
•
|
•
|
resource operations (Section 7.11)
|
<sys/sem.h>
|
•
|
•
|
•
|
•
|
semaphores (Section 15.8)
|
<sys/shm.h>
|
•
|
•
|
•
|
•
|
shared memory (Section 15.9)
|
<sys/statvfs.h>
|
•
|
•
|
•
|
file system information
| |
<sys/time.h>
|
•
|
•
|
•
|
•
|
time types
|
<sys/timeb.h>
|
•
|
•
|
•
|
•
|
additional date and time definitions
|
<sys/uio.h>
|
•
|
•
|
•
|
•
|
vector I/O operations (Section 14.7)
|
* POSIX 표준이 정의하는 선택적인 헤더들
Header
|
FreeBSD 5.2.1
|
Linux 2.4.22
|
Mac OS X 10.3
|
Solaris 9
|
Description
|
---|---|---|---|---|---|
<aio.h>
|
•
|
•
|
•
|
•
|
asynchronous I/O
|
<mqueue.h>
|
•
|
•
|
message queues
| ||
<pthread.h>
|
•
|
•
|
•
|
•
|
threads (Chapters 11 and 12)
|
<sched.h>
|
•
|
•
|
•
|
•
|
execution scheduling
|
<semaphore.h>
|
•
|
•
|
•
|
•
|
semaphores
|
<spawn.h>
|
•
|
real-time spawn interface
| |||
<stropts.h>
|
•
|
•
|
XSI STREAMS interface (Section 14.4)
| ||
<trace.h>
|
event tracing
|
* POSIX.1 선택적 인터페이스 그룹 및 해당 부호
Code
|
SUS mandatory
|
Symbolic constant
|
Description
|
---|---|---|---|
ADV
|
_POSIX_ADVISORY_INFO
|
advisory information (real-time)
| |
AIO
|
_POSIX_ASYNCHRONOUS_IO
|
asynchronous input and output (real-time)
| |
BAR
|
_POSIX_BARRIERS
|
barriers (real-time)
| |
CPT
|
_POSIX_CPUTIME
|
process CPU time clocks (real-time)
| |
CS
|
_POSIX_CLOCK_SELECTION
|
clock selection (real-time)
| |
CX
|
•
|
extension to ISO C standard
| |
FSC
|
•
|
_POSIX_FSYNC
|
file synchronization
|
IP6
|
_POSIX_IPV6
|
IPv6 interfaces
| |
MF
|
•
|
_POSIX_MAPPED_FILES
|
memory-mapped files
|
ML
|
_POSIX_MEMLOCK
|
process memory locking (real-time)
| |
MLR
|
_POSIX_MEMLOCK_RANGE
|
memory range locking (real-time)
| |
MON
|
_POSIX_MONOTONIC_CLOCK
|
monotonic clock (real-time)
| |
MPR
|
•
|
_POSIX_MEMORY_PROTECTION
|
memory protection
|
MSG
|
_POSIX_MESSAGE_PASSING
|
message passing (real-time)
| |
MX
|
IEC 60559 floating-point option
| ||
PIO
|
_POSIX_PRIORITIZED_IO
|
prioritized input and output
| |
PS
|
_POSIX_PRIORITIZED_SCHEDULING
|
process scheduling (real-time)
| |
RS
|
_POSIX_RAW_SOCKETS
|
raw sockets
| |
RTS
|
_POSIX_REALTIME_SIGNALS
|
real-time signals extension
| |
SEM
|
_POSIX_SEMAPHORES
|
semaphores (real-time)
| |
SHM
|
_POSIX_SHARED_MEMORY_OBJECTS
|
shared memory objects (real-time)
| |
SIO
|
_POSIX_SYNCHRONIZED_IO
|
synchronized input and output (real-time)
| |
SPI
|
_POSIX_SPIN_LOCKS
|
spin locks (real-time)
| |
SPN
|
_POSIX_SPAWN
|
spawn (real-time)
| |
SS
|
_POSIX_SPORADIC_SERVER
|
process sporadic server (real-time)
| |
TCT
|
_POSIX_THREAD_CPUTIME
|
thread CPU time clocks (real-time)
| |
TEF
|
_POSIX_TRACE_EVENT_FILTER
|
trace event filter
| |
THR
|
•
|
_POSIX_THREADS
|
threads
|
TMO
|
_POSIX_TIMEOUTS
|
timeouts (real-time)
| |
TMR
|
_POSIX_TIMERS
|
timers (real-time)
| |
TPI
|
_POSIX_THREAD_PRIO_INHERIT
|
thread priority inheritance (real-time)
| |
TPP
|
_POSIX_THREAD_PRIO_PROTECT
|
thread priority protection (real-time)
| |
TPS
|
_POSIX_THREAD_PRIORITY_SCHEDULING
|
thread execution scheduling (real-time)
| |
TRC
|
_POSIX_TRACE
|
trace
| |
TRI
|
_POSIX_TRACE_INHERIT
|
trace inherit
| |
TRL
|
_POSIX_TRACE_LOG
|
trace log
| |
TSA
|
•
|
_POSIX_THREAD_ATTR_STACKADDR
|
thread stack address attribute
|
TSF
|
•
|
_POSIX_THREAD_SAFE_FUNCTIONS
|
thread-safe functions
|
TSH
|
•
|
_POSIX_THREAD_PROCESS_SHARED
|
thread process-shared synchronization
|
TSP
|
_POSIX_THREAD_SPORADIC_SERVER
|
thread sporadic server (real-time)
| |
TSS
|
•
|
_POSIX_THREAD_ATTR_STACKSIZE
|
thread stack address size
|
TYM
|
_POSIX_TYPED_MEMORY_OBJECTS
|
typed memory objects (real-time)
| |
XSI
|
•
|
_XOPEN_UNIX
|
X/Open extended interfaces
|
XSR
|
_XOPEN_STREAMS
|
XSI STREAMS
|
2.2.3. 단일 UNIX 규격
기본적인 POSIX.1 명세가 제공하는 기능성을 확장하는 추가적인 인터페이스들을 명시
이런 시스템 인터페이스들의 전체 집합을 X/Open system Interface(XSI)로 칭함
_XOPEN_UNIX 라는 기호 상수 - XSI 확장들의 일부인 인터페이스들을 식별하는 용도
* XSI를 준수하기 위해 반드시 지원해야 될 것들
- 파일 동기화
- Memory mapped file
- 메모리 보호
- 스레드 인터페이스
XSI를 준수해야 Unix 시스템이라 불릴 수 있다.
* XSI의 옵션 그룹(기능성에 따라 나뉨)
- 암호화(Encryption) : 기호 상수 _XOPEN_CRYPT으로 표시
- 실시간 (Real-time) : 기호 상수 _XOPEN_REALTIME으로 표시
- 고급 실시간 (Advanced real-time)
- 실시간 쓰레드(Real-time threads) : 기호 상수 _XOPEN_REALTIME_THREADS로 표시됨.
- 고급 실시간 쓰레드(Advanced real-time threads)
- 추적(Tracing)
- XSI STREAMS: 기호 상수 _XOPEN_STREAMS로 표시됨.
- 유물(Legacy): 기호 상수 _XOPEN_LEGACY로 표시됨.
* The Open group
- 단일 UNIX 규격은 The Open group에서 발행
- 1996년 업계 컨소시엄인 X/Open과 Open Software Foundation(OSF)의 합병으로 탄생함.
- X/Open은 X/Open Portability Guide 공표
* 단일 UNIX 규격의 역사
1994년 : X/Open에서 최초 버전 공표, 이를 Spec 1170이라고도 함(1170개의 인터페이스 포함)
COSE(Common Open Software Environment) 그룹에서 주도함
COSE그룹에 포함된 기업은 Sun, IBM, Novell/ULS, OSF 임
Spec 1170에는 X/Open Common Application Environment(CAE) Issue 4(XPG4라고도 지칭),
System V Interface Definition(SVID), Edition 3, Level 1 인터페이스들
그리고, OSF Application Environment Specfication(AES) Full Use 인터페이스들 포함.
1997년 : 단일 UNIX 규격 둘째 버전 공표
쓰레드, 실시간 인터페이스, 64 비트 처리, 대형 파일, 개선된 다중 바이트 문자처리에 대한 지원 추가
2001년 : 단일 UNIX 규격 셋째 버전(SUSv3) 공표
SUSv3의 기본 명세(Base Specifications)는 IEEE Standard 1003.1-2001과 동일함
아래의 4개 섹션으로 구성됨
a. Base Definitioin
b. System Interface
c. Shell and Utilities
d. Rationale
X/Open Curses Issue 4, Version 2도 포함하지만 이는 POSIX.1의 일부가 아님
2002년 : 국제 표준 기구(ISO)에서 SUSv3을 ISO/IEC 9945:2002로 승인함.
2003년 : The Open group이 1003.1을 갱신(기술적 오류 정정), 국제 표준 기구(ISO)에서 SO/IEC 9945:2003로 승인함.
2004년 4월 : The Open group이 표준 본문의 기술적 오류들을 교정한 SUSv3 2004년판 발표
2.2.4. FIPS
* FIPS(미연방 정보처리 표준 : Federal Information Processing Standard)
- 미연방 정부의 컴퓨터 시스템 조달에 사용함.
* FIPS 151-1(1989년 4월)
- IEEE Std. 1003.1-1998, ANSI C 표준의 초안 기호
* FIPS 151-2
- POSIX.1에서 선택적인 기능들로 분류된 것들 중 일부를 필수로 요구함.
- POSIX.1-2001에서 필수적인 것으로 포함됨
POSIX.1 FIPS는 현재 폐기된 상태임
2.3 UNIX Systems 구현들
이제까지 언급된 표준들은 인터페이스에 대한 명시일 뿐
PDP-11에서 실행되는 UNIX Time-Sharing System의 버전6과 버전 7 이후
세가지 시스템으로 갈라짐.
1) AT&T에서 시작된 System 3와 System V(UNIX System의 상용 버전)
2) Berkeley의 University of California에서 만든 4.x BSD 구현들
3) AT&T Bell Laboratories의 Computing Science Research Center가 개발한 UNIX System 연구 버전에서 비롯되어
UNIX Time-Sharing System 버전 8, 버전 9를 거쳐 1990년 버전 10에서 끝나는 구현들
2.3.1 UNIX System V Release 4(SVR4)
AT&T의 UNIX System Laboratories(USL, 전신은 AT&T의 UNIX Software Operation)가 개발함.
AT&T UNIX System V Release 3.2(SVR 3.2) + Sun Microsystems의 Sun OS + University of California의 4.3 BSD 릴리스
+ Microsoft의 Xenix 시스템 => SVR4
SVR4의 소스코드는 1989년 후반에 발표, 1990년 End user를 위한 복사본 발매
SVR4는 POSIX 1003.1 표준과 X/Open Portability Guide, Issue 3(XPG3) 준수함.
* SVID(System V Interface Definition, 1989년 발표)
- SVR4를 준수하기 위해 운영체제가 반드시 제공해야 하는 기능성을 포함한 인터페이스 명시
- System Call과 Library 를 구분하지 않음
2.3.2 4.4BSD
Berkeley Software Distribution(BSD) 계열은 UC Berkeley의 Computer Systems Research Group(CSRG)가 개발하고 배포함.
1983년 : 4.2 BSD,VAX 미니 컴퓨터에서 실행
1986년 : 4.3 BSD,VAX 미니 컴퓨터에서 실행
1988년 : 4.3 BSD Tahoe, Tahoe 미니 컴퓨터에서 실행
1989년 : 4.3 BSD Tahoe 릴리즈의 비 AT&T 소스 코드를 대량으로 식별해서 BSD Networking Software, Release 1.0으로 공개
1990년 : 4.3 BSD Reno 릴리즈. POSIX.1의 여러 기능들을 지원함.
1991년 : 4.3 BSD Reno 에서 비롯된 BSD Networking Software, Release 2.0 공개
4.4 BSD 시스템의 대부분을 AT&T 라이센스 제약에서 벗어나게 함으로써 소스코드를 모두가 사용할 수 있도록 함.
1994년 : 라이센스 제약을 완전히 벗어난 4.4 BSD-Lite 공개
1995년 : 4.4 BSD-Lite의 버그를 교정한 Release 2 공개함.
UC Berkeley의 Computer Systems Research Group가 마지막으로 만든 BSD 버전임.
1990년대 초반 : 개인용 컴퓨터상에서도 돌아가는 386 BSD 발매, 이 소스코드의 상당 부분이 BSD Networking Software, Release 2.0에 포함됨
2.3.3 FreeBSD
4.4BSD-Lite 운영체제를 기초한 것으로써 1990년대 중반 이후 방치된 BSD 계열을 있기 위해 만들어짐.
2.3.4 Linux
2.3.5 Mac OS X
핵심 운영체제는 Mach 커널과 FreeBSD 운영체제에 기초한 "Darwin"이다. 이는 오픈소스 프로젝트로 관리되고 있음.
2.3.6 Sun Solaris
SVR4를 기초로 해서 Sun Microsystems의 엔지니어들이 10년 넘게 개선함 결과물.
SVR4 후손중 유일하게 상업적으로 성공함.
2.3.7 그밖의 UNIX 시스템들
- AIX, IBM의 UNIX System 버전
- HP-UX, HP의 UNIX System 버전
- IRIX, Silicon Graphics가 출시함
- UnixWare, SVR4의 후손이자 현재 SCO가 판매하는 버전
2.4 표준과 구현의 관계
여러 UNIX 표준들에 대한 구현들이 예전 릴리즈(SVR3.2와 4.3BSD 등)의 기능들을 위해 하위 호환성을 제공한다.
ex) Solaris는 비차단 I/O (O_NONBLOCK)에 대한 POSIX.1 명세와 전통적인 System V 방법(O_NDELAY)을 모두 지원함.
2.5 한계들
1) 컴파일 시점 한계들 ex) 짧은 정수의 최대값
2) 실행시점 한계들 ex) 하나의 파일이름의 최대 문자수
각 파일시스템 유형마다 해당 한계가 다를 수 있음.
그래서 아래와 같이 다시 분류함.
1) 컴파일 시점 한계들(헤더)
2) 파일이나 디렉토리와는 무관한 실행시점 한계들(sysconf 함수)
3) 파일이나 디렉토리와 연관된 실행시점 한계들(pathconf 함수와 fpathconf 함수)
* <limits.h>에 나온 정수 값 크기들
Name
|
Description
|
Minimum acceptable value
|
Typical value
|
---|---|---|---|
CHAR_BIT
|
bits in a char
|
8
|
8
|
CHAR_MAX
|
max value of char
|
(see later)
|
127
|
CHAR_MIN
|
min value of char
|
(see later)
|
128
|
SCHAR_MAX
|
max value of signed char
|
127
|
127
|
SCHAR_MIN
|
min value of signed char
|
127
|
128
|
UCHAR_MAX
|
max value of unsigned char
|
255
|
255
|
INT_MAX
|
max value of int
|
32,767
|
2,147,483,647
|
INT_MIN
|
min value of int
|
32,767
|
2,147,483,648
|
UINT_MAX
|
max value of unsigned int
|
65,535
|
4,294,967,295
|
SHRT_MIN
|
min value of short
|
32,767
|
32,768
|
SHRT_MAX
|
max value of short
|
32,767
|
32,767
|
USHRT_MAX
|
max value of unsigned short
|
65,535
|
65,535
|
LONG_MAX
|
max value of long
|
2,147,483,647
|
2,147,483,647
|
LONG_MIN
|
min value of long
|
2,147,483,647
|
2,147,483,648
|
ULONG_MAX
|
max value of unsigned long
|
4,294,967,295
|
4,294,967,295
|
LLONG_MAX
|
max value of long long
|
9,223,372,036,854,775,807
|
9,223,372,036,854,775,807
|
LLONG_MIN
|
min value of long long
|
9,223,372,036,854,775,807
|
9,223,372,036,854,775,808
|
ULLONG_MAX
|
max value of unsigned long long
|
18,446,744,073,709,551,615
|
18,446,744,073,709,551,615
|
MB_LEN_MAX
|
max number of bytes in a multibyte character constant
|
1
|
16
|
2.5.1 ISO C가 정의하는 한계들
모두 컴파일 시점 한계들
unsigned type의 최소값은 0이다.
64 bit 시스템에서 long 정수의 최대값은 long long 정수의 최대값과 동일함.
문자값이 부호있는 정수인지 부호없는 정수인지는 시스템마다 다를 수 있다.
CHAR_MIN와 SCHAR_MIN이 동일하고, CHAR_MAX가 SCHAR_MAX와 동일하다면 해당 시스템은 문자 값이 부호 있는 정수이다.
문자 값이 부호 없는 정수인 시스템의 경우 CHAR_MIN이 0이고, CHAR_MAX가 UCHAR_MAX와 동일함.
* FOPEN_MAX (ISO C 상수)
- 아래는 stdio.h 헤더파일 내용
/* Get the values:
L_tmpnam How long an array of chars must be to be passed to `tmpnam'.
TMP_MAX The minimum number of unique filenames generated by tmpnam
(and tempnam when it uses tmpnam's name space),
or tempnam (the two are separate).
L_ctermid How long an array to pass to `ctermid'.
L_cuserid How long an array to pass to `cuserid'.
FOPEN_MAX Minimum number of files that can be open at once.
FILENAME_MAX Maximum length of a filename. */
#include <bits/stdio_lim.h>
- 아래는 stdio_lim.h 헤더파일 내용
#if defined __need_FOPEN_MAX || defined _STDIO_H
# undef FOPEN_MAX
# define FOPEN_MAX 16
#endif
- 한 구현에서 동시에 열어둘 수 있는 표준 I/O 스트림 개수
- ISO 표준이 요구하는 최소값은 8 이다.
- POSIX.1의 상수인 STREAM_MAX가 정의되어 있는 경우 반드시 FOPEN_MAX와 같아야 함.
[wonsik@as48-x64 bits]$ grep STREAM_MAX posix1_lim.h
#define _POSIX_STREAM_MAX 8
* TMP_MAX (ISO C 상수)
- tmpnam 함수가 생성하는 고유한 파일이름들의 최대 개수
- <stdio.h> 헤더 파일에 정의됨
* 여러 플랫폼들에서의 ISO 한계들
Limit
|
FreeBSD 5.2.1
|
Linux 2.4.22
|
Mac OS X 10.3
|
Solaris 9
|
---|---|---|---|---|
FOPEN_MAX
|
20
|
16
|
20
|
20
|
TMP_MAX
|
308,915,776
|
238,328
|
308,915,776
|
17,576
|
2.5.2 POSIX가 정의하는 한계들
POSIX.1에서 정의하는 한계들과 상수들의 5가지 범주
1) 불변(invariant) 최소값: <limits.h>에 정의되는 POSIX.1 불변 최소값들 참조
2) 불변 값 : SSIZE_MAX
3) 실행시점 증가 가능 값 : CHARCLASS_NAME_MAX, COLL_WEIGHT_MAX, LINE_MAX, MGROUPS_MAX, RE_DUP_MAX
4) 실행 시점 불변 값(미결정일 수도 있음) : ARG_MAX, CHILD_MAX, HOST_NAME_MAX, LOGIN_NAME_MAX, OPEN_MAX, PAGESIZE, RE_DUP_MAX,
STREAM_MAX, SYMLOOP_MAX, TTY_NAME_MAX, TZNAME_MAX
5) 경로 이름 가변 값(미결정일 수도 있음) : FILESIZEBITS, LINK_MAX, MAX_CANON, MAX_INPUT, NAME_MAX, PATH_MAX, PIPE_BUF, SYMLINK_MAX
POSIX.1 을 준수하는 구현은 반드시 지정된 최소값 이상의 값을 제공해야 한다.
이식성 보장을 위해 POSIX.1을 엄격히 준수하는 application은 주어진 최소 값보다 큰 값을 요구해서는 안된다.
불변 최소값들중 일부는 실용적인 용도로는 너무 작다.
ex) 한 프로세스가 오픈할 수 있는 파일 개수(20개), _POSIX_PATH_MAX에 대한 하한(255),
_POSIX_OPEN_MAX 상수와 _POSIX_PATH_MAX 상수를 컴파일 시점에서 배열 크기로 사용할 수 없다.
* <limits.h>에 정의하는 POSIX.1 불변 최소값들
Name
|
Description: minimum acceptable value for
|
Value
|
---|---|---|
_POSIX_ARG_MAX
|
length of arguments to exec functions
|
4,096
|
_POSIX_CHILD_MAX
|
number of child processes per real user ID
|
25
|
_POSIX_HOST_NAME_MAX
|
maximum length of a host name as returned by gethostname
|
255
|
_POSIX_LINK_MAX
|
number of links to a file
|
8
|
_POSIX_LOGIN_NAME_MAX
|
maximum length of a login name
|
9
|
_POSIX_MAX_CANON
|
number of bytes on a terminal's canonical input queue
|
255
|
_POSIX_MAX_INPUT
|
space available on a terminal's input queue
|
255
|
_POSIX_NAME_MAX
|
number of bytes in a filename, not including the terminating null
|
14
|
_POSIX_NGROUPS_MAX
|
number of simultaneous supplementary group IDs per process
|
8
|
_POSIX_OPEN_MAX
|
number of open files per process
|
20
|
_POSIX_PATH_MAX
|
number of bytes in a pathname, including the terminating null
|
256
|
_POSIX_PIPE_BUF
|
number of bytes that can be written atomically to a pipe
|
512
|
_POSIX_RE_DUP_MAX
|
number of repeated occurrences of a basic regular expression permitted by the regexecand regcomp functions when using the interval notation \{m,n\}
|
255
|
_POSIX_SSIZE_MAX
|
value that can be stored in ssize_t object
|
32,767
|
_POSIX_STREAM_MAX
|
number of standard I/O streams a process can have open at once
|
8
|
_POSIX_SYMLINK_MAX
|
number of bytes in a symbolic link
|
255
|
_POSIX_SYMLOOP_MAX
|
number of symbolic links that can be traversed during pathname resolution
|
8
|
_POSIX_TTY_NAME_MAX
|
length of a terminal device name, including the terminating null
|
9
|
_POSIX_TZNAME_MAX
|
number of bytes for the name of a time zone
|
6
|
위 19가지 구현 값들 모두가 <limits.h> 헤더에 정의되어 있다는 보장은 없다.
ex) 주어진 프로세스에 대한 어떤 실제 값이 시스템의 가용 메모리 용량에 의존하단다면 그 값은 헤더에 포함되지 않을 수 있다.
헤더에 정의되어 있지 않은 값들은 컴파일 시점에서 배열 크기로 사용할 수 없다.
그래서 POSIX.1은 프로세스가 실행 시점에서 실제 구현 값을 얻고자 할 때 호출할 수 있는 세가지 함수는
- sysconf
- pathconf
- fpathconf
POSIX.1에 정의된 값들 중 일부는 "미결정" 일 수 있다.
미결정된 값은 논리적으로 무한대임.
====> 어떤 값이 미결정이라는 것은 현실적으로 의미를 가지는 상한이 없음을 의미
ex) Linux의 readv(), writev()에 사용할 수 있는 iovec 구조체들의 개수는 오직 시스템 메모리 용량에만 제한을 받음.
==> Linux의 IOV_MAX 상수는 미결정으로 간주함.
2.5.3 XSI (X/Open System Interface)가 정의하는 한계들
1) 불변 최소값 : <limits.h>에 정의되는 XSI 불변 최소값들 참조
2) 수치적 한계 : LONG_BIT와 WORD_BIT
3) 실행시점 불변 값(미결정일 수도 있음): ATEXIT_MAX,IOV_MAX,PAGE_SIZE
단일 UNIX 규격은 XSI 준수 시스템들에 대한 좀더 큰 최소값들을 가진 기호들을 추가함.
* <limits.h>에 정의되는 XSI 불변 최소값들
Name
|
Description
|
Minimum acceptable value
|
Typical value
|
---|---|---|---|
NL_ARGMAX
|
maximum value of digit in calls to printf and scanf
|
9
|
9
|
NL_LANGMAX
|
maximum number of bytes in LANG environment variable
|
14
|
14
|
NL_MSGMAX
|
maximum message number
|
32,767
|
32,767
|
NL_NMAX
|
maximum number of bytes in N-to-1 mapping characters
|
(none specified)
|
1
|
NL_SETMAX
|
maximum set number
|
255
|
255
|
NL_TEXTMAX
|
maximum number of bytes in a message string
|
_POSIX2_LINE_MAX
|
2,048
|
NZERO
|
default process priority
|
20
|
20
|
_XOPEN_IOV_MAX
|
maximum number of iovecstructures that can be used with readv or writev
|
16
|
16
|
_XOPEN_NAME_MAX
|
number of bytes in a filename
|
255
|
255
|
_XOPEN_PATH_MAX
|
number of bytes in a pathname
|
1,024
|
1,024
|
2.5.4 sysconf, pathconf, fpathconf 함수
실행시점 한계들을 알고자 할 때, sysconf(), pathconf(), fpathconf() 를 사용
- sysconf
- pathconf
- fpathconf
#include <unistd.h> long sysconf(int name); long pathconf(const char *pathname, int name); long fpathconf(int filedes, int name); |
All three return: corresponding value if OK, 1 on error (see later)
|
sysconf의 인자값으로 올 수 있는 값은 아래를 참조
* sysconf로 얻을 수 있는 한계들과 그에 해당하는 인수 값
Name of limit
|
Description
|
name argument
|
---|---|---|
ARG_MAX
|
maximum length, in bytes, of arguments to the exec functions
|
_SC_ARG_MAX
|
ATEXIT_MAX
|
maximum number of functions that can be registered with the atexit function
|
_SC_ATEXIT_MAX
|
CHILD_MAX
|
maximum number of processes per real user ID
|
_SC_CHILD_MAX
|
clock ticks/second
|
number of clock ticks per second
|
_SC_CLK_TCK
|
COLL_WEIGHTS_MAX
|
maximum number of weights that can be assigned to an entry of the LC_COLLATEorder keyword in the locale definition file
|
_SC_COLL_WEIGHTS_MAX
|
HOST_NAME_MAX
|
maximum length of a host name as returned by gethostname
|
_SC_HOST_NAME_MAX
|
IOV_MAX
|
maximum number of iovec structures that can be used with readv or writev
|
_SC_IOV_MAX
|
LINE_MAX
|
maximum length of a utility's input line
|
_SC_LINE_MAX
|
LOGIN_NAME_MAX
|
maximum length of a login name
|
_SC_LOGIN_NAME_MAX
|
NGROUPS_MAX
|
maximum number of simultaneous supplementary process group IDs per process
|
_SC_NGROUPS_MAX
|
OPEN_MAX
|
maximum number of open files per process
|
_SC_OPEN_MAX
|
PAGESIZE
|
system memory page size, in bytes
|
_SC_PAGESIZE
|
PAGE_SIZE
|
system memory page size, in bytes
|
_SC_PAGE_SIZE
|
RE_DUP_MAX
|
number of repeated occurrences of a basic regular expression permitted by theregexec and regcomp functions when using the interval notation \{m,n\}
|
_SC_RE_DUP_MAX
|
STREAM_MAX
|
maximum number of standard I/O streams per process at any given time; if defined, it must have the same value asFOPEN_MAX
|
_SC_STREAM_MAX
|
SYMLOOP_MAX
|
number of symbolic links that can be traversed during pathname resolution
|
_SC_SYMLOOP_MAX
|
TTY_NAME_MAX
|
length of a terminal device name, including the terminating null
|
_SC_TTY_NAME_MAX
|
TZNAME_MAX
|
maximum number of bytes for the name of a time zone
|
_SC_TZNAME_MAX
|
* pathconf, fpathconf로 얻을 수 있는 한계들과 그에 해당하는 name 인수의 값
Name of limit
|
Description
|
name argument
|
---|---|---|
FILESIZEBITS
|
minimum number of bits needed to represent, as a signed integer value, the maximum size of a regular file allowed in the specified directory
|
_PC_FILESIZEBITS
|
LINK_MAX
|
maximum value of a file's link count
|
_PC_LINK_MAX
|
MAX_CANON
|
maximum number of bytes on a terminal's canonical input queue
|
_PC_MAX_CANON
|
MAX_INPUT
|
number of bytes for which space is available on terminal's input queue
|
_PC_MAX_INPUT
|
NAME_MAX
|
maximum number of bytes in a filename (does not include a null at end)
|
_PC_NAME_MAX
|
PATH_MAX
|
maximum number of bytes in a relative pathname, including the terminating null
|
_PC_PATH_MAX
|
PIPE_BUF
|
maximum number of bytes that can be written atomically to a pipe
|
_PC_PIPE_BUF
|
SYMLINK_MAX
|
number of bytes in a symbolic link
|
_PC_SYMLINK_MAX
|
위 3가지 함수에 대한 주의할 점
1) 세함수 모두, name 인수에 적절한 상수가 지정되지 않았다면 -1을 돌려주며,
errno를 EINVAL(linux 기준 errno=22, Invalid argument)로 설정
2) 일부 name 값의 경우, 함수는 해당 한계의 값을 돌려주거나(이 경우 반환 값은 0 이상)
해당 한계가 미결정임을 나타내는 값을 반환. 미결정인 한계의 경우 -1이 반환되나 errno 값은 변하지 않음
3) _SC_CLK_TCK에 대한 반환값은 초당 클록 틱 수, 이 값은 times의 반환값을 해석하는 데 사용
* pathconf()의 pathname 인수와 fpathconf()의 filedes 인수의 제약 사항
- _PC_MAX_CANON과 _PC_MAX_INPUT에 대해 지정된 파일은 반드시 터미널 파일임.
- _PC_LINK_MAX에 대해 지정된 파일은 파일일 수도 있고, 디렉토리일 수도 있다. 지정된 파일이 디렉토리 일 경우
반환값은 디렉토리내의 파일이름 항목들이 아니라, 디렉토리 자체에 대한 것이다.
- _PC_FILESIZEBITS와 _PC_NAME_MAX에 대해 지정된 파일은 반드시 디렉토리이어야 함.
반환값은 지정된 디렉토리가 작업 디렉토리일 때의 상대 경로이름의 최대 길이
- _PC_PIPE_BUF에 대해 지정된 파일은 반드시 파이프나 FIFO, 디렉토리이어야 함.
반환값은 파이프나 FIFO의 경우 반환값은 지정된 파이프 또는 FIFO에 대한 한계,
디렉토리일 경우 그 디렉토리내에 생성된 임의의 FIFO에 대한 한계
- _PC_SYMLINK_MAX에 대해 지정된 파일은 반드시 디렉토리이어야 함.
반환값은 그 디렉토리 안의 기호링크가 담을 수 있는 문자열의 최대 길이
* 지원되는 모든 설정 한계를 출력하는 C 프로그램을 구축하는 awk 쉘 스크립트
BEGIN {
printf("#include \"apue.h\"\n")
printf("#include <errno.h>\n")
printf("#include <limits.h>\n")
printf("\n")
printf("static void pr_sysconf(char *, int);\n")
printf("static void pr_pathconf(char *, char *, int);\n")
printf("\n")
printf("int\n")
printf("main(int argc, char *argv[])\n")
printf("{\n")
printf("\tif (argc != 2)\n")
printf("\t\terr_quit(\"usage: a.out <dirname>\");\n\n")
FS="\t+"
while (getline <"sysconf.sym" > 0) {
printf("#ifdef %s\n", $1)
printf("\tprintf(\"%s defined to be %%d\\n\", %s+0);\n", $1, $1)
printf("#else\n")
printf("\tprintf(\"no symbol for %s\\n\");\n", $1)
printf("#endif\n")
printf("#ifdef %s\n", $2)
printf("\tpr_sysconf(\"%s =\", %s);\n", $1, $2)
printf("#else\n")
printf("\tprintf(\"no symbol for %s\\n\");\n", $2)
printf("#endif\n")
}
close("sysconf.sym")
while (getline <"pathconf.sym" > 0) {
printf("#ifdef %s\n", $1)
printf("\tprintf(\"%s defined to be %%d\\n\", %s+0);\n", $1, $1)
printf("#else\n")
printf("\tprintf(\"no symbol for %s\\n\");\n", $1)
printf("#endif\n")
printf("#ifdef %s\n", $2)
printf("\tpr_pathconf(\"%s =\", argv[1], %s);\n", $1, $2)
printf("#else\n")
printf("\tprintf(\"no symbol for %s\\n\");\n", $2)
printf("#endif\n")
}
close("pathconf.sym")
exit
}
END {
printf("\texit(0);\n")
printf("}\n\n")
printf("static void\n")
printf("pr_sysconf(char *mesg, int name)\n")
printf("{\n")
printf("\tlong val;\n\n")
printf("\tfputs(mesg, stdout);\n")
printf("\terrno = 0;\n")
printf("\tif ((val = sysconf(name)) < 0) {\n")
printf("\t\tif (errno != 0) {\n")
printf("\t\t\tif (errno == EINVAL)\n")
printf("\t\t\t\tfputs(\" (not supported)\\n\", stdout);\n")
printf("\t\t\telse\n")
printf("\t\t\t\terr_sys(\"sysconf error\");\n")
printf("\t\t} else {\n")
printf("\t\t\tfputs(\" (no limit)\\n\", stdout);\n")
printf("\t\t}\n")
printf("\t} else {\n")
printf("\t\tprintf(\" %%ld\\n\", val);\n")
printf("\t}\n")
printf("}\n\n")
printf("static void\n")
printf("pr_pathconf(char *mesg, char *path, int name)\n")
printf("{\n")
printf("\tlong val;\n")
printf("\n")
printf("\tfputs(mesg, stdout);\n")
printf("\terrno = 0;\n")
printf("\tif ((val = pathconf(path, name)) < 0) {\n")
printf("\t\tif (errno != 0) {\n")
printf("\t\t\tif (errno == EINVAL)\n")
printf("\t\t\t\tfputs(\" (not supported)\\n\", stdout);\n")
printf("\t\t\telse\n")
printf("\t\t\t\terr_sys(\"pathconf error, path = %%s\", path);\n")
printf("\t\t} else {\n")
printf("\t\t\tfputs(\" (no limit)\\n\", stdout);\n")
printf("\t\t}\n")
printf("\t} else {\n")
printf("\t\tprintf(\" %%ld\\n\", val);\n")
printf("\t}\n")
printf("}\n")
}
[wonsik@as48-x64 std]$ awk -f makeconf.awk
#include "apue.h"
#include <errno.h>
#include <limits.h>
static void pr_sysconf(char *, int);
static void pr_pathconf(char *, char *, int);
int
main(int argc, char *argv[])
{
if (argc != 2)
err_quit("usage: a.out <dirname>");
#ifdef ARG_MAX
printf("ARG_MAX defined to be %d\n", ARG_MAX+0);
#else
printf("no symbol for ARG_MAX\n");
#endif
#ifdef _SC_ARG_MAX
pr_sysconf("ARG_MAX =", _SC_ARG_MAX);
#else
printf("no symbol for _SC_ARG_MAX\n");
#endif
#ifdef ATEXIT_MAX
printf("ATEXIT_MAX defined to be %d\n", ATEXIT_MAX+0);
#else
printf("no symbol for ATEXIT_MAX\n");
#endif
#ifdef _SC_ATEXIT_MAX
pr_sysconf("ATEXIT_MAX =", _SC_ATEXIT_MAX);
#else
printf("no symbol for _SC_ATEXIT_MAX\n");
#endif
#ifdef CHARCLASS_NAME_MAX
printf("CHARCLASS_NAME_MAX defined to be %d\n", CHARCLASS_NAME_MAX+0);
#else
printf("no symbol for CHARCLASS_NAME_MAX\n");
#endif
#ifdef _SC_CHARCLASS_NAME_MAX
pr_sysconf("CHARCLASS_NAME_MAX =", _SC_CHARCLASS_NAME_MAX);
#else
printf("no symbol for _SC_CHARCLASS_NAME_MAX\n");
#endif
#ifdef CHILD_MAX
printf("CHILD_MAX defined to be %d\n", CHILD_MAX+0);
#else
printf("no symbol for CHILD_MAX\n");
#endif
#ifdef _SC_CHILD_MAX
pr_sysconf("CHILD_MAX =", _SC_CHILD_MAX);
#else
printf("no symbol for _SC_CHILD_MAX\n");
#endif
#ifdef CLOCKTICKSPERSECOND /*clock ticks/second*/
printf("CLOCKTICKSPERSECOND /*clock ticks/second*/ defined to be %d\n", CLOCKTICKSPERSECOND /*clock ticks/second*/+0);
#else
printf("no symbol for CLOCKTICKSPERSECOND /*clock ticks/second*/\n");
#endif
#ifdef _SC_CLK_TCK
pr_sysconf("CLOCKTICKSPERSECOND /*clock ticks/second*/ =", _SC_CLK_TCK);
#else
printf("no symbol for _SC_CLK_TCK\n");
#endif
#ifdef COLL_WEIGHTS_MAX
printf("COLL_WEIGHTS_MAX defined to be %d\n", COLL_WEIGHTS_MAX+0);
#else
printf("no symbol for COLL_WEIGHTS_MAX\n");
#endif
#ifdef _SC_COLL_WEIGHTS_MAX
pr_sysconf("COLL_WEIGHTS_MAX =", _SC_COLL_WEIGHTS_MAX);
#else
printf("no symbol for _SC_COLL_WEIGHTS_MAX\n");
#endif
#ifdef HOST_NAME_MAX
printf("HOST_NAME_MAX defined to be %d\n", HOST_NAME_MAX+0);
#else
printf("no symbol for HOST_NAME_MAX\n");
#endif
#ifdef _SC_HOST_NAME_MAX
pr_sysconf("HOST_NAME_MAX =", _SC_HOST_NAME_MAX);
#else
printf("no symbol for _SC_HOST_NAME_MAX\n");
#endif
#ifdef IOV_MAX
printf("IOV_MAX defined to be %d\n", IOV_MAX+0);
#else
printf("no symbol for IOV_MAX\n");
#endif
#ifdef _SC_IOV_MAX
pr_sysconf("IOV_MAX =", _SC_IOV_MAX);
#else
printf("no symbol for _SC_IOV_MAX\n");
#endif
#ifdef LINE_MAX
printf("LINE_MAX defined to be %d\n", LINE_MAX+0);
#else
printf("no symbol for LINE_MAX\n");
#endif
#ifdef _SC_LINE_MAX
pr_sysconf("LINE_MAX =", _SC_LINE_MAX);
#else
printf("no symbol for _SC_LINE_MAX\n");
#endif
#ifdef LOGIN_NAME_MAX
printf("LOGIN_NAME_MAX defined to be %d\n", LOGIN_NAME_MAX+0);
#else
printf("no symbol for LOGIN_NAME_MAX\n");
#endif
#ifdef _SC_LOGIN_NAME_MAX
pr_sysconf("LOGIN_NAME_MAX =", _SC_LOGIN_NAME_MAX);
#else
printf("no symbol for _SC_LOGIN_NAME_MAX\n");
#endif
#ifdef NGROUPS_MAX
printf("NGROUPS_MAX defined to be %d\n", NGROUPS_MAX+0);
#else
printf("no symbol for NGROUPS_MAX\n");
#endif
#ifdef _SC_NGROUPS_MAX
pr_sysconf("NGROUPS_MAX =", _SC_NGROUPS_MAX);
#else
printf("no symbol for _SC_NGROUPS_MAX\n");
#endif
#ifdef OPEN_MAX
printf("OPEN_MAX defined to be %d\n", OPEN_MAX+0);
#else
printf("no symbol for OPEN_MAX\n");
#endif
#ifdef _SC_OPEN_MAX
pr_sysconf("OPEN_MAX =", _SC_OPEN_MAX);
#else
printf("no symbol for _SC_OPEN_MAX\n");
#endif
#ifdef PAGESIZE
printf("PAGESIZE defined to be %d\n", PAGESIZE+0);
#else
printf("no symbol for PAGESIZE\n");
#endif
#ifdef _SC_PAGESIZE
pr_sysconf("PAGESIZE =", _SC_PAGESIZE);
#else
printf("no symbol for _SC_PAGESIZE\n");
#endif
#ifdef PAGE_SIZE
printf("PAGE_SIZE defined to be %d\n", PAGE_SIZE+0);
#else
printf("no symbol for PAGE_SIZE\n");
#endif
#ifdef _SC_PAGE_SIZE
pr_sysconf("PAGE_SIZE =", _SC_PAGE_SIZE);
#else
printf("no symbol for _SC_PAGE_SIZE\n");
#endif
#ifdef RE_DUP_MAX
printf("RE_DUP_MAX defined to be %d\n", RE_DUP_MAX+0);
#else
printf("no symbol for RE_DUP_MAX\n");
#endif
#ifdef _SC_RE_DUP_MAX
pr_sysconf("RE_DUP_MAX =", _SC_RE_DUP_MAX);
#else
printf("no symbol for _SC_RE_DUP_MAX\n");
#endif
#ifdef STREAM_MAX
printf("STREAM_MAX defined to be %d\n", STREAM_MAX+0);
#else
printf("no symbol for STREAM_MAX\n");
#endif
#ifdef _SC_STREAM_MAX
pr_sysconf("STREAM_MAX =", _SC_STREAM_MAX);
#else
printf("no symbol for _SC_STREAM_MAX\n");
#endif
#ifdef SYMLOOP_MAX
printf("SYMLOOP_MAX defined to be %d\n", SYMLOOP_MAX+0);
#else
printf("no symbol for SYMLOOP_MAX\n");
#endif
#ifdef _SC_SYMLOOP_MAX
pr_sysconf("SYMLOOP_MAX =", _SC_SYMLOOP_MAX);
#else
printf("no symbol for _SC_SYMLOOP_MAX\n");
#endif
#ifdef TTY_NAME_MAX
printf("TTY_NAME_MAX defined to be %d\n", TTY_NAME_MAX+0);
#else
printf("no symbol for TTY_NAME_MAX\n");
#endif
#ifdef _SC_TTY_NAME_MAX
pr_sysconf("TTY_NAME_MAX =", _SC_TTY_NAME_MAX);
#else
printf("no symbol for _SC_TTY_NAME_MAX\n");
#endif
#ifdef TZNAME_MAX
printf("TZNAME_MAX defined to be %d\n", TZNAME_MAX+0);
#else
printf("no symbol for TZNAME_MAX\n");
#endif
#ifdef _SC_TZNAME_MAX
pr_sysconf("TZNAME_MAX =", _SC_TZNAME_MAX);
#else
printf("no symbol for _SC_TZNAME_MAX\n");
#endif
#ifdef MAX_CANON
printf("MAX_CANON defined to be %d\n", MAX_CANON+0);
#else
printf("no symbol for MAX_CANON\n");
#endif
#ifdef _PC_MAX_CANON
pr_pathconf("MAX_CANON =", argv[1], _PC_MAX_CANON);
#else
printf("no symbol for _PC_MAX_CANON\n");
#endif
#ifdef MAX_INPUT
printf("MAX_INPUT defined to be %d\n", MAX_INPUT+0);
#else
printf("no symbol for MAX_INPUT\n");
#endif
#ifdef _PC_MAX_INPUT
pr_pathconf("MAX_INPUT =", argv[1], _PC_MAX_INPUT);
#else
printf("no symbol for _PC_MAX_INPUT\n");
#endif
#ifdef FILESIZEBITS
printf("FILESIZEBITS defined to be %d\n", FILESIZEBITS+0);
#else
printf("no symbol for FILESIZEBITS\n");
#endif
#ifdef _PC_FILESIZEBITS
pr_pathconf("FILESIZEBITS =", argv[1], _PC_FILESIZEBITS);
#else
printf("no symbol for _PC_FILESIZEBITS\n");
#endif
#ifdef LINK_MAX
printf("LINK_MAX defined to be %d\n", LINK_MAX+0);
#else
printf("no symbol for LINK_MAX\n");
#endif
#ifdef _PC_LINK_MAX
pr_pathconf("LINK_MAX =", argv[1], _PC_LINK_MAX);
#else
printf("no symbol for _PC_LINK_MAX\n");
#endif
#ifdef NAME_MAX
printf("NAME_MAX defined to be %d\n", NAME_MAX+0);
#else
printf("no symbol for NAME_MAX\n");
#endif
#ifdef _PC_NAME_MAX
pr_pathconf("NAME_MAX =", argv[1], _PC_NAME_MAX);
#else
printf("no symbol for _PC_NAME_MAX\n");
#endif
#ifdef PATH_MAX
printf("PATH_MAX defined to be %d\n", PATH_MAX+0);
#else
printf("no symbol for PATH_MAX\n");
#endif
#ifdef _PC_PATH_MAX
pr_pathconf("PATH_MAX =", argv[1], _PC_PATH_MAX);
#else
printf("no symbol for _PC_PATH_MAX\n");
#endif
#ifdef PIPE_BUF
printf("PIPE_BUF defined to be %d\n", PIPE_BUF+0);
#else
printf("no symbol for PIPE_BUF\n");
#endif
#ifdef _PC_PIPE_BUF
pr_pathconf("PIPE_BUF =", argv[1], _PC_PIPE_BUF);
#else
printf("no symbol for _PC_PIPE_BUF\n");
#endif
#ifdef SYMLINK_MAX
printf("SYMLINK_MAX defined to be %d\n", SYMLINK_MAX+0);
#else
printf("no symbol for SYMLINK_MAX\n");
#endif
#ifdef _PC_SYMLINK_MAX
pr_pathconf("SYMLINK_MAX =", argv[1], _PC_SYMLINK_MAX);
#else
printf("no symbol for _PC_SYMLINK_MAX\n");
#endif
exit(0);
}
static void
pr_sysconf(char *mesg, int name)
{
long val;
fputs(mesg, stdout);
errno = 0;
if ((val = sysconf(name)) < 0) {
if (errno != 0) {
if (errno == EINVAL)
fputs(" (not supported)\n", stdout);
else
err_sys("sysconf error");
} else {
fputs(" (no limit)\n", stdout);
}
} else {
printf(" %ld\n", val);
}
}
static void
pr_pathconf(char *mesg, char *path, int name)
{
long val;
fputs(mesg, stdout);
errno = 0;
if ((val = pathconf(path, name)) < 0) {
if (errno != 0) {
if (errno == EINVAL)
fputs(" (not supported)\n", stdout);
else
err_sys("pathconf error, path = %s", path);
} else {
fputs(" (no limit)\n", stdout);
}
} else {
printf(" %ld\n", val);
}
}
[wonsik@as48-x64 std]$ ./a.out
usage: a.out <dirname>
[wonsik@as48-x64 std]$ ./a.out .
ARG_MAX defined to be 131072
ARG_MAX = 131072
no symbol for ATEXIT_MAX
ATEXIT_MAX = 2147483647
CHARCLASS_NAME_MAX defined to be 2048
CHARCLASS_NAME_MAX = 2048
CHILD_MAX defined to be 999
CHILD_MAX = 999
no symbol for CLOCKTICKSPERSECOND /*clock ticks/second*/
CLOCKTICKSPERSECOND /*clock ticks/second*/ = 100
COLL_WEIGHTS_MAX defined to be 255
COLL_WEIGHTS_MAX = 255
HOST_NAME_MAX defined to be 64
HOST_NAME_MAX = 64
IOV_MAX defined to be 1024
IOV_MAX = 1024
LINE_MAX defined to be 2048
LINE_MAX = 2048
LOGIN_NAME_MAX defined to be 256
LOGIN_NAME_MAX = 256
NGROUPS_MAX defined to be 65536
NGROUPS_MAX = 65536
no symbol for OPEN_MAX
OPEN_MAX = 1048576
no symbol for PAGESIZE
PAGESIZE = 4096
no symbol for PAGE_SIZE
PAGE_SIZE = 4096
RE_DUP_MAX defined to be 32767
RE_DUP_MAX = 32767
no symbol for STREAM_MAX
STREAM_MAX = 16
no symbol for SYMLOOP_MAX
SYMLOOP_MAX = (no limit)
TTY_NAME_MAX defined to be 32
TTY_NAME_MAX = 32
no symbol for TZNAME_MAX
TZNAME_MAX = 6
MAX_CANON defined to be 255
MAX_CANON = 255
MAX_INPUT defined to be 255
MAX_INPUT = 255
no symbol for FILESIZEBITS
FILESIZEBITS = 64
no symbol for LINK_MAX
LINK_MAX = 32000
NAME_MAX defined to be 255
NAME_MAX = 255
PATH_MAX defined to be 4096
PATH_MAX = 4096
PIPE_BUF defined to be 4096
PIPE_BUF = 4096
no symbol for SYMLINK_MAX
SYMLINK_MAX = (no limit)
* 각 시스템들에 대한 설정 한계들의 예
Limit
|
FreeBSD 5.2.1
|
Linux 2.4.22
|
Mac OS X 10.3
|
Solaris 9
| |
---|---|---|---|---|---|
UFS file system
|
PCFS file system
| ||||
ARG_MAX
|
65,536
|
131,072
|
262,144
|
1,048,320
|
1,048,320
|
ATEXIT_MAX
|
32
|
2,147,483,647
|
no symbol
|
no limit
|
no limit
|
CHARCLASS_NAME_MAX
|
no symbol
|
2,048
|
no symbol
|
14
|
14
|
CHILD_MAX
|
867
|
999
|
100
|
7,877
|
7,877
|
clock ticks/second
|
128
|
100
|
100
|
100
|
100
|
COLL_WEIGHTS_MAX
|
0
|
255
|
2
|
10
|
10
|
FILESIZEBITS
|
unsupported
|
64
|
no symbol
|
41
|
unsupported
|
HOST_NAME_MAX
|
255
|
unsupported
|
no symbol
|
no symbol
|
no symbol
|
IOV_MAX
|
1,024
|
no limit
|
no symbol
|
16
|
16
|
LINE_MAX
|
2,048
|
2,048
|
2,048
|
2,048
|
2,048
|
LINK_MAX
|
32,767
|
32,000
|
32,767
|
32,767
|
1
|
LOGIN_NAME_MAX
|
17
|
256
|
no symbol
|
9
|
9
|
MAX_CANON
|
255
|
255
|
255
|
256
|
256
|
MAX_INPUT
|
255
|
255
|
255
|
512
|
512
|
NAME_MAX
|
255
|
255
|
765
|
255
|
8
|
NGROUPS_MAX
|
16
|
32
|
16
|
16
|
16
|
OPEN_MAX
|
1,735
|
1,024
|
256
|
256
|
256
|
PAGESIZE
|
4,096
|
4,096
|
4,096
|
8,192
|
8,192
|
PAGE_SIZE
|
4,096
|
4,096
|
no symbol
|
8,192
|
8,192
|
PATH_MAX
|
1,024
|
4,096
|
1,024
|
1,024
|
1,024
|
PIPE_BUF
|
512
|
4,096
|
512
|
5,120
|
5,120
|
RE_DUP_MAX
|
255
|
32,767
|
255
|
255
|
255
|
STREAM_MAX
|
1,735
|
16
|
20
|
256
|
256
|
SYMLINK_MAX
|
unsupported
|
no limit
|
no symbol
|
no symbol
|
no symbol
|
SYMLOOP_MAX
|
32
|
no limit
|
no symbol
|
no symbol
|
no symbol
|
TTY_NAME_MAX
|
255
|
32
|
no symbol
|
128
|
128
|
TZNAME_MAX
|
255
|
6
|
255
|
no limit
|
no limit
|
UFS는 Berkeley FFS(fast file system)의 SVR4 구현
PCFS는 Solaris용 MS-DOS FAT 파일 시스템 구현
2.5.5 미결정 실행시점 한계
# 경로 이름
POSIX.1은 <limits.h> 헤더 파일을 통해 PATH_MAX 상수를 제공함.
만일 정의되어 있지 않다면 pathconf()를 호출
pathconf()의 반환값은 첫인수로 주어진 디렉토리를 기준으로 한 상대 경로 이름의 최대크기이므로,
임의의 절대 경로이름의 최대크기를 얻기 위해서는 첫 인수에 루트("/")를 지정해서 함수를 호출하고 그 반환값에 1을 더해야 함.
만일, pathconf가 PATH_MAX 상수가 미결정이라고 알려주면, 그냥 적당한 추정치를 쓰는 수 밖에 없음.
보다 정확한 방법은 할당된 공간을 어떻게 사용할 것인가에 따라 다를 수 있음
ex) 할당된 메모리 공간을 getcwd() 호출에 사용하는 경우
할당된 공간이 너무 작으면 getcwd()는 오류를 반환하며, errno가 ERANGE로 설정
realloc()을 호출하여 할당된 공간을 늘린 후 다시 시도하는 과정을 getcwd() 호출이 성공할 때까지 반복해야 함.
#define ERANGE 34 /* Math result not representable */
* getcwd()
- 현재 작업 중인 디렉토리의 절대 경로를 받환
- 버퍼 공간이 작으면 에러 발생
* 경로 이름을 위한 공간을 동적으로 할당하는 함수
#include "apue.h"
#include <errno.h>
#include <limits.h>
#ifdef PATH_MAX
static int pathmax = PATH_MAX;
#else
static int pathmax = 0;
#endif
#define SUSV3 200112L
static long posix_version = 0;
/* If PATH_MAX is indeterminate, no guarantee this is adequate */
#define PATH_MAX_GUESS 1024
char *
path_alloc(int *sizep) /* also return allocated size, if nonnull */
{
char *ptr;
int size;
if (posix_version == 0)
posix_version = sysconf(_SC_VERSION);
if (pathmax == 0) { /* first time through */
errno = 0;
if ((pathmax = pathconf("/", _PC_PATH_MAX)) < 0) {
if (errno == 0)
pathmax = PATH_MAX_GUESS; /* it's indeterminate */
else
err_sys("pathconf error for _PC_PATH_MAX");
} else {
pathmax++; /* add one since it's relative to root */
}
}
if (posix_version < SUSV3)
size = pathmax + 1;
else
size = pathmax;
if ((ptr = malloc(size)) == NULL)
err_sys("malloc error for pathname");
if (sizep != NULL)
*sizep = size;
return(ptr);
}
# 열린 파일 최대 개수
데몬 프로세스들에서는 열린 파일들을 모두 닫는 코드열이 아래와 같이 쓰이곤 함.
그러나, 만일 예를 들어 fd 9는 open되지 않은 상태이고, fd 10은 열린 상태라고 하면
fd 9에서 루프문이 끝나므로 fd 10은 닫히지 않음.
close가 반환하는 오류(EBADF)는 유효하지 않은 서술자와 열리지 않은 서술자를 구분할 수 없음.
#include <sys/param.h>
for (i = 0; i < NOFILE; i++)
close(i);
<sys/param.h>
/* The following is not really correct but it is a value we used for a
long time and which seems to be usable. People should not use NOFILE
anyway. */
#define NOFILE 256
좀더 이식성 있는 방식을 취할 경우 POSIX.1의 OPEN_MAX 상수를 사용할 수 있지만
해당 상수 값이 미결정일 수 있다. 미결정일 경우 아래의 코드는 무한 루프에 빠짐.
#include <unistd.h>
for(i = 0; i < sysconf(_SC_OPEN_MAX); i++)
close(i);
<bits/stdio_lim.h>
#if defined __need_FOPEN_MAX || defined _STDIO_H
# undef FOPEN_MAX
# define FOPEN_MAX 16
#endif
* 파일 서술자 개수를 알아내는 함수
#include "apue.h"
#include <errno.h>
#include <limits.h>
#ifdef OPEN_MAX
static long openmax = OPEN_MAX;
#else
static long openmax = 0;
#endif
/*
* If OPEN_MAX is indeterminate, we're not
* guaranteed that this is adequate.
*/
#define OPEN_MAX_GUESS 256
long
open_max(void)
{
if (openmax == 0) { /* first time through */
errno = 0;
if ((openmax = sysconf(_SC_OPEN_MAX)) < 0) {
if (errno == 0)
openmax = OPEN_MAX_GUESS; /* it's indeterminate */
else
err_sys("sysconf error for _SC_OPEN_MAX");
}
}
return(openmax);
}
ulimit을 이용해 nofiles 항목을 unlimited로 설정한 후
sysconf로 OPEN_MAX를 조회하면 LONG_MAX가 반환됨.
단일 UNIX 규격의 XSI 확장들을 지원하는 시스템은 getrlimit(), setrlimit()을 통해
최대 FD 개수를 조회하고 설정할 수 있다.
getrlimit()을 통해 파일 개수에 대한 상한이 설정되어 있지 않음을 검출할 수 있다.
2.6 옵션들
* 단일 UNIX 규격이 제공하는 특정 옵션을 지원하는지 여부를 판단하는 방법 3 가지
1) 컴파일 시점 옵션들은 <unistd.h>에 정의되어 있다.
[wonsik@as48-x64 include]$ grep "^#define" unistd.h
#define _POSIX_ASYNC_IO 1
#define _POSIX_JOB_CONTROL 1
#define _POSIX_SAVED_IDS 1
#define _POSIX_SYNC_IO 1
#define _POSIX_ASYNCHRONOUS_IO 200112L
#define _POSIX_FSYNC 200112L
#define _POSIX_MAPPED_FILES 200112L
#define _POSIX_MEMLOCK 200112L
#define _POSIX_MEMLOCK_RANGE 200112L
#define _POSIX_MEMORY_PROTECTION 200112L
#define _POSIX_MESSAGE_PASSING 200112L
#define _POSIX_PRIORITY_SCHEDULING 200112L
#define _POSIX_REALTIME_SIGNALS 200112L
#define _POSIX_SEMAPHORES 200112L
#define _POSIX_SHARED_MEMORY_OBJECTS 200112L
#define _POSIX_SYNCHRONIZED_IO 200112L
#define _POSIX_ASYNCHRONOUS_IO 1
#define _POSIX_FSYNC 1
#define _POSIX_MAPPED_FILES 1
#define _POSIX_MEMLOCK 1
#define _POSIX_MEMLOCK_RANGE 1
#define _POSIX_MEMORY_PROTECTION 1
#define _POSIX_MESSAGE_PASSING 1
#define _POSIX_PRIORITY_SCHEDULING 1
#define _POSIX_REALTIME_SIGNALS 1
#define _POSIX_SEMAPHORES 1
#define _POSIX_SHARED_MEMORY_OBJECTS 1
#define _POSIX_SYNCHRONIZED_IO 1
#define _POSIX_THREAD_SAFE_FUNCTIONS 200112L
#define _POSIX_THREADS 200112L
#define _POSIX_THREAD_ATTR_STACKADDR 200112L
#define _POSIX_THREAD_ATTR_STACKSIZE 200112L
#define _POSIX_THREAD_PROCESS_SHARED 200112L
#define _POSIX_THREAD_PRIORITY_SCHEDULING 200112L
#define _POSIX_TIMERS 200112L
#define _POSIX_THREAD_SAFE_FUNCTIONS 1
#define _POSIX_THREADS 1
#define _POSIX_THREAD_ATTR_STACKADDR 1
#define _POSIX_THREAD_ATTR_STACKSIZE 1
#define _POSIX_THREAD_PROCESS_SHARED 1
#define _POSIX_THREAD_PRIORITY_SCHEDULING 1
#define _POSIX_TIMERS 1
#define _POSIX_IPV6 200112L
#define _POSIX_RAW_SOCKETS 200112L
#define _POSIX_READER_WRITER_LOCKS 200112L
#define _POSIX_THREAD_PRIO_INHERIT 200112L
#define _POSIX_THREAD_PRIO_PROTECT 200112L
#define _POSIX_THREAD_PRIO_INHERIT 1
#define _POSIX_THREAD_PRIO_PROTECT 1
#define _POSIX_VDISABLE 0
2) 파일이나 디렉토리에 연관되지 않은 실행시점 옵션들은 sysconf 함수로 알아낼 수 있다.
3) 파일이나 디렉토리에 연관된 실행시점 옵션들은 pathconf() 나 fpathconf()로 알아낼 수 있다.
* 기호 상수가 정의되어 있지 않은 경우
sysconf(), pathconf(), fpathconf() 등을 이용해 해당 옵션의 지원 여부를 판정해야 함.
_XOPEN으로 시작하는 기호 상수들의 경우 이름앞에 _SC나 _PC로 대체한 이름을 name 인수에 지정해야함.
ex) _POSIX_THREADS 기호 상수 경우 헤더에 정의되어 있지 않다면 name 인수에 _SC_THREADS를 지정해서 sysconf() 호출
_XOPEN_UNIX 기호 상수가 정의되어 있지 않다면 name 인수에 _SC_XOPEN_UNIX를 지정해서 sysconf() 호출
* 기호 상수가 정의되어 있다면 아래 3가지 경우로 나뉨
1) 기호 상수의 값이 -1이면 구현은 해당 옵션을 미지원
2) 기호 상수의 값이 0보다 큰 값이면 해당 옵션을 지원
3) 기호 상수 의 값이 0이면 해당 옵션의 지원 여부를 반드시 sysconf(), pathconf(), fpathconf()의 호출을 통해 판단
* sysconf()로 알아낼 수 있는 옵션들과 해당 기호 상수들
(POSIX.1 선택적 인터페이스 그룹 및 해당 부호에 포함되어 있는 것들은 생략함)
Name of option
|
Description
|
name argument
|
---|---|---|
_POSIX_JOB_CONTROL
|
indicates whether the implementation supports job control
|
_SC_JOB_CONTROL
|
_POSIX_READER_WRITER_LOCKS
|
indicates whether the implementation supports readerwriter locks
|
_SC_READER_WRITER_LOCKS
|
_POSIX_SAVED_IDS
|
indicates whether the implementation supports the saved set-user-ID and the saved set-group-ID
|
_SC_SAVED_IDS
|
_POSIX_SHELL
|
indicates whether the implementation supports the POSIX shell
|
_SC_SHELL
|
_POSIX_VERSION
|
indicates the POSIX.1 version
|
_SC_VERSION
|
_XOPEN_CRYPT
|
indicates whether the implementation supports the XSI encryption option group
|
_SC_XOPEN_CRYPT
|
_XOPEN_LEGACY
|
indicates whether the implementation supports the XSI legacy option group
|
_SC_XOPEN_LEGACY
|
_XOPEN_REALTIME
|
indicates whether the implementation supports the XSI real-time option group
|
_SC_XOPEN_REALTIME
|
_XOPEN_REALTIME_THREADS
|
indicates whether the implementation supports the XSI real-time threads option group
|
_SC_XOPEN_REALTIME_THREADS
|
_XOPEN_VERSION
|
indicates the XSI version
|
_SC_XOPEN_VERSION
|
* pathconf(), fpathconf로 알아낼 수 있는 옵션들과 해당 기호 상수들
Name of option
|
Description
|
name argument
|
---|---|---|
_POSIX_CHOWN_RESTRICTED
|
indicates whether use of chown is restricted
|
_PC_CHOWN_RESTRICTED
|
_POSIX_NO_TRUNC
|
indicates whether pathnames longer than NAME_MAX generate an error
|
_PC_NO_TRUNC
|
_POSIX_VDISABLE
|
if defined, terminal special characters can be disabled with this value
|
_PC_VDISABLE
|
_POSIX_ASYNC_IO
|
indicates whether asynchronous I/O can be used with the associated file
|
_PC_ASYNC_IO
|
_POSIX_PRIO_IO
|
indicates whether prioritized I/O can be used with the associated file
|
_PC_PRIO_IO
|
_POSIX_SYNC_IO
|
indicates whether synchronized I/O can be used with the associated file
|
_PC_SYNC_IO
|
* 주의 사항
1) _SC_VERSION에 대해 반환된 값은 해당표준의 네 자리 연도와 두 자리 월로 구성된 수치 값
ex) 198808L, 199009L, 199506L 등 SUSv3(단일 UNIX 규격 버전 3)에 해당하는 값은 200112L
2) _SC_XOPEN_VERSION에 대해 반환된 값은 시스템이 준수하는 XSI의 버전을 나타냄.
단일 UNIX 규격 버전 3에 해당하는 값은 600임.
3) _SC_JOB_CONTROL, _SC_SAVED_IDS, _PC_VDISABLE은 더 이상 선택적인 기능들을 나타내는 값이 아님.
단일 UNIX 규격 버전 3에서부터 이 기능들은 필수임. 하위 호환성을 위해 남겨둠
4) _PC_CHOWN_RESTRICTED와 _PC_NO_TRUNC의 경우, 지정된 pathname이나 filedes에 대해 해당 옵션이 지원되지 않음
반환값은 -1 이지만 errno는 변경되지 않음.
5) _PC_CHOWN_RESTRICTED에 대해 지정된 파일은 반드시 파일이나 디렉토리이어야 함.
디렉토리인 경우 반환값은 그 디렉토리 안의 파일들에 대한 이 옵션의 지원 여부
6) _PC_NO_TRUNC에 대해 지정된 파일은 반드시 디렉토리이어야 함.
반환값은 그 디렉토리 안의 파일이름들에 대한 것임.
7) _PC_VDISABLE에 대해 지정된 파일은 반드시 터미널 파일이어야 함.
* 각 OS들에 대한 설정 옵션들의 예
Limit
|
FreeBSD 5.2.1
|
Linux 2.4.22
|
Mac OS X 10.3
|
Solaris 9
| |
---|---|---|---|---|---|
UFS file system
|
PCFS file system
| ||||
_POSIX_CHOWN_RESTRICTED
|
1
|
1
|
1
|
1
|
1
|
_POSIX_JOB_CONTROL
|
1
|
1
|
1
|
1
|
1
|
_POSIX_NO_TRUNC
|
1
|
1
|
1
|
1
|
unsupported
|
_POSIX_SAVED_IDS
|
unsupported
|
1
|
unsupported
|
1
|
1
|
_POSIX_THREADS
|
200112
|
200112
|
defined
|
1
|
1
|
_POSIX_VDISABLE
|
255
|
0
|
255
|
0
|
0
|
_POSIX_VERSION
|
200112
|
200112
|
198808
|
199506
|
199506
|
_XOPEN_UNIX
|
unsupported
|
1
|
undefined
|
1
|
1
|
_XOPEN_VERSION
|
unsupported
|
500
|
undefined
|
3
|
3
|
- undefined : 기호 상수나 그에 해당하는 _PC 또는 _SC 기호가 정의되지 않았음을 의미
- define : 기호 상수가 정의되어 있긴 하지만 특정한 값이 설정되지는 않았음을 의미
- unsupported : 시스템이 기호 상수의 값을 -1로 정의하거나, 기호 상수의 값이 0이지만, 해당 sysconf(), pathconf() 호출이 -1을 돌려줌을 의미
Mac OS X 10.3의 경우 POSIX thread를 지원하나 _POSIX_THREADS 기호를 정의만 할 뿐 특정한 값을 설정하지 않음.
#define _POSIX_THREADS
단일 UNIX 규격 버전 3을 준수할 경우 _POSIX_THREADS 기호에 대한 반드시 -1이나 0 또는 200112 라는 구체적인 값 설정해야 함.
2.7 기능 판정 매크로
_POSIX_C_SOURCE와 _XOPEN_SOURCE 와 같은 상수를 기능 판정 매크로로 칭함.
위 상수는 unistd.h 헤더파일에 정의되어 있음.
* _POSIX_C_SOURCE
- application이 POSIX 정의들에만 의존하며, applicatin 고유의 한계들은 전혀 사용하지 않도록 하려면 컴파일할 때
아래와 같이 위 상수를 정의한다.
cc -D_POSIX_C_SOURCE=200112 file.c <-- POSIX.1의 모든 헤더는 다른 정의들을 제외시킴
소스 파일의 첫줄에 아래와 같이 정의해도 됨
#define _POSIX_C_SOURCE 200112
* _XOPEN_SOURCE
- 단일 UNIX 규격 버전 3의 기능성만 사용할 경우
#define _XOPEN_SOURCE 600
단일 UNIX 규격의 정의하에서 C 컴파일 환경에 대한 인터페이스는 c99 유틸리티
c99 -D_XOPEN_SOURCE=600 file.c -o file
gcc C 컴파일러에서 1999 ISO C 확장들을 활성화할 때
gcc -D_XOPEN_SOURCE=600 -std=c99 file.c -o file
* __STDC__
- ISO C 표준을 준수하는 C 컴파일러는 소스 파일을 컴파일할 때 자동으로 이 매크로를 정의함.
- ISO C 컴파일러와 비 ISO C 컴파일러 모두에서 컴파일되는 C 프로그램을 작성함.
- Sun solaris 환경 unistd.h 헤더파일에서 정의
#ifdef __STDC__
void *myfunc(const char *, int);
#else
void *myfunc();
#endif
2.8 기본 시스템 자료 형식(primitive system data type)
UNIX 시스템의 device에 매기는 번호의 형식
<sys/types.h> 헤더 파일에 C의 typedef를 통해 정의되어 있고, 일부는 다른 헤더들에 정의되어 있음.
v20z:/usr/include/sys] grep typedef types.h
typedef long long longlong_t;
typedef unsigned long long u_longlong_t;
typedef int32_t t_scalar_t;
typedef uint32_t t_uscalar_t;
typedef long t_scalar_t; /* historical versions */
typedef unsigned long t_uscalar_t;
typedef unsigned char uchar_t;
typedef unsigned short ushort_t;
typedef unsigned int uint_t;
typedef unsigned long ulong_t;
typedef char *caddr_t; /* ?<core address> type */
typedef long daddr_t; /* <disk address> type */
typedef short cnt_t; /* ?<count> type */
typedef long ptrdiff_t; /* pointer difference */
typedef ulong_t pfn_t; /* page frame number */
typedef ulong_t pgcnt_t; /* number of pages */
typedef long spgcnt_t; /* signed number of pages */
typedef uchar_t use_t; /* use count for swap. */
typedef short sysid_t;
typedef short index_t;
typedef void *timeout_id_t; /* opaque handle from timeout(9F) */
typedef void *bufcall_id_t; /* opaque handle from bufcall(9F) */
typedef long off_t; /* offsets within files */
typedef longlong_t off_t; /* offsets within files */
typedef off_t off64_t; /* offsets within files */
typedef longlong_t off64_t; /* offsets within files */
typedef ulong_t ino_t; /* expanded inode type */
typedef long blkcnt_t; /* count of file blocks */
typedef ulong_t fsblkcnt_t; /* count of file system blocks */
typedef ulong_t fsfilcnt_t; /* count of files */
typedef u_longlong_t ino_t; /* expanded inode type */
typedef longlong_t blkcnt_t; /* count of file blocks */
typedef u_longlong_t fsblkcnt_t; /* count of file system blocks */
typedef u_longlong_t fsfilcnt_t; /* count of files */
typedef ino_t ino64_t; /* expanded inode type */
typedef blkcnt_t blkcnt64_t; /* count of file blocks */
typedef fsblkcnt_t fsblkcnt64_t; /* count of file system blocks */
typedef fsfilcnt_t fsfilcnt64_t; /* count of files */
typedef u_longlong_t ino64_t; /* expanded inode type */
typedef longlong_t blkcnt64_t; /* count of file blocks */
typedef u_longlong_t fsblkcnt64_t; /* count of file system blocks */
typedef u_longlong_t fsfilcnt64_t; /* count of files */
typedef int blksize_t; /* used for block sizes */
typedef long blksize_t; /* used for block sizes */
typedef enum { _B_FALSE, _B_TRUE } boolean_t;
typedef enum { B_FALSE, B_TRUE } boolean_t;
typedef int64_t pad64_t;
typedef uint64_t upad64_t;
typedef longlong_t offset_t;
typedef u_longlong_t u_offset_t;
typedef u_longlong_t len_t;
typedef u_longlong_t diskaddr_t;
typedef uint64_t paddr_t;
typedef uint_t k_fltset_t; /* kernel fault set type */
typedef int id_t;
typedef uint_t useconds_t; /* Time, in microseconds */
typedef long suseconds_t; /* signed # of microseconds */
typedef uint_t major_t; /* major part of device number */
typedef uint_t minor_t; /* minor part of device number */
typedef short pri_t;
typedef ushort_t cpu_flag_t;
typedef ushort_t o_mode_t; /* old file attribute type */
typedef short o_dev_t; /* old device type */
typedef ushort_t o_uid_t; /* old UID type */
typedef o_uid_t o_gid_t; /* old GID type */
typedef short o_nlink_t; /* old file link type */
typedef short o_pid_t; /* old process id type */
typedef ushort_t o_ino_t; /* old inode type */
typedef int key_t; /* IPC key type */
typedef uint_t mode_t; /* file attribute type */
typedef int uid_t; /* UID type */
typedef uid_t gid_t; /* GID type */
typedef id_t taskid_t;
typedef id_t projid_t;
typedef id_t poolid_t;
typedef id_t zoneid_t;
typedef id_t ctid_t;
typedef uint_t pthread_t; /* = thread_t in thread.h */
typedef uint_t pthread_key_t; /* = thread_key_t in thread.h */
typedef struct _pthread_mutex { /* = mutex_t in synch.h */
typedef struct _pthread_cond { /* = cond_t in synch.h */
typedef struct _pthread_rwlock { /* = rwlock_t in synch.h */
typedef pthread_mutex_t pthread_spinlock_t;
typedef ulong_t dev_t; /* expanded device type */
typedef uint_t nlink_t; /* file link type */
typedef int pid_t; /* process id type */
typedef ulong_t size_t; /* size of something in bytes */
typedef long ssize_t; /* size of something in bytes or -1 */
typedef long time_t; /* time of day in seconds */
typedef long clock_t; /* relative time in a specified resolution */
typedef int clockid_t; /* clock identifier type */
typedef int timer_t; /* timer identifier type */
typedef struct _quad { int val[2]; } quad_t; /* used by UFS */
typedef quad_t quad; /* used by UFS */
* 주요 primitive system data type 몇가지 예
Type
|
Description
|
---|---|
caddr_t
|
core address (Section 14.9)
|
clock_t
|
counter of clock ticks (process time) (Section 1.10)
|
comp_t
|
compressed clock ticks (Section 8.14)
|
dev_t
|
device numbers (major and minor) (Section 4.23)
|
fd_set
|
file descriptor sets (Section 14.5.1)
|
fpos_t
|
file position (Section 5.10)
|
gid_t
|
numeric group IDs
|
ino_t
|
i-node numbers (Section 4.14)
|
mode_t
|
file type, file creation mode (Section 4.5)
|
nlink_t
|
link counts for directory entries (Section 4.14)
|
off_t
|
file sizes and offsets (signed) (lseek, Section 3.6)
|
pid_t
|
process IDs and process group IDs (signed) (Sections 8.2and 9.4)
|
ptrdiff_t
|
result of subtracting two pointers (signed)
|
rlim_t
|
resource limits (Section 7.11)
|
sig_atomic_t
|
data type that can be accessed atomically (Section 10.15)
|
sigset_t
|
signal set (Section 10.11)
|
size_t
|
sizes of objects (such as strings) (unsigned) (Section 3.7)
|
ssize_t
|
functions that return a count of bytes (signed) (read, write,Section 3.7)
|
time_t
|
counter of seconds of calendar time (Section 1.10)
|
uid_t
|
numeric user IDs
|
wchar_t
|
can represent all distinct character codes
|
2.9 표준들의 충돌
SUSv3은 POSIX.1을 포함하므로, ISO C 표준과 POSIX.1의 차이점을 유념할 것.
* cloct_t 사례 (primitive system data type)
- ISC 표준
clock 함수 호출시 프로세스가 사용한 CPU 시간에 대한 반환 타입이 clock_t임.
이 값을 초로 변환할 때 <times.h>에 정의된 CLOCKS_PER_SEC 상수로 나눔
- POSIX.1
times함수 호출시 반환하는 CPU 시간(호출한 프로세스와 그 프로세스의 종료된 모든 자식 프로세스가 소비한)과
클록 시간에 대한 타입이 clock_t 임.
times 함수의 반환값을 초 단위로 변환하기 위해서는 sysconf()를 이용해서 초당 클릭 틱 수를 알아내야 함.
초당 클릭 틱 수를 ISO C와 POSIX.1은 서로 다르게 정의함.
위 두 표준은 서로 다른 값을 동일한 자료 형식(clock)에 담는다.
ex) Solaris에서 clock()의 반환값은 마이크로 초 단위의 값(따라서, CLOCKSP_PER_SEC는 1,000,000)
반면 sysconf() 호출시 초당 clock tick 수가 100이라가 알려줌
* 솔라리스
v20z:/usr/include/sys] grep clock_t types.h
typedef long clock_t; /* relative time in a specified resolution */
* AIX
aix53-t9:/usr/include/sys>grep clock_t types.h
typedef int clock_t;
* HP-UX
rx5670:[/usr/include/sys] $ grep clock_t types.h
typedef uint32_t clock_t; /* For clock ticks */
* Linux
[wonsik@as48-x64 sys]$ grep clock_t types.h
# define __need_clock_t
POSIX 환경 - 멀티 프로세스 환경 고려
ISO C 환경 - 호스트 운영체제에 대한 가정을 거의 두지 않음.