OSDN Git Service

Implement POSIX.1-2004 Monotonic Clock.
[pf3gnuchains/sourceware.git] / winsup / cygwin / sysconf.cc
1 /* sysconf.cc
2
3    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4    2006, 2007, 2009 Red Hat, Inc.
5
6 This file is part of Cygwin.
7
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
10 details. */
11
12 #include "winsup.h"
13 #include <unistd.h>
14 #include <sys/sysinfo.h>
15 #include "cygerrno.h"
16 #include "security.h"
17 #include "path.h"
18 #include "fhandler.h"
19 #include "dtable.h"
20 #include "ntdll.h"
21
22 static long
23 get_open_max (int in)
24 {
25   long max = getdtablesize ();
26   if (max < OPEN_MAX)
27     max = OPEN_MAX;
28   return max;
29 }
30
31 static long
32 get_page_size (int in)
33 {
34   return getpagesize ();
35 }
36
37 static long
38 get_nproc_values (int in)
39 {
40   NTSTATUS ret;
41   SYSTEM_BASIC_INFORMATION sbi;
42   if ((ret = NtQuerySystemInformation (SystemBasicInformation, (PVOID) &sbi,
43                                        sizeof sbi, NULL)) != STATUS_SUCCESS)
44     {
45       __seterrno_from_nt_status (ret);
46       debug_printf ("NtQuerySystemInformation: ret %d, Dos(ret) %E",
47                     ret);
48       return -1;
49     }
50   switch (in)
51     {
52     case _SC_NPROCESSORS_CONF:
53       return sbi.NumberProcessors;
54     case _SC_NPROCESSORS_ONLN:
55       {
56         int i = 0;
57         do
58          if (sbi.ActiveProcessors & 1)
59            i++;
60         while (sbi.ActiveProcessors >>= 1);
61         return i;
62       }
63     case _SC_PHYS_PAGES:
64       return sbi.NumberOfPhysicalPages
65              / (getpagesize () / getsystempagesize ());
66     }
67   return -1;
68 }
69
70 static long
71 get_avphys (int in)
72 {
73   NTSTATUS ret;
74   SYSTEM_PERFORMANCE_INFORMATION spi;
75   if ((ret = NtQuerySystemInformation (SystemPerformanceInformation,
76                                        (PVOID) &spi, sizeof spi, NULL))
77       != STATUS_SUCCESS)
78     {
79       __seterrno_from_nt_status (ret);
80       debug_printf ("NtQuerySystemInformation: ret %d, Dos(ret) %E",
81                     ret);
82       return -1;
83     }
84   return spi.AvailablePages / (getpagesize () / getsystempagesize ());
85 }
86
87 enum sc_type { nsup, cons, func };
88
89 static struct
90 {
91   sc_type type;
92   union
93     {
94       long c;
95       long (*f)(int);
96     };
97 } sca[] =
98 {
99   {cons, {c:ARG_MAX}},                  /*   0, _SC_ARG_MAX */
100   {cons, {c:CHILD_MAX}},                /*   1, _SC_CHILD_MAX */
101   {cons, {c:CLOCKS_PER_SEC}},           /*   2, _SC_CLK_TCK */
102   {cons, {c:NGROUPS_MAX}},              /*   3, _SC_NGROUPS_MAX */
103   {func, {f:get_open_max}},             /*   4, _SC_OPEN_MAX */
104   {cons, {c:_POSIX_JOB_CONTROL}},       /*   5, _SC_JOB_CONTROL */
105   {cons, {c:_POSIX_SAVED_IDS}},         /*   6, _SC_SAVED_IDS */
106   {cons, {c:_POSIX_VERSION}},           /*   7, _SC_VERSION */
107   {func, {f:get_page_size}},            /*   8, _SC_PAGESIZE */
108   {func, {f:get_nproc_values}},         /*   9, _SC_NPROCESSORS_CONF */
109   {func, {f:get_nproc_values}},         /*  10, _SC_NPROCESSORS_ONLN */
110   {func, {f:get_nproc_values}},         /*  11, _SC_PHYS_PAGES */
111   {func, {f:get_avphys}},               /*  12, _SC_AVPHYS_PAGES */
112   {cons, {c:MQ_OPEN_MAX}},              /*  13, _SC_MQ_OPEN_MAX */
113   {cons, {c:MQ_PRIO_MAX}},              /*  14, _SC_MQ_PRIO_MAX */
114   {cons, {c:RTSIG_MAX}},                /*  15, _SC_RTSIG_MAX */
115   {cons, {c:-1L}},                      /*  16, _SC_SEM_NSEMS_MAX */
116   {cons, {c:SEM_VALUE_MAX}},            /*  17, _SC_SEM_VALUE_MAX */
117   {cons, {c:SIGQUEUE_MAX}},             /*  18, _SC_SIGQUEUE_MAX */
118   {cons, {c:TIMER_MAX}},                /*  19, _SC_TIMER_MAX */
119   {nsup, {c:0}},                        /*  20, _SC_TZNAME_MAX */
120   {cons, {c:-1L}},                      /*  21, _SC_ASYNCHRONOUS_IO */
121   {cons, {c:_POSIX_FSYNC}},             /*  22, _SC_FSYNC */
122   {cons, {c:_POSIX_MAPPED_FILES}},      /*  23, _SC_MAPPED_FILES */
123   {cons, {c:-1L}},                      /*  24, _SC_MEMLOCK */
124   {cons, {c:_POSIX_MEMLOCK_RANGE}},     /*  25, _SC_MEMLOCK_RANGE */
125   {cons, {c:_POSIX_MEMORY_PROTECTION}}, /*  26, _SC_MEMORY_PROTECTION */
126   {cons, {c:_POSIX_MESSAGE_PASSING}},   /*  27, _SC_MESSAGE_PASSING */
127   {cons, {c:-1L}},                      /*  28, _SC_PRIORITIZED_IO */
128   {cons, {c:_POSIX_REALTIME_SIGNALS}},  /*  29, _SC_REALTIME_SIGNALS */
129   {cons, {c:_POSIX_SEMAPHORES}},        /*  30, _SC_SEMAPHORES */
130   {cons, {c:_POSIX_SHARED_MEMORY_OBJECTS}},     /*  31, _SC_SHARED_MEMORY_OBJECTS */
131   {cons, {c:_POSIX_SYNCHRONIZED_IO}},   /*  32, _SC_SYNCHRONIZED_IO */
132   {cons, {c:_POSIX_TIMERS}},            /*  33, _SC_TIMERS */
133   {nsup, {c:0}},                        /*  34, _SC_AIO_LISTIO_MAX */
134   {nsup, {c:0}},                        /*  35, _SC_AIO_MAX */
135   {nsup, {c:0}},                        /*  36, _SC_AIO_PRIO_DELTA_MAX */
136   {nsup, {c:0}},                        /*  37, _SC_DELAYTIMER_MAX */
137   {cons, {c:PTHREAD_KEYS_MAX}},         /*  38, _SC_THREAD_KEYS_MAX */
138   {cons, {c:PTHREAD_STACK_MIN}},        /*  39, _SC_THREAD_STACK_MIN */
139   {cons, {c:-1L}},                      /*  40, _SC_THREAD_THREADS_MAX */
140   {cons, {c:TTY_NAME_MAX}},             /*  41, _SC_TTY_NAME_MAX */
141   {cons, {c:_POSIX_THREADS}},           /*  42, _SC_THREADS */
142   {cons, {c:-1L}},                      /*  43, _SC_THREAD_ATTR_STACKADDR */
143   {cons, {c:_POSIX_THREAD_ATTR_STACKSIZE}},     /*  44, _SC_THREAD_ATTR_STACKSIZE */
144   {cons, {c:_POSIX_THREAD_PRIORITY_SCHEDULING}},        /*  45, _SC_THREAD_PRIORITY_SCHEDULING */
145   {cons, {c:-1L}},                      /*  46, _SC_THREAD_PRIO_INHERIT */
146   {cons, {c:-1L}},                      /*  47, _SC_THREAD_PRIO_PROTECT */
147   {cons, {c:_POSIX_THREAD_PROCESS_SHARED}},     /*  48, _SC_THREAD_PROCESS_SHARED */
148   {cons, {c:_POSIX_THREAD_SAFE_FUNCTIONS}},     /*  49, _SC_THREAD_SAFE_FUNCTIONS */
149   {cons, {c:16384L}},                   /*  50, _SC_GETGR_R_SIZE_MAX */
150   {cons, {c:16384L}},                   /*  51, _SC_GETPW_R_SIZE_MAX */
151   {cons, {c:LOGIN_NAME_MAX}},           /*  52, _SC_LOGIN_NAME_MAX */
152   {cons, {c:PTHREAD_DESTRUCTOR_ITERATIONS}},    /*  53, _SC_THREAD_DESTRUCTOR_ITERATIONS */
153   {cons, {c:_POSIX_ADVISORY_INFO}},     /*  54, _SC_ADVISORY_INFO */
154   {cons, {c:ATEXIT_MAX}},               /*  55, _SC_ATEXIT_MAX */
155   {cons, {c:-1L}},                      /*  56, _SC_BARRIERS */
156   {cons, {c:BC_BASE_MAX}},              /*  57, _SC_BC_BASE_MAX */
157   {cons, {c:BC_DIM_MAX}},               /*  58, _SC_BC_DIM_MAX */
158   {cons, {c:BC_SCALE_MAX}},             /*  59, _SC_BC_SCALE_MAX */
159   {cons, {c:BC_STRING_MAX}},            /*  60, _SC_BC_STRING_MAX */
160   {cons, {c:-1L}},                      /*  61, _SC_CLOCK_SELECTION */
161   {nsup, {c:0}},                        /*  62, _SC_COLL_WEIGHTS_MAX */
162   {cons, {c:-1L}},                      /*  63, _SC_CPUTIME */
163   {cons, {c:EXPR_NEST_MAX}},            /*  64, _SC_EXPR_NEST_MAX */
164   {cons, {c:HOST_NAME_MAX}},            /*  65, _SC_HOST_NAME_MAX */
165   {cons, {c:IOV_MAX}},                  /*  66, _SC_IOV_MAX */
166   {cons, {c:_POSIX_IPV6}},              /*  67, _SC_IPV6 */
167   {cons, {c:LINE_MAX}},                 /*  68, _SC_LINE_MAX */
168   {cons, {c:_POSIX_MONOTONIC_CLOCK}},   /*  69, _SC_MONOTONIC_CLOCK */
169   {cons, {c:_POSIX_RAW_SOCKETS}},       /*  70, _SC_RAW_SOCKETS */
170   {cons, {c:_POSIX_READER_WRITER_LOCKS}},       /*  71, _SC_READER_WRITER_LOCKS */
171   {cons, {c:_POSIX_REGEXP}},            /*  72, _SC_REGEXP */
172   {cons, {c:RE_DUP_MAX}},               /*  73, _SC_RE_DUP_MAX */
173   {cons, {c:_POSIX_SHELL}},             /*  74, _SC_SHELL */
174   {cons, {c:-1L}},                      /*  75, _SC_SPAWN */
175   {cons, {c:-1L}},                      /*  76, _SC_SPIN_LOCKS */
176   {cons, {c:-1L}},                      /*  77, _SC_SPORADIC_SERVER */
177   {nsup, {c:0}},                        /*  78, _SC_SS_REPL_MAX */
178   {cons, {c:SYMLOOP_MAX}},              /*  79, _SC_SYMLOOP_MAX */
179   {cons, {c:-1L}},                      /*  80, _SC_THREAD_CPUTIME */
180   {cons, {c:-1L}},                      /*  81, _SC_THREAD_SPORADIC_SERVER */
181   {cons, {c:-1L}},                      /*  82, _SC_TIMEOUTS */
182   {cons, {c:-1L}},                      /*  83, _SC_TRACE */
183   {cons, {c:-1L}},                      /*  84, _SC_TRACE_EVENT_FILTER */
184   {nsup, {c:0}},                        /*  85, _SC_TRACE_EVENT_NAME_MAX */
185   {cons, {c:-1L}},                      /*  86, _SC_TRACE_INHERIT */
186   {cons, {c:-1L}},                      /*  87, _SC_TRACE_LOG */
187   {nsup, {c:0}},                        /*  88, _SC_TRACE_NAME_MAX */
188   {nsup, {c:0}},                        /*  89, _SC_TRACE_SYS_MAX */
189   {nsup, {c:0}},                        /*  90, _SC_TRACE_USER_EVENT_MAX */
190   {cons, {c:-1L}},                      /*  91, _SC_TYPED_MEMORY_OBJECTS */
191   {cons, {c:-1L}},                      /*  92, _SC_V6_ILP32_OFF32 */
192   {cons, {c:_POSIX_V6_ILP32_OFFBIG}},   /*  93, _SC_V6_ILP32_OFFBIG */
193   {cons, {c:-1L}},                      /*  94, _SC_V6_LP64_OFF64 */
194   {cons, {c:-1L}},                      /*  95, _SC_V6_LPBIG_OFFBIG */
195   {cons, {c:_XOPEN_CRYPT}},             /*  96, _SC_XOPEN_CRYPT */
196   {cons, {c:_XOPEN_ENH_I18N}},          /*  97, _SC_XOPEN_ENH_I18N */
197   {cons, {c:-1L}},                      /*  98, _SC_XOPEN_LEGACY */
198   {cons, {c:-1L}},                      /*  99, _SC_XOPEN_REALTIME */
199   {cons, {c:STREAM_MAX}},               /* 100, _SC_STREAM_MAX */
200   {cons, {c:_POSIX_PRIORITY_SCHEDULING}},       /* 101, _SC_PRIORITY_SCHEDULING */
201   {cons, {c:-1L}},                      /* 102, _SC_XOPEN_REALTIME_THREADS */
202   {cons, {c:_XOPEN_SHM}},               /* 103, _SC_XOPEN_SHM */
203   {cons, {c:-1L}},                      /* 104, _SC_XOPEN_STREAMS */
204   {cons, {c:-1L}},                      /* 105, _SC_XOPEN_UNIX */
205   {cons, {c:_XOPEN_VERSION}},           /* 106, _SC_XOPEN_VERSION */
206   {cons, {c:_POSIX2_CHAR_TERM}},        /* 107, _SC_2_CHAR_TERM */
207   {cons, {c:_POSIX2_C_BIND}},           /* 108, _SC_2_C_BIND */
208   {cons, {c:_POSIX2_C_BIND}},           /* 109, _SC_2_C_DEV */
209   {cons, {c:-1L}},                      /* 110, _SC_2_FORT_DEV */
210   {cons, {c:-1L}},                      /* 111, _SC_2_FORT_RUN */
211   {cons, {c:-1L}},                      /* 112, _SC_2_LOCALEDEF */
212   {cons, {c:-1L}},                      /* 113, _SC_2_PBS */
213   {cons, {c:-1L}},                      /* 114, _SC_2_PBS_ACCOUNTING */
214   {cons, {c:-1L}},                      /* 115, _SC_2_PBS_CHECKPOINT */
215   {cons, {c:-1L}},                      /* 116, _SC_2_PBS_LOCATE */
216   {cons, {c:-1L}},                      /* 117, _SC_2_PBS_MESSAGE */
217   {cons, {c:-1L}},                      /* 118, _SC_2_PBS_TRACK */
218   {cons, {c:_POSIX2_SW_DEV}},           /* 119, _SC_2_SW_DEV */
219   {cons, {c:_POSIX2_UPE}},              /* 120, _SC_2_UPE */
220   {cons, {c:_POSIX2_VERSION}},          /* 121, _SC_2_VERSION */
221 };
222
223 #define SC_MIN _SC_ARG_MAX
224 #define SC_MAX _SC_2_VERSION
225
226 /* sysconf: POSIX 4.8.1.1 */
227 /* Allows a portable app to determine quantities of resources or
228    presence of an option at execution time. */
229 long int
230 sysconf (int in)
231 {
232   if (in >= SC_MIN && in <= SC_MAX)
233     {
234       switch (sca[in].type)
235         {
236         case nsup:
237           break;
238         case cons:
239           return sca[in].c;
240         case func:
241           return sca[in].f (in);
242         }
243     }
244   /* Unimplemented sysconf name or invalid option value. */
245   set_errno (EINVAL);
246   return -1L;
247 }
248
249 #define ls(s)   sizeof(s),s
250
251 static struct
252 {
253   size_t l;
254   const char *s;
255 } csa[] =
256 {
257   {ls ("/bin:/usr/bin")},               /* _CS_PATH */
258   {0, NULL},                            /* _CS_POSIX_V6_ILP32_OFF32_CFLAGS */
259   {0, NULL},                            /* _CS_POSIX_V6_ILP32_OFF32_LDFLAGS */
260   {0, NULL},                            /* _CS_POSIX_V6_ILP32_OFF32_LIBS */
261   {0, NULL},                            /* _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS */
262   {ls ("")},                            /* _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS */
263   {ls ("")},                            /* _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS */
264   {ls ("")},                            /* _CS_POSIX_V6_ILP32_OFFBIG_LIBS */
265   {ls ("")},                            /* _CS_XBS5_ILP32_OFFBIG_LINTFLAGS */
266   {0, NULL},                            /* _CS_POSIX_V6_LP64_OFF64_CFLAGS */
267   {0, NULL},                            /* _CS_POSIX_V6_LP64_OFF64_LDFLAGS */
268   {0, NULL},                            /* _CS_POSIX_V6_LP64_OFF64_LIBS */
269   {0, NULL},                            /* _CS_XBS5_LP64_OFF64_LINTFLAGS */
270   {0, NULL},                            /* _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS */
271   {0, NULL},                            /* _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS */
272   {0, NULL},                            /* _CS_POSIX_V6_LPBIG_OFFBIG_LIBS */
273   {0, NULL},                            /* _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS */
274   {ls ("POSIX_V6_ILP32_OFFBIG")},       /* _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS */
275 };
276
277 #define CS_MIN _CS_PATH
278 #define CS_MAX _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS
279
280 extern "C" size_t
281 confstr (int in, char *buf, size_t len)
282 {
283   if (in >= CS_MIN && in <= CS_MAX)
284     {
285       if (csa[in].l && len)
286         {
287           buf[0] = 0;
288           strncat (buf, csa[in].s, min (len, csa[in].l) - 1);
289         }
290       return csa[in].l;
291     }
292   /* Invalid option value. */
293   set_errno (EINVAL);
294   return 0;
295 }
296
297 extern "C" int
298 get_nprocs_conf (void)
299 {
300   return get_nproc_values (_SC_NPROCESSORS_CONF);
301 }
302
303 extern "C" int
304 get_nprocs (void)
305 {
306   return get_nproc_values (_SC_NPROCESSORS_ONLN);
307 }
308
309 extern "C" long
310 get_phys_pages (void)
311 {
312   return get_nproc_values (_SC_PHYS_PAGES);
313 }
314
315 extern "C" long
316 get_avphys_pages (void)
317 {
318   return get_avphys (_SC_AVPHYS_PAGES);
319 }