2014년 7월 14일 월요일

UNIX Standardization and Implementations

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>
<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) (lseekSection 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) (readwrite,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 환경 - 호스트 운영체제에 대한 가정을 거의 두지 않음.