OSDN Git Service

Initial checkin of text Corinna sent to cygwin-announce.
[pf3gnuchains/pf3gnuchains4x.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, 2010, 2011 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 "pinfo.h"
21 #include "ntdll.h"
22
23 static long
24 get_open_max (int in)
25 {
26   long max = getdtablesize ();
27   if (max < OPEN_MAX)
28     max = OPEN_MAX;
29   return max;
30 }
31
32 static long
33 get_page_size (int in)
34 {
35   return wincap.allocation_granularity ();
36 }
37
38 static long
39 get_nproc_values (int in)
40 {
41   NTSTATUS status;
42   SYSTEM_BASIC_INFORMATION sbi;
43
44   status = NtQuerySystemInformation (SystemBasicInformation, (PVOID) &sbi,
45                                      sizeof sbi, NULL);
46   if (!NT_SUCCESS (status))
47     {
48       __seterrno_from_nt_status (status);
49       debug_printf ("NtQuerySystemInformation: status %p, %E", status);
50       return -1;
51     }
52   switch (in)
53     {
54     case _SC_NPROCESSORS_CONF:
55       return sbi.NumberProcessors;
56     case _SC_NPROCESSORS_ONLN:
57       {
58         int i = 0;
59         do
60          if (sbi.ActiveProcessors & 1)
61            i++;
62         while (sbi.ActiveProcessors >>= 1);
63         return i;
64       }
65     case _SC_PHYS_PAGES:
66       return sbi.NumberOfPhysicalPages
67              / (wincap.allocation_granularity () / wincap.page_size ());
68     }
69   return -1;
70 }
71
72 static long
73 get_avphys (int in)
74 {
75   NTSTATUS status;
76   SYSTEM_PERFORMANCE_INFORMATION spi;
77
78   status = NtQuerySystemInformation (SystemPerformanceInformation,
79                                      (PVOID) &spi, sizeof spi, NULL);
80   if (!NT_SUCCESS (status))
81     {
82       __seterrno_from_nt_status (status);
83       debug_printf ("NtQuerySystemInformation: status %d, %E", status);
84       return -1;
85     }
86   return spi.AvailablePages
87          / (wincap.allocation_granularity () / wincap.page_size ());
88 }
89
90 enum sc_type { nsup, cons, func };
91
92 static struct
93 {
94   sc_type type;
95   union
96     {
97       long c;
98       long (*f)(int);
99     };
100 } sca[] =
101 {
102   {cons, {c:ARG_MAX}},                  /*   0, _SC_ARG_MAX */
103   {cons, {c:CHILD_MAX}},                /*   1, _SC_CHILD_MAX */
104   {cons, {c:CLOCKS_PER_SEC}},           /*   2, _SC_CLK_TCK */
105   {cons, {c:NGROUPS_MAX}},              /*   3, _SC_NGROUPS_MAX */
106   {func, {f:get_open_max}},             /*   4, _SC_OPEN_MAX */
107   {cons, {c:_POSIX_JOB_CONTROL}},       /*   5, _SC_JOB_CONTROL */
108   {cons, {c:_POSIX_SAVED_IDS}},         /*   6, _SC_SAVED_IDS */
109   {cons, {c:_POSIX_VERSION}},           /*   7, _SC_VERSION */
110   {func, {f:get_page_size}},            /*   8, _SC_PAGESIZE */
111   {func, {f:get_nproc_values}},         /*   9, _SC_NPROCESSORS_CONF */
112   {func, {f:get_nproc_values}},         /*  10, _SC_NPROCESSORS_ONLN */
113   {func, {f:get_nproc_values}},         /*  11, _SC_PHYS_PAGES */
114   {func, {f:get_avphys}},               /*  12, _SC_AVPHYS_PAGES */
115   {cons, {c:MQ_OPEN_MAX}},              /*  13, _SC_MQ_OPEN_MAX */
116   {cons, {c:MQ_PRIO_MAX}},              /*  14, _SC_MQ_PRIO_MAX */
117   {cons, {c:RTSIG_MAX}},                /*  15, _SC_RTSIG_MAX */
118   {cons, {c:-1L}},                      /*  16, _SC_SEM_NSEMS_MAX */
119   {cons, {c:SEM_VALUE_MAX}},            /*  17, _SC_SEM_VALUE_MAX */
120   {cons, {c:SIGQUEUE_MAX}},             /*  18, _SC_SIGQUEUE_MAX */
121   {cons, {c:TIMER_MAX}},                /*  19, _SC_TIMER_MAX */
122   {nsup, {c:0}},                        /*  20, _SC_TZNAME_MAX */
123   {cons, {c:-1L}},                      /*  21, _SC_ASYNCHRONOUS_IO */
124   {cons, {c:_POSIX_FSYNC}},             /*  22, _SC_FSYNC */
125   {cons, {c:_POSIX_MAPPED_FILES}},      /*  23, _SC_MAPPED_FILES */
126   {cons, {c:-1L}},                      /*  24, _SC_MEMLOCK */
127   {cons, {c:_POSIX_MEMLOCK_RANGE}},     /*  25, _SC_MEMLOCK_RANGE */
128   {cons, {c:_POSIX_MEMORY_PROTECTION}}, /*  26, _SC_MEMORY_PROTECTION */
129   {cons, {c:_POSIX_MESSAGE_PASSING}},   /*  27, _SC_MESSAGE_PASSING */
130   {cons, {c:-1L}},                      /*  28, _SC_PRIORITIZED_IO */
131   {cons, {c:_POSIX_REALTIME_SIGNALS}},  /*  29, _SC_REALTIME_SIGNALS */
132   {cons, {c:_POSIX_SEMAPHORES}},        /*  30, _SC_SEMAPHORES */
133   {cons, {c:_POSIX_SHARED_MEMORY_OBJECTS}},     /*  31, _SC_SHARED_MEMORY_OBJECTS */
134   {cons, {c:_POSIX_SYNCHRONIZED_IO}},   /*  32, _SC_SYNCHRONIZED_IO */
135   {cons, {c:_POSIX_TIMERS}},            /*  33, _SC_TIMERS */
136   {nsup, {c:0}},                        /*  34, _SC_AIO_LISTIO_MAX */
137   {nsup, {c:0}},                        /*  35, _SC_AIO_MAX */
138   {nsup, {c:0}},                        /*  36, _SC_AIO_PRIO_DELTA_MAX */
139   {nsup, {c:0}},                        /*  37, _SC_DELAYTIMER_MAX */
140   {cons, {c:PTHREAD_KEYS_MAX}},         /*  38, _SC_THREAD_KEYS_MAX */
141   {cons, {c:PTHREAD_STACK_MIN}},        /*  39, _SC_THREAD_STACK_MIN */
142   {cons, {c:-1L}},                      /*  40, _SC_THREAD_THREADS_MAX */
143   {cons, {c:TTY_NAME_MAX}},             /*  41, _SC_TTY_NAME_MAX */
144   {cons, {c:_POSIX_THREADS}},           /*  42, _SC_THREADS */
145   {cons, {c:_POSIX_THREAD_ATTR_STACKADDR}},/*  43, _SC_THREAD_ATTR_STACKADDR */
146   {cons, {c:_POSIX_THREAD_ATTR_STACKSIZE}},/*  44, _SC_THREAD_ATTR_STACKSIZE */
147   {cons, {c:_POSIX_THREAD_PRIORITY_SCHEDULING}},        /*  45, _SC_THREAD_PRIORITY_SCHEDULING */
148   {cons, {c:-1L}},                      /*  46, _SC_THREAD_PRIO_INHERIT */
149   {cons, {c:-1L}},                      /*  47, _SC_THREAD_PRIO_PROTECT */
150   {cons, {c:_POSIX_THREAD_PROCESS_SHARED}},     /*  48, _SC_THREAD_PROCESS_SHARED */
151   {cons, {c:_POSIX_THREAD_SAFE_FUNCTIONS}},     /*  49, _SC_THREAD_SAFE_FUNCTIONS */
152   {cons, {c:16384L}},                   /*  50, _SC_GETGR_R_SIZE_MAX */
153   {cons, {c:16384L}},                   /*  51, _SC_GETPW_R_SIZE_MAX */
154   {cons, {c:LOGIN_NAME_MAX}},           /*  52, _SC_LOGIN_NAME_MAX */
155   {cons, {c:PTHREAD_DESTRUCTOR_ITERATIONS}},    /*  53, _SC_THREAD_DESTRUCTOR_ITERATIONS */
156   {cons, {c:_POSIX_ADVISORY_INFO}},     /*  54, _SC_ADVISORY_INFO */
157   {cons, {c:ATEXIT_MAX}},               /*  55, _SC_ATEXIT_MAX */
158   {cons, {c:-1L}},                      /*  56, _SC_BARRIERS */
159   {cons, {c:BC_BASE_MAX}},              /*  57, _SC_BC_BASE_MAX */
160   {cons, {c:BC_DIM_MAX}},               /*  58, _SC_BC_DIM_MAX */
161   {cons, {c:BC_SCALE_MAX}},             /*  59, _SC_BC_SCALE_MAX */
162   {cons, {c:BC_STRING_MAX}},            /*  60, _SC_BC_STRING_MAX */
163   {cons, {c:_POSIX_CLOCK_SELECTION}},   /*  61, _SC_CLOCK_SELECTION */
164   {nsup, {c:0}},                        /*  62, _SC_COLL_WEIGHTS_MAX */
165   {cons, {c:_POSIX_CPUTIME}},           /*  63, _SC_CPUTIME */
166   {cons, {c:EXPR_NEST_MAX}},            /*  64, _SC_EXPR_NEST_MAX */
167   {cons, {c:HOST_NAME_MAX}},            /*  65, _SC_HOST_NAME_MAX */
168   {cons, {c:IOV_MAX}},                  /*  66, _SC_IOV_MAX */
169   {cons, {c:_POSIX_IPV6}},              /*  67, _SC_IPV6 */
170   {cons, {c:LINE_MAX}},                 /*  68, _SC_LINE_MAX */
171   {cons, {c:_POSIX_MONOTONIC_CLOCK}},   /*  69, _SC_MONOTONIC_CLOCK */
172   {cons, {c:_POSIX_RAW_SOCKETS}},       /*  70, _SC_RAW_SOCKETS */
173   {cons, {c:_POSIX_READER_WRITER_LOCKS}},       /*  71, _SC_READER_WRITER_LOCKS */
174   {cons, {c:_POSIX_REGEXP}},            /*  72, _SC_REGEXP */
175   {cons, {c:RE_DUP_MAX}},               /*  73, _SC_RE_DUP_MAX */
176   {cons, {c:_POSIX_SHELL}},             /*  74, _SC_SHELL */
177   {cons, {c:-1L}},                      /*  75, _SC_SPAWN */
178   {cons, {c:_POSIX_SPIN_LOCKS}},        /*  76, _SC_SPIN_LOCKS */
179   {cons, {c:-1L}},                      /*  77, _SC_SPORADIC_SERVER */
180   {nsup, {c:0}},                        /*  78, _SC_SS_REPL_MAX */
181   {cons, {c:SYMLOOP_MAX}},              /*  79, _SC_SYMLOOP_MAX */
182   {cons, {c:_POSIX_THREAD_CPUTIME}},    /*  80, _SC_THREAD_CPUTIME */
183   {cons, {c:-1L}},                      /*  81, _SC_THREAD_SPORADIC_SERVER */
184   {cons, {c:-1L}},                      /*  82, _SC_TIMEOUTS */
185   {cons, {c:-1L}},                      /*  83, _SC_TRACE */
186   {cons, {c:-1L}},                      /*  84, _SC_TRACE_EVENT_FILTER */
187   {nsup, {c:0}},                        /*  85, _SC_TRACE_EVENT_NAME_MAX */
188   {cons, {c:-1L}},                      /*  86, _SC_TRACE_INHERIT */
189   {cons, {c:-1L}},                      /*  87, _SC_TRACE_LOG */
190   {nsup, {c:0}},                        /*  88, _SC_TRACE_NAME_MAX */
191   {nsup, {c:0}},                        /*  89, _SC_TRACE_SYS_MAX */
192   {nsup, {c:0}},                        /*  90, _SC_TRACE_USER_EVENT_MAX */
193   {cons, {c:-1L}},                      /*  91, _SC_TYPED_MEMORY_OBJECTS */
194   {cons, {c:-1L}},                      /*  92, _SC_V6_ILP32_OFF32 */
195   {cons, {c:_POSIX_V6_ILP32_OFFBIG}},   /*  93, _SC_V6_ILP32_OFFBIG */
196   {cons, {c:-1L}},                      /*  94, _SC_V6_LP64_OFF64 */
197   {cons, {c:-1L}},                      /*  95, _SC_V6_LPBIG_OFFBIG */
198   {cons, {c:_XOPEN_CRYPT}},             /*  96, _SC_XOPEN_CRYPT */
199   {cons, {c:_XOPEN_ENH_I18N}},          /*  97, _SC_XOPEN_ENH_I18N */
200   {cons, {c:-1L}},                      /*  98, _SC_XOPEN_LEGACY */
201   {cons, {c:-1L}},                      /*  99, _SC_XOPEN_REALTIME */
202   {cons, {c:STREAM_MAX}},               /* 100, _SC_STREAM_MAX */
203   {cons, {c:_POSIX_PRIORITY_SCHEDULING}},       /* 101, _SC_PRIORITY_SCHEDULING */
204   {cons, {c:-1L}},                      /* 102, _SC_XOPEN_REALTIME_THREADS */
205   {cons, {c:_XOPEN_SHM}},               /* 103, _SC_XOPEN_SHM */
206   {cons, {c:-1L}},                      /* 104, _SC_XOPEN_STREAMS */
207   {cons, {c:-1L}},                      /* 105, _SC_XOPEN_UNIX */
208   {cons, {c:_XOPEN_VERSION}},           /* 106, _SC_XOPEN_VERSION */
209   {cons, {c:_POSIX2_CHAR_TERM}},        /* 107, _SC_2_CHAR_TERM */
210   {cons, {c:_POSIX2_C_BIND}},           /* 108, _SC_2_C_BIND */
211   {cons, {c:_POSIX2_C_BIND}},           /* 109, _SC_2_C_DEV */
212   {cons, {c:-1L}},                      /* 110, _SC_2_FORT_DEV */
213   {cons, {c:-1L}},                      /* 111, _SC_2_FORT_RUN */
214   {cons, {c:-1L}},                      /* 112, _SC_2_LOCALEDEF */
215   {cons, {c:-1L}},                      /* 113, _SC_2_PBS */
216   {cons, {c:-1L}},                      /* 114, _SC_2_PBS_ACCOUNTING */
217   {cons, {c:-1L}},                      /* 115, _SC_2_PBS_CHECKPOINT */
218   {cons, {c:-1L}},                      /* 116, _SC_2_PBS_LOCATE */
219   {cons, {c:-1L}},                      /* 117, _SC_2_PBS_MESSAGE */
220   {cons, {c:-1L}},                      /* 118, _SC_2_PBS_TRACK */
221   {cons, {c:_POSIX2_SW_DEV}},           /* 119, _SC_2_SW_DEV */
222   {cons, {c:_POSIX2_UPE}},              /* 120, _SC_2_UPE */
223   {cons, {c:_POSIX2_VERSION}},          /* 121, _SC_2_VERSION */
224   {cons, {c:-1L}},                      /* 122, _SC_THREAD_ROBUST_PRIO_INHERIT */
225   {cons, {c:-1L}},                      /* 123, _SC_THREAD_ROBUST_PRIO_PROTECT */
226   {cons, {c:-1L}},                      /* 124, _SC_XOPEN_UUCP */
227 };
228
229 #define SC_MIN _SC_ARG_MAX
230 #define SC_MAX _SC_XOPEN_UUCP
231
232 /* sysconf: POSIX 4.8.1.1 */
233 /* Allows a portable app to determine quantities of resources or
234    presence of an option at execution time. */
235 long int
236 sysconf (int in)
237 {
238   if (in >= SC_MIN && in <= SC_MAX)
239     {
240       switch (sca[in].type)
241         {
242         case nsup:
243           break;
244         case cons:
245           return sca[in].c;
246         case func:
247           return sca[in].f (in);
248         }
249     }
250   /* Unimplemented sysconf name or invalid option value. */
251   set_errno (EINVAL);
252   return -1L;
253 }
254
255 #define ls(s)   sizeof(s),s
256
257 static struct
258 {
259   size_t l;
260   const char *s;
261 } csa[] =
262 {
263   {ls ("/bin:/usr/bin")},               /* _CS_PATH */
264   {0, NULL},                            /* _CS_POSIX_V6_ILP32_OFF32_CFLAGS */
265   {0, NULL},                            /* _CS_POSIX_V6_ILP32_OFF32_LDFLAGS */
266   {0, NULL},                            /* _CS_POSIX_V6_ILP32_OFF32_LIBS */
267   {0, NULL},                            /* _CS_XBS5_ILP32_OFF32_LINTFLAGS */
268   {ls ("")},                            /* _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS */
269   {ls ("")},                            /* _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS */
270   {ls ("")},                            /* _CS_POSIX_V6_ILP32_OFFBIG_LIBS */
271   {ls ("")},                            /* _CS_XBS5_ILP32_OFFBIG_LINTFLAGS */
272   {0, NULL},                            /* _CS_POSIX_V6_LP64_OFF64_CFLAGS */
273   {0, NULL},                            /* _CS_POSIX_V6_LP64_OFF64_LDFLAGS */
274   {0, NULL},                            /* _CS_POSIX_V6_LP64_OFF64_LIBS */
275   {0, NULL},                            /* _CS_XBS5_LP64_OFF64_LINTFLAGS */
276   {0, NULL},                            /* _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS */
277   {0, NULL},                            /* _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS */
278   {0, NULL},                            /* _CS_POSIX_V6_LPBIG_OFFBIG_LIBS */
279   {0, NULL},                            /* _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS */
280   {ls ("POSIX_V6_ILP32_OFFBIG")},       /* _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS */
281   {ls ("")},                            /* _CS_POSIX_V7_THREADS_CFLAGS */
282   {ls ("")},                            /* _CS_POSIX_V7_THREADS_LDFLAGS */
283   {ls ("POSIXLY_CORRECT=1")},           /* _CS_V7_ENV */
284 };
285
286 #define CS_MIN _CS_PATH
287 #define CS_MAX _CS_V7_ENV
288
289 extern "C" size_t
290 confstr (int in, char *buf, size_t len)
291 {
292   if (in >= CS_MIN && in <= CS_MAX)
293     {
294       if (csa[in].l && len)
295         {
296           buf[0] = 0;
297           strncat (buf, csa[in].s, min (len, csa[in].l) - 1);
298         }
299       return csa[in].l;
300     }
301   /* Invalid option value. */
302   set_errno (EINVAL);
303   return 0;
304 }
305
306 extern "C" int
307 get_nprocs_conf (void)
308 {
309   return get_nproc_values (_SC_NPROCESSORS_CONF);
310 }
311
312 extern "C" int
313 get_nprocs (void)
314 {
315   return get_nproc_values (_SC_NPROCESSORS_ONLN);
316 }
317
318 extern "C" long
319 get_phys_pages (void)
320 {
321   return get_nproc_values (_SC_PHYS_PAGES);
322 }
323
324 extern "C" long
325 get_avphys_pages (void)
326 {
327   return get_avphys (_SC_AVPHYS_PAGES);
328 }
329
330 extern "C" int
331 sysinfo (struct sysinfo *info)
332 {
333   unsigned long long uptime = 0ULL, totalram = 0ULL, freeram = 0ULL,
334                 totalswap = 0ULL, freeswap = 0ULL;
335   MEMORYSTATUSEX memory_status;
336   PSYSTEM_PAGEFILE_INFORMATION spi = NULL;
337   ULONG sizeof_spi = 512;
338   PSYSTEM_TIME_OF_DAY_INFORMATION stodi = NULL;
339   const ULONG sizeof_stodi = sizeof (SYSTEM_TIME_OF_DAY_INFORMATION);
340   NTSTATUS status = STATUS_SUCCESS;
341   winpids pids ((DWORD) 0);
342
343   if (!info)
344     {
345       set_errno (EFAULT);
346       return -1;
347     }
348
349   stodi = (PSYSTEM_TIME_OF_DAY_INFORMATION) malloc (sizeof_stodi);
350   status = NtQuerySystemInformation (SystemTimeOfDayInformation, (PVOID) stodi,
351                                      sizeof_stodi, NULL);
352   if (NT_SUCCESS (status))
353     uptime = (stodi->CurrentTime.QuadPart - stodi->BootTime.QuadPart)
354              / 10000000ULL;
355   else
356     debug_printf ("NtQuerySystemInformation(SystemTimeOfDayInformation), "
357                   "status %p", status);
358
359   if (stodi)
360     free (stodi);
361
362   memory_status.dwLength = sizeof (MEMORYSTATUSEX);
363   GlobalMemoryStatusEx (&memory_status);
364   totalram = memory_status.ullTotalPhys / wincap.page_size ();
365   freeram = memory_status.ullAvailPhys / wincap.page_size ();
366
367   spi = (PSYSTEM_PAGEFILE_INFORMATION) malloc (sizeof_spi);
368   if (spi)
369     {
370       status = NtQuerySystemInformation (SystemPagefileInformation, (PVOID) spi,
371                                          sizeof_spi, &sizeof_spi);
372       if (status == STATUS_INFO_LENGTH_MISMATCH)
373         {
374           free (spi);
375           spi = (PSYSTEM_PAGEFILE_INFORMATION) malloc (sizeof_spi);
376           if (spi)
377             status = NtQuerySystemInformation (SystemPagefileInformation,
378                                                (PVOID) spi, sizeof_spi,
379                                                &sizeof_spi);
380         }
381     }
382   if (!spi || !NT_SUCCESS (status))
383     {
384       debug_printf ("NtQuerySystemInformation(SystemPagefileInformation), "
385                     "status %p", status);
386       totalswap = (memory_status.ullTotalPageFile - memory_status.ullTotalPhys)
387                   / wincap.page_size ();
388       freeswap = (memory_status.ullAvailPageFile - memory_status.ullTotalPhys)
389                  / wincap.page_size ();
390     }
391   else
392     {
393       PSYSTEM_PAGEFILE_INFORMATION spp = spi;
394       do
395         {
396           totalswap += spp->CurrentSize;
397           freeswap += spp->CurrentSize - spp->TotalUsed;
398         }
399       while (spp->NextEntryOffset
400              && (spp = (PSYSTEM_PAGEFILE_INFORMATION)
401                            ((char *) spp + spp->NextEntryOffset)));
402     }
403   if (spi)
404     free (spi);
405
406   info->uptime = (long) uptime;
407   info->totalram = (unsigned long) totalram;
408   info->freeram = (unsigned long) freeram;
409   info->totalswap = (unsigned long) totalswap;
410   info->freeswap = (unsigned long) freeswap;
411   info->procs = (unsigned short) pids.npids;
412   info->mem_unit = (unsigned int) wincap.page_size ();
413
414   /* FIXME: unsupported */
415   info->loads[0] = 0UL;
416   info->loads[1] = 0UL;
417   info->loads[2] = 0UL;
418   info->sharedram = 0UL;
419   info->bufferram = 0UL;
420   info->totalhigh = 0UL;
421   info->freehigh = 0UL;
422
423   return 0;
424 }