1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski *
3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file
5*b1cdbd2cSJim Jagielski * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file
7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski *
11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski *
13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the
17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski * under the License.
19*b1cdbd2cSJim Jagielski *
20*b1cdbd2cSJim Jagielski *************************************************************/
21*b1cdbd2cSJim Jagielski
22*b1cdbd2cSJim Jagielski
23*b1cdbd2cSJim Jagielski
24*b1cdbd2cSJim Jagielski
25*b1cdbd2cSJim Jagielski #include <unistd.h>
26*b1cdbd2cSJim Jagielski #include <errno.h>
27*b1cdbd2cSJim Jagielski #include <stdio.h>
28*b1cdbd2cSJim Jagielski #include <string.h>
29*b1cdbd2cSJim Jagielski #include <sys/ioctl.h>
30*b1cdbd2cSJim Jagielski #include <sys/socket.h>
31*b1cdbd2cSJim Jagielski #include <net/if.h>
32*b1cdbd2cSJim Jagielski
33*b1cdbd2cSJim Jagielski #ifdef SOLARIS
34*b1cdbd2cSJim Jagielski #include <sys/sockio.h>
35*b1cdbd2cSJim Jagielski #endif
36*b1cdbd2cSJim Jagielski
37*b1cdbd2cSJim Jagielski #include "osl/util.h"
38*b1cdbd2cSJim Jagielski
39*b1cdbd2cSJim Jagielski
40*b1cdbd2cSJim Jagielski
41*b1cdbd2cSJim Jagielski /*****************************************************************************/
42*b1cdbd2cSJim Jagielski /* Static Module Functions */
43*b1cdbd2cSJim Jagielski /*****************************************************************************/
44*b1cdbd2cSJim Jagielski
45*b1cdbd2cSJim Jagielski static int osl_getHWAddr(const char *ifname, char* hard_addr);
46*b1cdbd2cSJim Jagielski static int osl_checkAddr(const char* addr);
47*b1cdbd2cSJim Jagielski
48*b1cdbd2cSJim Jagielski
49*b1cdbd2cSJim Jagielski /*****************************************************************************/
50*b1cdbd2cSJim Jagielski /* osl_getEthernetAddress */
51*b1cdbd2cSJim Jagielski /*****************************************************************************/
52*b1cdbd2cSJim Jagielski
osl_getEthernetAddress(sal_uInt8 * pAddr)53*b1cdbd2cSJim Jagielski sal_Bool SAL_CALL osl_getEthernetAddress( sal_uInt8 * pAddr )
54*b1cdbd2cSJim Jagielski {
55*b1cdbd2cSJim Jagielski char buff[1024];
56*b1cdbd2cSJim Jagielski char hard_addr[64];
57*b1cdbd2cSJim Jagielski struct ifconf ifc;
58*b1cdbd2cSJim Jagielski struct ifreq *ifr;
59*b1cdbd2cSJim Jagielski int i;
60*b1cdbd2cSJim Jagielski int so;
61*b1cdbd2cSJim Jagielski
62*b1cdbd2cSJim Jagielski #ifdef SOLARIS
63*b1cdbd2cSJim Jagielski /** algorithm doesn't work on solaris */
64*b1cdbd2cSJim Jagielski return sal_False;
65*b1cdbd2cSJim Jagielski #else
66*b1cdbd2cSJim Jagielski
67*b1cdbd2cSJim Jagielski if ( pAddr == 0 )
68*b1cdbd2cSJim Jagielski {
69*b1cdbd2cSJim Jagielski return sal_False;
70*b1cdbd2cSJim Jagielski }
71*b1cdbd2cSJim Jagielski
72*b1cdbd2cSJim Jagielski
73*b1cdbd2cSJim Jagielski /*
74*b1cdbd2cSJim Jagielski * All we need is ... a network file descriptor.
75*b1cdbd2cSJim Jagielski * Normally, this is a very socket.
76*b1cdbd2cSJim Jagielski */
77*b1cdbd2cSJim Jagielski
78*b1cdbd2cSJim Jagielski so = socket(AF_INET, SOCK_DGRAM, 0);
79*b1cdbd2cSJim Jagielski
80*b1cdbd2cSJim Jagielski
81*b1cdbd2cSJim Jagielski /*
82*b1cdbd2cSJim Jagielski * The first thing we have to do, get the interface configuration.
83*b1cdbd2cSJim Jagielski * It is a list of attached/configured interfaces
84*b1cdbd2cSJim Jagielski */
85*b1cdbd2cSJim Jagielski
86*b1cdbd2cSJim Jagielski ifc.ifc_len = sizeof(buff);
87*b1cdbd2cSJim Jagielski ifc.ifc_buf = buff;
88*b1cdbd2cSJim Jagielski if ( ioctl(so, SIOCGIFCONF, &ifc) < 0 )
89*b1cdbd2cSJim Jagielski {
90*b1cdbd2cSJim Jagielski /* fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));*/
91*b1cdbd2cSJim Jagielski close(so);
92*b1cdbd2cSJim Jagielski return sal_False;
93*b1cdbd2cSJim Jagielski }
94*b1cdbd2cSJim Jagielski
95*b1cdbd2cSJim Jagielski close(so);
96*b1cdbd2cSJim Jagielski
97*b1cdbd2cSJim Jagielski /*
98*b1cdbd2cSJim Jagielski * For each of the interfaces in the interface list,
99*b1cdbd2cSJim Jagielski * try to get the hardware address
100*b1cdbd2cSJim Jagielski */
101*b1cdbd2cSJim Jagielski
102*b1cdbd2cSJim Jagielski ifr = ifc.ifc_req;
103*b1cdbd2cSJim Jagielski for ( i = ifc.ifc_len / sizeof(struct ifreq) ; --i >= 0 ; ifr++ )
104*b1cdbd2cSJim Jagielski {
105*b1cdbd2cSJim Jagielski int nRet=0;
106*b1cdbd2cSJim Jagielski nRet = osl_getHWAddr(ifr->ifr_name,hard_addr);
107*b1cdbd2cSJim Jagielski if ( nRet > 0 )
108*b1cdbd2cSJim Jagielski {
109*b1cdbd2cSJim Jagielski memcpy( pAddr , hard_addr, 6 );
110*b1cdbd2cSJim Jagielski return sal_True;
111*b1cdbd2cSJim Jagielski }
112*b1cdbd2cSJim Jagielski }
113*b1cdbd2cSJim Jagielski
114*b1cdbd2cSJim Jagielski return sal_False;
115*b1cdbd2cSJim Jagielski #endif
116*b1cdbd2cSJim Jagielski }
117*b1cdbd2cSJim Jagielski
118*b1cdbd2cSJim Jagielski
119*b1cdbd2cSJim Jagielski /*****************************************************************************/
120*b1cdbd2cSJim Jagielski /* osl_getHWAddr */
121*b1cdbd2cSJim Jagielski /*****************************************************************************/
122*b1cdbd2cSJim Jagielski
osl_getHWAddr(const char * ifname,char * hard_addr)123*b1cdbd2cSJim Jagielski static int osl_getHWAddr(const char *ifname, char* hard_addr)
124*b1cdbd2cSJim Jagielski {
125*b1cdbd2cSJim Jagielski int ret=0;
126*b1cdbd2cSJim Jagielski struct ifreq ifr;
127*b1cdbd2cSJim Jagielski int so = socket(AF_INET, SOCK_DGRAM, 0);
128*b1cdbd2cSJim Jagielski
129*b1cdbd2cSJim Jagielski strcpy(ifr.ifr_name, ifname);
130*b1cdbd2cSJim Jagielski
131*b1cdbd2cSJim Jagielski /*
132*b1cdbd2cSJim Jagielski * First, get the Interface-FLAGS
133*b1cdbd2cSJim Jagielski */
134*b1cdbd2cSJim Jagielski
135*b1cdbd2cSJim Jagielski ret=ioctl(so, SIOCGIFFLAGS, &ifr) ;
136*b1cdbd2cSJim Jagielski
137*b1cdbd2cSJim Jagielski if ( ret < 0 )
138*b1cdbd2cSJim Jagielski {
139*b1cdbd2cSJim Jagielski /* fprintf(stderr, "SIOCGIFFLAGS: %s\n", strerror(errno)); */
140*b1cdbd2cSJim Jagielski close(so);
141*b1cdbd2cSJim Jagielski return ret;
142*b1cdbd2cSJim Jagielski }
143*b1cdbd2cSJim Jagielski
144*b1cdbd2cSJim Jagielski
145*b1cdbd2cSJim Jagielski /*
146*b1cdbd2cSJim Jagielski * If it is the loopback device, do not consider it any further
147*b1cdbd2cSJim Jagielski */
148*b1cdbd2cSJim Jagielski
149*b1cdbd2cSJim Jagielski if (ifr.ifr_flags & IFF_LOOPBACK)
150*b1cdbd2cSJim Jagielski {
151*b1cdbd2cSJim Jagielski /* fprintf(stderr, "SIOCGIFFLAGS : is LOOPBACK : %s\n", strerror(errno));*/
152*b1cdbd2cSJim Jagielski close(so);
153*b1cdbd2cSJim Jagielski return 0;
154*b1cdbd2cSJim Jagielski }
155*b1cdbd2cSJim Jagielski
156*b1cdbd2cSJim Jagielski
157*b1cdbd2cSJim Jagielski /*
158*b1cdbd2cSJim Jagielski * And now, the real thing: the get address
159*b1cdbd2cSJim Jagielski */
160*b1cdbd2cSJim Jagielski
161*b1cdbd2cSJim Jagielski #if defined(SIOCGIFHWADDR) && !defined(SOLARIS)
162*b1cdbd2cSJim Jagielski ret=ioctl(so, SIOCGIFHWADDR, &ifr);
163*b1cdbd2cSJim Jagielski #else
164*b1cdbd2cSJim Jagielski ret=ioctl(so, SIOCGIFADDR, &ifr);
165*b1cdbd2cSJim Jagielski #endif
166*b1cdbd2cSJim Jagielski
167*b1cdbd2cSJim Jagielski if (ret < 0) {
168*b1cdbd2cSJim Jagielski /* fprintf(stderr, "SIOCGIFADDR: %s\n", strerror(errno));*/
169*b1cdbd2cSJim Jagielski memset(hard_addr, 0, 32);
170*b1cdbd2cSJim Jagielski close(so);
171*b1cdbd2cSJim Jagielski return ret;
172*b1cdbd2cSJim Jagielski }
173*b1cdbd2cSJim Jagielski
174*b1cdbd2cSJim Jagielski close(so);
175*b1cdbd2cSJim Jagielski
176*b1cdbd2cSJim Jagielski #if defined(SIOCGIFHWADDR) && !defined(SOLARIS)
177*b1cdbd2cSJim Jagielski memcpy(hard_addr,ifr.ifr_hwaddr.sa_data,8);
178*b1cdbd2cSJim Jagielski #else
179*b1cdbd2cSJim Jagielski memcpy(hard_addr,ifr.ifr_ifru.ifru_addr.sa_data,8);
180*b1cdbd2cSJim Jagielski #endif
181*b1cdbd2cSJim Jagielski
182*b1cdbd2cSJim Jagielski
183*b1cdbd2cSJim Jagielski /*
184*b1cdbd2cSJim Jagielski * Check, if no real, i.e. 00:00:00:00:00:00, address was retrieved.
185*b1cdbd2cSJim Jagielski * The Linux dummy device has this kind of behaviour
186*b1cdbd2cSJim Jagielski */
187*b1cdbd2cSJim Jagielski
188*b1cdbd2cSJim Jagielski ret=osl_checkAddr(hard_addr);
189*b1cdbd2cSJim Jagielski
190*b1cdbd2cSJim Jagielski if (ret < 0) {
191*b1cdbd2cSJim Jagielski /* fprintf(stderr, "SIOCGIFADDR got '00:00:00:00:00:00'\n"); */
192*b1cdbd2cSJim Jagielski return ret;
193*b1cdbd2cSJim Jagielski }
194*b1cdbd2cSJim Jagielski
195*b1cdbd2cSJim Jagielski /* fprintf(stderr,"interface : %s -- ",ifname);*/
196*b1cdbd2cSJim Jagielski /* fprintf(stderr,"HWaddr : %s\n", print_ether(hard_addr));*/
197*b1cdbd2cSJim Jagielski
198*b1cdbd2cSJim Jagielski return 1;
199*b1cdbd2cSJim Jagielski }
200*b1cdbd2cSJim Jagielski
201*b1cdbd2cSJim Jagielski
202*b1cdbd2cSJim Jagielski /*****************************************************************************/
203*b1cdbd2cSJim Jagielski /* osl_checkAddr */
204*b1cdbd2cSJim Jagielski /*****************************************************************************/
205*b1cdbd2cSJim Jagielski
osl_checkAddr(const char * addr)206*b1cdbd2cSJim Jagielski static int osl_checkAddr(const char* addr)
207*b1cdbd2cSJim Jagielski {
208*b1cdbd2cSJim Jagielski if (addr[0]==0 && addr[1]==0 &&
209*b1cdbd2cSJim Jagielski addr[2]==0 && addr[3]==0 &&
210*b1cdbd2cSJim Jagielski addr[4]==0 && addr[5]==0)
211*b1cdbd2cSJim Jagielski {
212*b1cdbd2cSJim Jagielski return -1;
213*b1cdbd2cSJim Jagielski }
214*b1cdbd2cSJim Jagielski return 0;
215*b1cdbd2cSJim Jagielski }
216*b1cdbd2cSJim Jagielski
217*b1cdbd2cSJim Jagielski
218*b1cdbd2cSJim Jagielski #if defined (SPARC)
219*b1cdbd2cSJim Jagielski
220*b1cdbd2cSJim Jagielski #if defined (SOLARIS) && !defined(__sparcv8plus) && !defined(__sparcv9)
221*b1cdbd2cSJim Jagielski #include <sys/types.h>
222*b1cdbd2cSJim Jagielski #include <sys/processor.h>
223*b1cdbd2cSJim Jagielski
224*b1cdbd2cSJim Jagielski /*****************************************************************************/
225*b1cdbd2cSJim Jagielski /* osl_InitSparcV9 */
226*b1cdbd2cSJim Jagielski /*****************************************************************************/
227*b1cdbd2cSJim Jagielski
228*b1cdbd2cSJim Jagielski void osl_InterlockedCountSetV9(sal_Bool bV9);
229*b1cdbd2cSJim Jagielski
230*b1cdbd2cSJim Jagielski /*
231*b1cdbd2cSJim Jagielski * osl_InitSparcV9() should be executed as early as possible. We place it in the
232*b1cdbd2cSJim Jagielski * .init section of sal
233*b1cdbd2cSJim Jagielski */
234*b1cdbd2cSJim Jagielski #if defined ( __SUNPRO_C ) || defined ( __SUNPRO_CC )
235*b1cdbd2cSJim Jagielski void osl_InitSparcV9(void);
236*b1cdbd2cSJim Jagielski #pragma init (osl_InitSparcV9)
237*b1cdbd2cSJim Jagielski #elif defined ( __GNUC__ )
238*b1cdbd2cSJim Jagielski void osl_InitSparcV9(void) __attribute__((constructor));
239*b1cdbd2cSJim Jagielski #endif
240*b1cdbd2cSJim Jagielski
osl_InitSparcV9(void)241*b1cdbd2cSJim Jagielski void osl_InitSparcV9(void)
242*b1cdbd2cSJim Jagielski {
243*b1cdbd2cSJim Jagielski /* processor_info() identifies SPARCV8 (ie sun4c machines) simply as "sparc"
244*b1cdbd2cSJim Jagielski * and SPARCV9 (ie ultra sparcs, sun4u) as "sparcv9". Since we know that we
245*b1cdbd2cSJim Jagielski * run at least on a SPARCV8 architecture or better, any processor type != "sparc"
246*b1cdbd2cSJim Jagielski * and != "i386" is considered to be SPARCV9 or better
247*b1cdbd2cSJim Jagielski *
248*b1cdbd2cSJim Jagielski * This way we are certain that this will still work if someone names SPARCV10
249*b1cdbd2cSJim Jagielski * "foobar"
250*b1cdbd2cSJim Jagielski */
251*b1cdbd2cSJim Jagielski processor_info_t aInfo;
252*b1cdbd2cSJim Jagielski int rc;
253*b1cdbd2cSJim Jagielski
254*b1cdbd2cSJim Jagielski rc = processor_info(0, &aInfo);
255*b1cdbd2cSJim Jagielski
256*b1cdbd2cSJim Jagielski if ( rc != -1 ) {
257*b1cdbd2cSJim Jagielski if ( !strcmp( "sparc", aInfo.pi_processor_type ) /* SPARCV8 */
258*b1cdbd2cSJim Jagielski || !strcmp( "i386", aInfo.pi_processor_type ) ) /* can't happen, but ... */
259*b1cdbd2cSJim Jagielski return;
260*b1cdbd2cSJim Jagielski /* we are reasonably certain to be on sparcv9/sparcv8plus or better */
261*b1cdbd2cSJim Jagielski osl_InterlockedCountSetV9(sal_True);
262*b1cdbd2cSJim Jagielski }
263*b1cdbd2cSJim Jagielski }
264*b1cdbd2cSJim Jagielski
265*b1cdbd2cSJim Jagielski #endif /* SOLARIS */
266*b1cdbd2cSJim Jagielski
267*b1cdbd2cSJim Jagielski #if defined(NETBSD) && defined(GCC) && !defined(__sparcv9) && !defined(__sparc_v9__)
268*b1cdbd2cSJim Jagielski
269*b1cdbd2cSJim Jagielski #include <sys/param.h>
270*b1cdbd2cSJim Jagielski #include <sys/sysctl.h>
271*b1cdbd2cSJim Jagielski void osl_InitSparcV9(void) __attribute__((constructor));
272*b1cdbd2cSJim Jagielski void osl_InterlockedCountSetV9(sal_Bool bV9);
273*b1cdbd2cSJim Jagielski
274*b1cdbd2cSJim Jagielski /* Determine which processor we are running on (sparc v8 or v9)
275*b1cdbd2cSJim Jagielski * The approach is very similar to Solaris.
276*b1cdbd2cSJim Jagielski */
277*b1cdbd2cSJim Jagielski
osl_InitSparcV9(void)278*b1cdbd2cSJim Jagielski void osl_InitSparcV9(void)
279*b1cdbd2cSJim Jagielski {
280*b1cdbd2cSJim Jagielski int mib[2]={CTL_HW,HW_MACHINE};
281*b1cdbd2cSJim Jagielski char processorname[256];
282*b1cdbd2cSJim Jagielski size_t len=256;
283*b1cdbd2cSJim Jagielski
284*b1cdbd2cSJim Jagielski /* get the machine name */
285*b1cdbd2cSJim Jagielski sysctl(mib, 2, processorname, &len, NULL, 0);
286*b1cdbd2cSJim Jagielski if (!strncmp("sparc64",processorname, len)) {
287*b1cdbd2cSJim Jagielski osl_InterlockedCountSetV9(sal_True);
288*b1cdbd2cSJim Jagielski }
289*b1cdbd2cSJim Jagielski }
290*b1cdbd2cSJim Jagielski
291*b1cdbd2cSJim Jagielski #endif /* NETBSD */
292*b1cdbd2cSJim Jagielski
293*b1cdbd2cSJim Jagielski #endif /* SPARC */
294*b1cdbd2cSJim Jagielski
295*b1cdbd2cSJim Jagielski #if defined ( LINUX ) && defined ( SPARC )
296*b1cdbd2cSJim Jagielski #include <sys/utsname.h>
297*b1cdbd2cSJim Jagielski void osl_InitSparcV9(void) __attribute__((constructor));
298*b1cdbd2cSJim Jagielski void osl_InterlockedCountSetV9(sal_Bool bV9);
299*b1cdbd2cSJim Jagielski /* Determine which processor we are running on (sparc v8 or v9)
300*b1cdbd2cSJim Jagielski * The approach is very similar to Solaris.
301*b1cdbd2cSJim Jagielski */
osl_InitSparcV9(void)302*b1cdbd2cSJim Jagielski void osl_InitSparcV9(void)
303*b1cdbd2cSJim Jagielski {
304*b1cdbd2cSJim Jagielski struct utsname name;
305*b1cdbd2cSJim Jagielski int rc;
306*b1cdbd2cSJim Jagielski rc = uname(&name);
307*b1cdbd2cSJim Jagielski if ( rc != -1 ) {
308*b1cdbd2cSJim Jagielski if ( !strcmp( "sparc", name.machine ))
309*b1cdbd2cSJim Jagielski return;
310*b1cdbd2cSJim Jagielski osl_InterlockedCountSetV9(sal_True);
311*b1cdbd2cSJim Jagielski }
312*b1cdbd2cSJim Jagielski }
313*b1cdbd2cSJim Jagielski #endif
314*b1cdbd2cSJim Jagielski
315*b1cdbd2cSJim Jagielski #if ( defined(__GNUC__) && (defined(X86) || defined(X86_64)) )\
316*b1cdbd2cSJim Jagielski || ( defined(SOLARIS) && defined (__SUNPRO_C) && defined(__i386) )
317*b1cdbd2cSJim Jagielski
318*b1cdbd2cSJim Jagielski /* Safe default */
319*b1cdbd2cSJim Jagielski int osl_isSingleCPU = 0;
320*b1cdbd2cSJim Jagielski
321*b1cdbd2cSJim Jagielski /* Determine if we are on a multiprocessor/multicore/HT x86/x64 system
322*b1cdbd2cSJim Jagielski *
323*b1cdbd2cSJim Jagielski * The lock prefix for atomic operations in osl_[inc|de]crementInterlockedCount()
324*b1cdbd2cSJim Jagielski * comes with a cost and is especially expensive on pre HT x86 single processor
325*b1cdbd2cSJim Jagielski * systems, where it isn't needed at all.
326*b1cdbd2cSJim Jagielski *
327*b1cdbd2cSJim Jagielski * This should be run as early as possible, thus it's placed in the init section
328*b1cdbd2cSJim Jagielski */
329*b1cdbd2cSJim Jagielski #if defined(_SC_NPROCESSORS_CONF) /* i.e. MACOSX for Intel doesn't have this */
330*b1cdbd2cSJim Jagielski #if defined(__GNUC__)
331*b1cdbd2cSJim Jagielski void osl_interlockedCountCheckForSingleCPU(void) __attribute__((constructor));
332*b1cdbd2cSJim Jagielski #elif defined(__SUNPRO_C)
333*b1cdbd2cSJim Jagielski void osl_interlockedCountCheckForSingleCPU(void);
334*b1cdbd2cSJim Jagielski #pragma init (osl_interlockedCountCheckForSingleCPU)
335*b1cdbd2cSJim Jagielski #endif
336*b1cdbd2cSJim Jagielski
osl_interlockedCountCheckForSingleCPU(void)337*b1cdbd2cSJim Jagielski void osl_interlockedCountCheckForSingleCPU(void)
338*b1cdbd2cSJim Jagielski {
339*b1cdbd2cSJim Jagielski /* In case sysconfig fails be on the safe side,
340*b1cdbd2cSJim Jagielski * consider it a multiprocessor/multicore/HT system */
341*b1cdbd2cSJim Jagielski if ( sysconf(_SC_NPROCESSORS_CONF) == 1 ) {
342*b1cdbd2cSJim Jagielski osl_isSingleCPU = 1;
343*b1cdbd2cSJim Jagielski }
344*b1cdbd2cSJim Jagielski }
345*b1cdbd2cSJim Jagielski #endif /* defined(_SC_NPROCESSORS_CONF) */
346*b1cdbd2cSJim Jagielski #endif
347