aboutsummaryrefslogtreecommitdiff
path: root/winsup/cygwin/sysconf.cc
blob: bdbbb99be0f757b4379400180001e556691ce381 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/* sysconf.cc

   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.

This file is part of Cygwin.

This software is a copyrighted work licensed under the terms of the
Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
details. */

#include "winsup.h"
#include <unistd.h>
#include <time.h>
#include <limits.h>
#include <ntdef.h>
#include "cygerrno.h"
#include "security.h"
#include "path.h"
#include "fhandler.h"
#include "dtable.h"
#include "cygheap.h"
#include "ntdll.h"

/* sysconf: POSIX 4.8.1.1 */
/* Allows a portable app to determine quantities of resources or
   presence of an option at execution time. */
long int
sysconf (int in)
{
  switch (in)
    {
      case _SC_ARG_MAX:
	/* FIXME: what's the right value?  _POSIX_ARG_MAX is only 4K */
	return 1048576;
      case _SC_OPEN_MAX:
	{
	  long max = getdtablesize ();
	  if (max < OPEN_MAX)
	    max = OPEN_MAX;
	  return max;
	}
      case _SC_PAGESIZE:
	return getpagesize ();
      case _SC_CLK_TCK:
	return CLOCKS_PER_SEC;
      case _SC_JOB_CONTROL:
	return _POSIX_JOB_CONTROL;
      case _SC_CHILD_MAX:
	return CHILD_MAX;
      case _SC_NGROUPS_MAX:
	return NGROUPS_MAX;
      case _SC_SAVED_IDS:
	return _POSIX_SAVED_IDS;
      case _SC_LOGIN_NAME_MAX:
	return LOGIN_NAME_MAX;
      case _SC_GETPW_R_SIZE_MAX:
      case _SC_GETGR_R_SIZE_MAX:
	return 16*1024;
      case _SC_VERSION:
	return _POSIX_VERSION;
#if 0	/* FIXME -- unimplemented */
      case _SC_TZNAME_MAX:
	return _POSIX_TZNAME_MAX;
      case _SC_STREAM_MAX:
	return _POSIX_STREAM_MAX;
#endif
      case _SC_NPROCESSORS_CONF:
      case _SC_NPROCESSORS_ONLN:
	if (!wincap.supports_smp ())
	  return 1;
	/*FALLTHRU*/
      case _SC_PHYS_PAGES:
	if (wincap.supports_smp ())
	  {
	    NTSTATUS ret;
	    SYSTEM_BASIC_INFORMATION sbi;
	    if ((ret = NtQuerySystemInformation (SystemBasicInformation,
						   (PVOID) &sbi,
						 sizeof sbi, NULL))
		  != STATUS_SUCCESS)
	      {
		__seterrno_from_nt_status (ret);
		debug_printf ("NtQuerySystemInformation: ret %d, Dos(ret) %E",
			      ret);
		return -1;
	      }
	    switch (in)
	      {
	      case _SC_NPROCESSORS_CONF:
	       return sbi.NumberProcessors;
	      case _SC_NPROCESSORS_ONLN:
	       {
		 int i = 0;
		 do
		   if (sbi.ActiveProcessors & 1)
		     i++;
		 while (sbi.ActiveProcessors >>= 1);
		 return i;
	       }
	      case _SC_PHYS_PAGES:
		return sbi.NumberOfPhysicalPages;
	      }
	  }
	break;
      case _SC_AVPHYS_PAGES:
	if (wincap.supports_smp ())
	  {
	    NTSTATUS ret;
	    SYSTEM_PERFORMANCE_INFORMATION spi;
	    if ((ret = NtQuerySystemInformation (SystemPerformanceInformation,
						   (PVOID) &spi,
						 sizeof spi, NULL))
		  != STATUS_SUCCESS)
	      {
		__seterrno_from_nt_status (ret);
		debug_printf ("NtQuerySystemInformation: ret %d, Dos(ret) %E",
			      ret);
		return -1;
	      }
	    return spi.AvailablePages;
	  }
      case _SC_RTSIG_MAX:
	return RTSIG_MAX;
      case _SC_TTY_NAME_MAX:
	return TTY_NAME_MAX;
      case _SC_MEMLOCK_RANGE:
	return _POSIX_MEMLOCK_RANGE;
    }

  /* Invalid input or unimplemented sysconf name */
  set_errno (EINVAL);
  return -1;
}