This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #128763] Fix POSIX.xs longdbl assertion
[perl5.git] / ext / POSIX / POSIX.xs
CommitLineData
6e22d046
JH
1#define PERL_EXT_POSIX
2
2986a63f
JH
3#ifdef NETWARE
4 #define _POSIX_
4efcf9a2
SB
5 /*
6 * Ideally this should be somewhere down in the includes
7 * but putting it in other places is giving compiler errors.
8 * Also here I am unable to check for HAS_UNAME since it wouldn't have
9 * yet come into the file at this stage - sgp 18th Oct 2000
10 */
2986a63f
JH
11 #include <sys/utsname.h>
12#endif /* NETWARE */
13
c5be433b
GS
14#define PERL_NO_GET_CONTEXT
15
463ee0b2 16#include "EXTERN.h"
760ac839 17#define PERLIO_NOT_STDIO 1
463ee0b2
LW
18#include "perl.h"
19#include "XSUB.h"
acfe0abc 20#if defined(PERL_IMPLICIT_SYS)
873ef191
GS
21# undef signal
22# undef open
cd661bb6 23# undef setmode
35ff7856 24# define open PerlLIO_open3
873ef191 25#endif
2304df62 26#include <ctype.h>
a0d0e21e 27#ifdef I_DIRENT /* XXX maybe better to just rely on perl.h? */
2304df62 28#include <dirent.h>
a0d0e21e 29#endif
2304df62 30#include <errno.h>
b0ba2190
SH
31#ifdef WIN32
32#include <sys/errno2.h>
33#endif
2304df62
AD
34#ifdef I_FLOAT
35#include <float.h>
36#endif
a5713e21
JH
37#ifdef I_FENV
38#include <fenv.h>
39#endif
a0d0e21e 40#ifdef I_LIMITS
2304df62 41#include <limits.h>
a0d0e21e 42#endif
2304df62
AD
43#include <locale.h>
44#include <math.h>
85e6fe83 45#ifdef I_PWD
2304df62 46#include <pwd.h>
85e6fe83 47#endif
2304df62
AD
48#include <setjmp.h>
49#include <signal.h>
2304df62 50#include <stdarg.h>
17c3b450 51
2304df62
AD
52#ifdef I_STDDEF
53#include <stddef.h>
54#endif
6990d991 55
b5846a0b
BS
56#ifdef I_UNISTD
57#include <unistd.h>
58#endif
59
05b4a618
JH
60#if defined(USE_QUADMATH) && defined(I_QUADMATH)
61
62# undef M_E
63# undef M_LOG2E
64# undef M_LOG10E
65# undef M_LN2
66# undef M_LN10
67# undef M_PI
68# undef M_PI_2
69# undef M_PI_4
70# undef M_1_PI
71# undef M_2_PI
72# undef M_2_SQRTPI
73# undef M_SQRT2
74# undef M_SQRT1_2
75
76# define M_E M_Eq
77# define M_LOG2E M_LOG2Eq
78# define M_LOG10E M_LOG10Eq
79# define M_LN2 M_LN2q
80# define M_LN10 M_LN10q
81# define M_PI M_PIq
82# define M_PI_2 M_PI_2q
83# define M_PI_4 M_PI_4q
84# define M_1_PI M_1_PIq
85# define M_2_PI M_2_PIq
86# define M_2_SQRTPI M_2_SQRTPIq
87# define M_SQRT2 M_SQRT2q
88# define M_SQRT1_2 M_SQRT1_2q
89
90#else
91
19035550
JH
92# ifdef USE_LONG_DOUBLE
93# undef M_E
94# undef M_LOG2E
95# undef M_LOG10E
96# undef M_LN2
97# undef M_LN10
98# undef M_PI
99# undef M_PI_2
100# undef M_PI_4
101# undef M_1_PI
102# undef M_2_PI
103# undef M_2_SQRTPI
104# undef M_SQRT2
105# undef M_SQRT1_2
106# define FLOAT_C(c) CAT2(c,L)
107# else
108# define FLOAT_C(c) (c)
109# endif
110
05b4a618 111# ifndef M_E
19035550 112# define M_E FLOAT_C(2.71828182845904523536028747135266250)
05b4a618
JH
113# endif
114# ifndef M_LOG2E
19035550 115# define M_LOG2E FLOAT_C(1.44269504088896340735992468100189214)
05b4a618
JH
116# endif
117# ifndef M_LOG10E
19035550 118# define M_LOG10E FLOAT_C(0.434294481903251827651128918916605082)
05b4a618
JH
119# endif
120# ifndef M_LN2
19035550 121# define M_LN2 FLOAT_C(0.693147180559945309417232121458176568)
05b4a618
JH
122# endif
123# ifndef M_LN10
19035550 124# define M_LN10 FLOAT_C(2.30258509299404568401799145468436421)
05b4a618
JH
125# endif
126# ifndef M_PI
19035550 127# define M_PI FLOAT_C(3.14159265358979323846264338327950288)
05b4a618
JH
128# endif
129# ifndef M_PI_2
19035550 130# define M_PI_2 FLOAT_C(1.57079632679489661923132169163975144)
05b4a618
JH
131# endif
132# ifndef M_PI_4
19035550 133# define M_PI_4 FLOAT_C(0.785398163397448309615660845819875721)
05b4a618
JH
134# endif
135# ifndef M_1_PI
19035550 136# define M_1_PI FLOAT_C(0.318309886183790671537767526745028724)
05b4a618
JH
137# endif
138# ifndef M_2_PI
19035550 139# define M_2_PI FLOAT_C(0.636619772367581343075535053490057448)
05b4a618
JH
140# endif
141# ifndef M_2_SQRTPI
19035550 142# define M_2_SQRTPI FLOAT_C(1.12837916709551257389615890312154517)
05b4a618
JH
143# endif
144# ifndef M_SQRT2
19035550 145# define M_SQRT2 FLOAT_C(1.41421356237309504880168872420969808)
05b4a618
JH
146# endif
147# ifndef M_SQRT1_2
19035550 148# define M_SQRT1_2 FLOAT_C(0.707106781186547524400844362104849039)
05b4a618
JH
149# endif
150
39b5f1c4
JH
151#endif
152
a5f1a7e5
JH
153#if !defined(INFINITY) && defined(NV_INF)
154# define INFINITY NV_INF
155#endif
156
157#if !defined(NAN) && defined(NV_NAN)
158# define NAN NV_NAN
159#endif
160
161#if !defined(Inf) && defined(NV_INF)
162# define Inf NV_INF
163#endif
164
165#if !defined(NaN) && defined(NV_NAN)
166# define NaN NV_NAN
167#endif
168
935e3c48 169/* We will have an emulation. */
3f8e6f93 170#ifndef FP_INFINITE
935e3c48
JH
171# define FP_INFINITE 0
172# define FP_NAN 1
173# define FP_NORMAL 2
174# define FP_SUBNORMAL 3
175# define FP_ZERO 4
176#endif
177
e0939537
JH
178/* We will have an emulation. */
179#ifndef FE_TONEAREST
ebac59ac
JH
180# define FE_TOWARDZERO 0
181# define FE_TONEAREST 1
182# define FE_UPWARD 2
183# define FE_DOWNWARD 3
e0939537
JH
184#endif
185
7965edec
JH
186/* C89 math.h:
187
188 acos asin atan atan2 ceil cos cosh exp fabs floor fmod frexp ldexp
189 log log10 modf pow sin sinh sqrt tan tanh
190
191 * Implemented in core:
192
193 atan2 cos exp log pow sin sqrt
194
9d233e12 195 * C99 math.h added:
7965edec 196
9d233e12
JH
197 acosh asinh atanh cbrt copysign erf erfc exp2 expm1 fdim fma fmax
198 fmin fpclassify hypot ilogb isfinite isgreater isgreaterequal isinf
199 isless islessequal islessgreater isnan isnormal isunordered lgamma
9e010b89 200 log1p log2 logb lrint lround nan nearbyint nextafter nexttoward remainder
9d233e12 201 remquo rint round scalbn signbit tgamma trunc
7965edec 202
36467c3a
JH
203 See:
204 http://pubs.opengroup.org/onlinepubs/009695399/basedefs/math.h.html
205
26e0f0d3 206 * Berkeley/SVID extensions:
7965edec 207
26e0f0d3 208 j0 j1 jn y0 y1 yn
7965edec 209
427d28ce 210 * Configure already (5.21.5) scans for:
d2bce0fd 211
427d28ce 212 copysign*l* fpclassify isfinite isinf isnan isnan*l* ilogb*l* signbit scalbn*l*
d2bce0fd 213
26e0f0d3 214 * For floating-point round mode (which matters for e.g. lrint and rint)
9d233e12 215
26e0f0d3 216 fegetround fesetround
9d233e12 217
7965edec
JH
218*/
219
9d233e12
JH
220/* XXX Constant FP_FAST_FMA (if true, FMA is faster) */
221
5716d070
JH
222/* XXX Add ldiv(), lldiv()? It's C99, but from stdlib.h, not math.h */
223
39b5f1c4 224/* XXX Beware old gamma() -- one cannot know whether that is the
d334ccbe 225 * gamma or the log of gamma, that's why the new tgamma and lgamma.
2e9cdb62 226 * Though also remember lgamma_r. */
39b5f1c4 227
e0972548
JH
228/* Certain AIX releases have the C99 math, but not in long double.
229 * The <math.h> has them, e.g. __expl128, but no library has them!
78c93c95 230 *
42f1389c 231 * Also see the comments in hints/aix.sh about long doubles. */
e0972548 232
f1498836
JH
233#if defined(USE_QUADMATH) && defined(I_QUADMATH)
234# define c99_acosh acoshq
235# define c99_asinh asinhq
236# define c99_atanh atanhq
237# define c99_cbrt cbrtq
238# define c99_copysign copysignq
239# define c99_erf erfq
240# define c99_erfc erfcq
05b4a618 241/* no exp2q */
f1498836
JH
242# define c99_expm1 expm1q
243# define c99_fdim fdimq
244# define c99_fma fmaq
245# define c99_fmax fmaxq
246# define c99_fmin fminq
247# define c99_hypot hypotq
248# define c99_ilogb ilogbq
249# define c99_lgamma lgammaq
250# define c99_log1p log1pq
251# define c99_log2 log2q
05b4a618 252/* no logbq */
568793b6
JH
253# if defined(USE_64_BIT_INT) && QUADKIND == QUAD_IS_LONG_LONG
254# define c99_lrint llrintq
255# define c99_lround llroundq
256# else
257# define c99_lrint lrintq
258# define c99_lround lroundq
259# endif
f1498836
JH
260# define c99_nan nanq
261# define c99_nearbyint nearbyintq
262# define c99_nextafter nextafterq
05b4a618 263/* no nexttowardq */
f1498836
JH
264# define c99_remainder remainderq
265# define c99_remquo remquoq
266# define c99_rint rintq
267# define c99_round roundq
268# define c99_scalbn scalbnq
269# define c99_signbit signbitq
270# define c99_tgamma tgammaq
271# define c99_trunc truncq
272# define bessel_j0 j0q
273# define bessel_j1 j1q
274# define bessel_jn jnq
275# define bessel_y0 y0q
276# define bessel_y1 y1q
277# define bessel_yn ynq
278#elif defined(USE_LONG_DOUBLE) && \
22192125
JH
279 (defined(HAS_FREXPL) || defined(HAS_ILOGBL)) && defined(HAS_SQRTL)
280/* Use some of the Configure scans for long double math functions
281 * as the canary for all the C99 *l variants being defined. */
f1498836
JH
282# define c99_acosh acoshl
283# define c99_asinh asinhl
284# define c99_atanh atanhl
285# define c99_cbrt cbrtl
286# define c99_copysign copysignl
287# define c99_erf erfl
288# define c99_erfc erfcl
289# define c99_exp2 exp2l
290# define c99_expm1 expm1l
291# define c99_fdim fdiml
292# define c99_fma fmal
293# define c99_fmax fmaxl
294# define c99_fmin fminl
295# define c99_hypot hypotl
296# define c99_ilogb ilogbl
297# define c99_lgamma lgammal
298# define c99_log1p log1pl
299# define c99_log2 log2l
300# define c99_logb logbl
755cce00
JH
301# if defined(USE_64_BIT_INT) && QUADKIND == QUAD_IS_LONG_LONG && defined(HAS_LLRINTL)
302# define c99_lrint llrintl
303# elif defined(HAS_LRINTL)
f1498836
JH
304# define c99_lrint lrintl
305# endif
755cce00 306# if defined(USE_64_BIT_INT) && QUADKIND == QUAD_IS_LONG_LONG && defined(HAS_LLROUNDL)
f1498836 307# define c99_lround llroundl
755cce00 308# elif defined(HAS_LROUNDL)
f1498836
JH
309# define c99_lround lroundl
310# endif
311# define c99_nan nanl
312# define c99_nearbyint nearbyintl
313# define c99_nextafter nextafterl
314# define c99_nexttoward nexttowardl
315# define c99_remainder remainderl
316# define c99_remquo remquol
317# define c99_rint rintl
318# define c99_round roundl
319# define c99_scalbn scalbnl
320# ifdef HAS_SIGNBIT /* possibly bad assumption */
321# define c99_signbit signbitl
322# endif
323# define c99_tgamma tgammal
324# define c99_trunc truncl
325#else
326# define c99_acosh acosh
327# define c99_asinh asinh
328# define c99_atanh atanh
329# define c99_cbrt cbrt
330# define c99_copysign copysign
331# define c99_erf erf
332# define c99_erfc erfc
333# define c99_exp2 exp2
334# define c99_expm1 expm1
335# define c99_fdim fdim
336# define c99_fma fma
337# define c99_fmax fmax
338# define c99_fmin fmin
339# define c99_hypot hypot
340# define c99_ilogb ilogb
341# define c99_lgamma lgamma
342# define c99_log1p log1p
343# define c99_log2 log2
344# define c99_logb logb
345# if defined(USE_64_BIT_INT) && QUADKIND == QUAD_IS_LONG_LONG && defined(HAS_LLRINT)
346# define c99_lrint llrint
347# else
348# define c99_lrint lrint
349# endif
350# if defined(USE_64_BIT_INT) && QUADKIND == QUAD_IS_LONG_LONG && defined(HAS_LLROUND)
351# define c99_lround llround
7965edec 352# else
f1498836
JH
353# define c99_lround lround
354# endif
355# define c99_nan nan
356# define c99_nearbyint nearbyint
357# define c99_nextafter nextafter
358# define c99_nexttoward nexttoward
359# define c99_remainder remainder
360# define c99_remquo remquo
361# define c99_rint rint
362# define c99_round round
363# define c99_scalbn scalbn
5716d070 364/* We already define Perl_signbit in perl.h. */
f1498836
JH
365# ifdef HAS_SIGNBIT
366# define c99_signbit signbit
7965edec 367# endif
f1498836
JH
368# define c99_tgamma tgamma
369# define c99_trunc trunc
370#endif
03397f96 371
b8b5f83a
JH
372/* AIX xlc (__IBMC__) really doesn't have the following long double
373 * math interfaces (no __acoshl128 aka acoshl, etc.), see
374 * hints/aix.sh. These are in the -lc128 but fail to be found
375 * during dynamic linking/loading.
376 *
377 * XXX1 Better Configure scans
378 * XXX2 Is this xlc version dependent? */
379#if defined(USE_LONG_DOUBLE) && defined(__IBMC__)
380# undef c99_acosh
381# undef c99_asinh
382# undef c99_atanh
383# undef c99_cbrt
384# undef c99_copysign
385# undef c99_exp2
386# undef c99_expm1
387# undef c99_fdim
388# undef c99_fma
389# undef c99_fmax
390# undef c99_fmin
391# undef c99_hypot
392# undef c99_ilogb
393# undef c99_lrint
394# undef c99_lround
395# undef c99_log1p
396# undef c99_log2
397# undef c99_logb
398# undef c99_nan
399# undef c99_nearbyint
400# undef c99_nextafter
401# undef c99_nexttoward
402# undef c99_remainder
403# undef c99_remquo
404# undef c99_rint
405# undef c99_round
406# undef c99_scalbn
407# undef c99_tgamma
408# undef c99_trunc
409#endif
410
f1498836
JH
411#ifndef isunordered
412# ifdef Perl_isnan
413# define isunordered(x, y) (Perl_isnan(x) || Perl_isnan(y))
414# elif defined(HAS_UNORDERED)
415# define isunordered(x, y) unordered(x, y)
2bf3fd6f 416# endif
f1498836 417#endif
2bf3fd6f 418
a0d9739d
JH
419/* XXX these isgreater/isnormal/isunordered macros definitions should
420 * be moved further in the file to be part of the emulations, so that
421 * platforms can e.g. #undef c99_isunordered and have it work like
422 * it does for the other interfaces. */
423
f1498836
JH
424#if !defined(isgreater) && defined(isunordered)
425# define isgreater(x, y) (!isunordered((x), (y)) && (x) > (y))
426# define isgreaterequal(x, y) (!isunordered((x), (y)) && (x) >= (y))
427# define isless(x, y) (!isunordered((x), (y)) && (x) < (y))
428# define islessequal(x, y) (!isunordered((x), (y)) && (x) <= (y))
429# define islessgreater(x, y) (!isunordered((x), (y)) && \
2bf3fd6f 430 ((x) > (y) || (y) > (x)))
f1498836 431#endif
2bf3fd6f 432
03397f96 433/* Check both the Configure symbol and the macro-ness (like C99 promises). */
f1498836
JH
434#if defined(HAS_FPCLASSIFY) && defined(fpclassify)
435# define c99_fpclassify fpclassify
436#endif
03397f96
JH
437/* Like isnormal(), the isfinite(), isinf(), and isnan() are also C99
438 and also (sizeof-arg-aware) macros, but they are already well taken
439 care of by Configure et al, and defined in perl.h as
440 Perl_isfinite(), Perl_isinf(), and Perl_isnan(). */
f1498836
JH
441#ifdef isnormal
442# define c99_isnormal isnormal
443#endif
444#ifdef isgreater /* canary for all the C99 is*<cmp>* macros. */
445# define c99_isgreater isgreater
446# define c99_isgreaterequal isgreaterequal
447# define c99_isless isless
448# define c99_islessequal islessequal
449# define c99_islessgreater islessgreater
450# define c99_isunordered isunordered
7965edec
JH
451#endif
452
d0e3c0f2
JH
453/* The Great Wall of Undef where according to the definedness of HAS_FOO symbols
454 * the corresponding c99_foo wrappers are undefined. This list doesn't include
455 * the isfoo() interfaces because they are either type-aware macros, or dealt
456 * separately, already in perl.h */
457
458#ifndef HAS_ACOSH
459# undef c99_acosh
460#endif
461#ifndef HAS_ASINH
462# undef c99_asinh
463#endif
464#ifndef HAS_ATANH
465# undef c99_atanh
466#endif
467#ifndef HAS_CBRT
468# undef c99_cbrt
469#endif
470#ifndef HAS_COPYSIGN
471# undef c99_copysign
472#endif
473#ifndef HAS_ERF
474# undef c99_erf
475#endif
476#ifndef HAS_ERFC
477# undef c99_erfc
478#endif
479#ifndef HAS_EXP2
480# undef c99_exp2
481#endif
482#ifndef HAS_EXPM1
483# undef c99_expm1
484#endif
485#ifndef HAS_FDIM
486# undef c99_fdim
487#endif
488#ifndef HAS_FMA
489# undef c99_fma
490#endif
491#ifndef HAS_FMAX
492# undef c99_fmax
493#endif
494#ifndef HAS_FMIN
495# undef c99_fmin
496#endif
497#ifndef HAS_FPCLASSIFY
498# undef c99_fpclassify
499#endif
500#ifndef HAS_HYPOT
501# undef c99_hypot
502#endif
503#ifndef HAS_ILOGB
504# undef c99_ilogb
505#endif
506#ifndef HAS_LGAMMA
507# undef c99_lgamma
508#endif
509#ifndef HAS_LOG1P
510# undef c99_log1p
511#endif
512#ifndef HAS_LOG2
513# undef c99_log2
514#endif
515#ifndef HAS_LOGB
516# undef c99_logb
517#endif
518#ifndef HAS_LRINT
519# undef c99_lrint
520#endif
521#ifndef HAS_LROUND
522# undef c99_lround
523#endif
524#ifndef HAS_NAN
525# undef c99_nan
526#endif
527#ifndef HAS_NEARBYINT
528# undef c99_nearbyint
529#endif
530#ifndef HAS_NEXTAFTER
531# undef c99_nextafter
532#endif
533#ifndef HAS_NEXTTOWARD
534# undef c99_nexttoward
535#endif
536#ifndef HAS_REMAINDER
537# undef c99_remainder
538#endif
539#ifndef HAS_REMQUO
540# undef c99_remquo
541#endif
542#ifndef HAS_RINT
543# undef c99_rint
544#endif
545#ifndef HAS_ROUND
546# undef c99_round
547#endif
548#ifndef HAS_SCALBN
549# undef c99_scalbn
550#endif
551#ifndef HAS_SIGNBIT
552# undef c99_signbit
553#endif
554#ifndef HAS_TGAMMA
555# undef c99_tgamma
556#endif
557#ifndef HAS_TRUNC
558# undef c99_trunc
559#endif
560
bfce4ab3 561#ifdef WIN32
39b5f1c4
JH
562
563/* Some APIs exist under Win32 with "underbar" names. */
564# undef c99_hypot
565# undef c99_logb
566# undef c99_nextafter
567# define c99_hypot _hypot
568# define c99_logb _logb
569# define c99_nextafter _nextafter
570
85c93440
JH
571# define bessel_j0 _j0
572# define bessel_j1 _j1
573# define bessel_jn _jn
574# define bessel_y0 _y0
575# define bessel_y1 _y1
576# define bessel_yn _yn
577
5716d070 578#endif
bfce4ab3 579
39b5f1c4 580/* The Bessel functions: BSD, SVID, XPG4, and POSIX. But not C99. */
05b4a618 581#if defined(HAS_J0) && !defined(bessel_j0)
5716d070
JH
582# if defined(USE_LONG_DOUBLE) && defined(HAS_J0L)
583# define bessel_j0 j0l
584# define bessel_j1 j1l
585# define bessel_jn jnl
586# define bessel_y0 y0l
587# define bessel_y1 y1l
588# define bessel_yn ynl
589# else
85c93440
JH
590# define bessel_j0 j0
591# define bessel_j1 j1
592# define bessel_jn jn
593# define bessel_y0 y0
594# define bessel_y1 y1
595# define bessel_yn yn
5716d070 596# endif
bfce4ab3
JH
597#endif
598
39b5f1c4 599/* Emulations for missing math APIs.
bfce4ab3
JH
600 *
601 * Keep in mind that the point of many of these functions is that
602 * they, if available, are supposed to give more precise/more
39b5f1c4
JH
603 * numerically stable results.
604 *
605 * See e.g. http://www.johndcook.com/math_h.html
606 */
607
39b5f1c4
JH
608#ifndef c99_acosh
609static NV my_acosh(NV x)
610{
611 return Perl_log(x + Perl_sqrt(x * x - 1));
612}
613# define c99_acosh my_acosh
614#endif
615
616#ifndef c99_asinh
617static NV my_asinh(NV x)
618{
619 return Perl_log(x + Perl_sqrt(x * x + 1));
620}
621# define c99_asinh my_asinh
622#endif
623
624#ifndef c99_atanh
625static NV my_atanh(NV x)
626{
627 return (Perl_log(1 + x) - Perl_log(1 - x)) / 2;
628}
629# define c99_atanh my_atanh
630#endif
631
632#ifndef c99_cbrt
633static NV my_cbrt(NV x)
634{
635 static const NV one_third = (NV)1.0/3;
636 return x >= 0.0 ? Perl_pow(x, one_third) : -Perl_pow(-x, one_third);
637}
638# define c99_cbrt my_cbrt
639#endif
640
641#ifndef c99_copysign
642static NV my_copysign(NV x, NV y)
643{
644 return y >= 0 ? (x < 0 ? -x : x) : (x < 0 ? x : -x);
645}
646# define c99_copysign my_copysign
647#endif
648
1ae51000 649/* XXX cosh (though c89) */
d5f4f26a 650
7895eac5
JH
651#ifndef c99_erf
652static NV my_erf(NV x)
653{
654 /* http://www.johndcook.com/cpp_erf.html -- public domain */
655 NV a1 = 0.254829592;
656 NV a2 = -0.284496736;
657 NV a3 = 1.421413741;
658 NV a4 = -1.453152027;
659 NV a5 = 1.061405429;
660 NV p = 0.3275911;
efc74307 661 NV t, y;
7895eac5
JH
662 int sign = x < 0 ? -1 : 1; /* Save the sign. */
663 x = PERL_ABS(x);
664
665 /* Abramowitz and Stegun formula 7.1.26 */
efc74307 666 t = 1.0 / (1.0 + p * x);
6347c79c 667 y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1) * t * Perl_exp(-x*x);
7895eac5
JH
668
669 return sign * y;
670}
671# define c99_erf my_erf
672#endif
673
ffbadafb
JH
674#ifndef c99_erfc
675static NV my_erfc(NV x) {
aed13ba6
JH
676 /* This is not necessarily numerically stable, but better than nothing. */
677 return 1.0 - c99_erf(x);
ffbadafb
JH
678}
679# define c99_erfc my_erfc
680#endif
d5f4f26a 681
39b5f1c4
JH
682#ifndef c99_exp2
683static NV my_exp2(NV x)
684{
685 return Perl_pow((NV)2.0, x);
686}
687# define c99_exp2 my_exp2
688#endif
689
690#ifndef c99_expm1
691static NV my_expm1(NV x)
692{
693 if (PERL_ABS(x) < 1e-5)
7895eac5 694 /* http://www.johndcook.com/cpp_expm1.html -- public domain.
2783359f 695 * Taylor series, the first four terms (the last term quartic). */
39b5f1c4 696 /* Probably not enough for long doubles. */
2783359f 697 return x * (1.0 + x * (1/2.0 + x * (1/6.0 + x/24.0)));
39b5f1c4
JH
698 else
699 return Perl_exp(x) - 1;
700}
701# define c99_expm1 my_expm1
702#endif
703
704#ifndef c99_fdim
705static NV my_fdim(NV x, NV y)
706{
eaa53991 707 return (Perl_isnan(x) || Perl_isnan(y)) ? NV_NAN : (x > y ? x - y : 0);
39b5f1c4
JH
708}
709# define c99_fdim my_fdim
710#endif
711
7678a27f
JH
712#ifndef c99_fma
713static NV my_fma(NV x, NV y, NV z)
714{
715 return (x * y) + z;
716}
717# define c99_fma my_fma
718#endif
719
39b5f1c4
JH
720#ifndef c99_fmax
721static NV my_fmax(NV x, NV y)
722{
723 if (Perl_isnan(x)) {
724 return Perl_isnan(y) ? NV_NAN : y;
725 } else if (Perl_isnan(y)) {
726 return x;
727 }
728 return x > y ? x : y;
729}
730# define c99_fmax my_fmax
731#endif
732
733#ifndef c99_fmin
734static NV my_fmin(NV x, NV y)
735{
736 if (Perl_isnan(x)) {
737 return Perl_isnan(y) ? NV_NAN : y;
738 } else if (Perl_isnan(y)) {
739 return x;
740 }
741 return x < y ? x : y;
742}
743# define c99_fmin my_fmin
744#endif
745
26e0f0d3
JH
746#ifndef c99_fpclassify
747
ea464252 748static IV my_fpclassify(NV x)
935e3c48 749{
c3607571 750#ifdef Perl_fp_class_inf
935e3c48
JH
751 if (Perl_fp_class_inf(x)) return FP_INFINITE;
752 if (Perl_fp_class_nan(x)) return FP_NAN;
753 if (Perl_fp_class_norm(x)) return FP_NORMAL;
754 if (Perl_fp_class_denorm(x)) return FP_SUBNORMAL;
755 if (Perl_fp_class_zero(x)) return FP_ZERO;
935e3c48
JH
756# define c99_fpclassify my_fpclassify
757#endif
c3607571 758 return -1;
935e3c48 759}
935e3c48 760
26e0f0d3
JH
761#endif
762
39b5f1c4
JH
763#ifndef c99_hypot
764static NV my_hypot(NV x, NV y)
765{
7bbf2c9b
JH
766 /* http://en.wikipedia.org/wiki/Hypot */
767 NV t;
768 x = PERL_ABS(x); /* Take absolute values. */
769 if (y == 0)
770 return x;
771 if (Perl_isnan(y))
772 return NV_INF;
773 y = PERL_ABS(y);
774 if (x < y) { /* Swap so that y is less. */
775 t = x;
776 x = y;
777 y = t;
39b5f1c4 778 }
7bbf2c9b 779 t = y / x;
6347c79c 780 return x * Perl_sqrt(1.0 + t * t);
39b5f1c4
JH
781}
782# define c99_hypot my_hypot
783#endif
784
785#ifndef c99_ilogb
786static IV my_ilogb(NV x)
787{
788 return (IV)(Perl_log(x) * M_LOG2E);
789}
790# define c99_ilogb my_ilogb
791#endif
792
8e65ef33
JH
793/* tgamma and lgamma emulations based on
794 * http://www.johndcook.com/cpp_gamma.html,
2e9cdb62
JH
795 * code placed in public domain.
796 *
797 * Note that these implementations (neither the johndcook originals
798 * nor these) do NOT set the global signgam variable. This is not
799 * necessarily a bad thing. */
800
8e65ef33
JH
801/* Note that the tgamma() and lgamma() implementations
802 * here depend on each other. */
256fef93 803
dc7cecfb 804#if !defined(HAS_TGAMMA) || !defined(c99_tgamma)
2e9cdb62 805static NV my_tgamma(NV x);
256fef93 806# define c99_tgamma my_tgamma
dc7cecfb 807# define USE_MY_TGAMMA
256fef93 808#endif
dc7cecfb 809#if !defined(HAS_LGAMMA) || !defined(c99_lgamma)
2e9cdb62 810static NV my_lgamma(NV x);
256fef93 811# define c99_lgamma my_lgamma
dc7cecfb 812# define USE_MY_LGAMMA
2e9cdb62
JH
813#endif
814
dc7cecfb 815#ifdef USE_MY_TGAMMA
2e9cdb62
JH
816static NV my_tgamma(NV x)
817{
f5802bf0 818 const NV gamma = 0.577215664901532860606512090; /* Euler's gamma constant. */
2e9cdb62
JH
819 if (Perl_isnan(x) || x < 0.0)
820 return NV_NAN;
821 if (x == 0.0 || x == NV_INF)
822 return x == -0.0 ? -NV_INF : NV_INF;
823
824 /* The function domain is split into three intervals:
825 * (0, 0.001), [0.001, 12), and (12, infinity) */
826
827 /* First interval: (0, 0.001)
f5802bf0 828 * For small values, 1/tgamma(x) has power series x + gamma x^2,
2e9cdb62
JH
829 * so in this range, 1/tgamma(x) = x + gamma x^2 with error on the order of x^3.
830 * The relative error over this interval is less than 6e-7. */
831 if (x < 0.001)
832 return 1.0 / (x * (1.0 + gamma * x));
833
834 /* Second interval: [0.001, 12) */
835 if (x < 12.0) {
836 double y = x; /* Working copy. */
837 int n = 0;
838 /* Numerator coefficients for approximation over the interval (1,2) */
839 static const NV p[] = {
840 -1.71618513886549492533811E+0,
841 2.47656508055759199108314E+1,
842 -3.79804256470945635097577E+2,
843 6.29331155312818442661052E+2,
844 8.66966202790413211295064E+2,
845 -3.14512729688483675254357E+4,
846 -3.61444134186911729807069E+4,
847 6.64561438202405440627855E+4
848 };
849 /* Denominator coefficients for approximation over the interval (1, 2) */
850 static const NV q[] = {
851 -3.08402300119738975254353E+1,
852 3.15350626979604161529144E+2,
853 -1.01515636749021914166146E+3,
854 -3.10777167157231109440444E+3,
855 2.25381184209801510330112E+4,
856 4.75584627752788110767815E+3,
857 -1.34659959864969306392456E+5,
858 -1.15132259675553483497211E+5
859 };
860 NV num = 0.0;
861 NV den = 1.0;
862 NV z;
863 NV result;
864 int i;
865
866 if (x < 1.0)
867 y += 1.0;
868 else {
5306a04c 869 n = (int)Perl_floor(y) - 1;
2e9cdb62
JH
870 y -= n;
871 }
872 z = y - 1;
873 for (i = 0; i < 8; i++) {
874 num = (num + p[i]) * z;
875 den = den * z + q[i];
876 }
877 result = num / den + 1.0;
878
879 if (x < 1.0) {
880 /* Use the identity tgamma(z) = tgamma(z+1)/z
881 * The variable "result" now holds tgamma of the original y + 1
882 * Thus we use y - 1 to get back the original y. */
883 result /= (y - 1.0);
884 }
885 else {
886 /* Use the identity tgamma(z+n) = z*(z+1)* ... *(z+n-1)*tgamma(z) */
887 for (i = 0; i < n; i++)
888 result *= y++;
889 }
890
891 return result;
892 }
893
894 /* Third interval: [12, +Inf) */
ec7c51d0
JH
895#if LDBL_MANT_DIG == 113 /* IEEE quad prec */
896 if (x > 1755.548) {
2e9cdb62
JH
897 return NV_INF;
898 }
ec7c51d0
JH
899#else
900 if (x > 171.624) {
901 return NV_INF;
902 }
903#endif
2e9cdb62 904
256fef93 905 return Perl_exp(c99_lgamma(x));
2e9cdb62 906}
2e9cdb62
JH
907#endif
908
dc7cecfb 909#ifdef USE_MY_LGAMMA
2e9cdb62
JH
910static NV my_lgamma(NV x)
911{
912 if (Perl_isnan(x))
913 return NV_NAN;
914 if (x <= 0 || x == NV_INF)
915 return NV_INF;
916 if (x == 1.0 || x == 2.0)
917 return 0;
918 if (x < 12.0)
256fef93 919 return Perl_log(PERL_ABS(c99_tgamma(x)));
f5802bf0
JH
920 /* Abramowitz and Stegun 6.1.41
921 * Asymptotic series should be good to at least 11 or 12 figures
922 * For error analysis, see Whittiker and Watson
923 * A Course in Modern Analysis (1927), page 252 */
2e9cdb62
JH
924 {
925 static const NV c[8] = {
926 1.0/12.0,
927 -1.0/360.0,
928 1.0/1260.0,
929 -1.0/1680.0,
930 1.0/1188.0,
931 -691.0/360360.0,
932 1.0/156.0,
933 -3617.0/122400.0
934 };
935 NV z = 1.0 / (x * x);
936 NV sum = c[7];
937 static const NV half_log_of_two_pi =
938 0.91893853320467274178032973640562;
939 NV series;
940 int i;
941 for (i = 6; i >= 0; i--) {
942 sum *= z;
943 sum += c[i];
944 }
945 series = sum / x;
946 return (x - 0.5) * Perl_log(x) - x + half_log_of_two_pi + series;
947 }
948}
2e9cdb62 949#endif
d5f4f26a 950
39b5f1c4
JH
951#ifndef c99_log1p
952static NV my_log1p(NV x)
953{
7895eac5 954 /* http://www.johndcook.com/cpp_log_one_plus_x.html -- public domain.
2783359f 955 * Taylor series, the first four terms (the last term quartic). */
3ae4cd6c 956 if (x < -1.0)
731a2bdb 957 return NV_NAN;
3ae4cd6c
JH
958 if (x == -1.0)
959 return -NV_INF;
39b5f1c4
JH
960 if (PERL_ABS(x) > 1e-4)
961 return Perl_log(1.0 + x);
962 else
963 /* Probably not enough for long doubles. */
2783359f 964 return x * (1.0 + x * (-1/2.0 + x * (1/3.0 - x/4.0)));
39b5f1c4
JH
965}
966# define c99_log1p my_log1p
967#endif
968
969#ifndef c99_log2
970static NV my_log2(NV x)
971{
972 return Perl_log(x) * M_LOG2E;
973}
974# define c99_log2 my_log2
975#endif
976
d5f4f26a
JH
977/* XXX nextafter */
978
979/* XXX nexttoward */
980
981static int my_fegetround()
982{
983#ifdef HAS_FEGETROUND
984 return fegetround();
e0939537
JH
985#elif defined(HAS_FPGETROUND)
986 switch (fpgetround()) {
e0939537
JH
987 case FP_RN: return FE_TONEAREST;
988 case FP_RZ: return FE_TOWARDZERO;
989 case FP_RM: return FE_DOWNWARD;
cc639810 990 case FP_RP: return FE_UPWARD;
9d491117 991 default: return -1;
e0939537 992 }
c35bb41d
JH
993#elif defined(FLT_ROUNDS)
994 switch (FLT_ROUNDS) {
c35bb41d 995 case 0: return FE_TOWARDZERO;
ebac59ac
JH
996 case 1: return FE_TONEAREST;
997 case 2: return FE_UPWARD;
998 case 3: return FE_DOWNWARD;
c35bb41d
JH
999 default: return -1;
1000 }
877206df
JH
1001#elif defined(__osf__) /* Tru64 */
1002 switch (read_rnd()) {
1003 case FP_RND_RN: return FE_TONEAREST;
1004 case FP_RND_RZ: return FE_TOWARDZERO;
1005 case FP_RND_RM: return FE_DOWNWARD;
1006 case FP_RND_RP: return FE_UPWARD;
1007 default: return -1;
1008 }
d5f4f26a
JH
1009#else
1010 return -1;
1011#endif
1012}
1013
c4125715
JH
1014/* Toward closest integer. */
1015#define MY_ROUND_NEAREST(x) ((NV)((IV)((x) >= 0.0 ? (x) + 0.5 : (x) - 0.5)))
1016
1017/* Toward zero. */
1018#define MY_ROUND_TRUNC(x) ((NV)((IV)(x)))
1019
e0939537 1020/* Toward minus infinity. */
c4125715 1021#define MY_ROUND_DOWN(x) ((NV)((IV)((x) >= 0.0 ? (x) : (x) - 0.5)))
e0939537
JH
1022
1023/* Toward plus infinity. */
c4125715 1024#define MY_ROUND_UP(x) ((NV)((IV)((x) >= 0.0 ? (x) + 0.5 : (x))))
e0939537 1025
5a4dabf8 1026#if (!defined(c99_nearbyint) || !defined(c99_lrint)) && defined(FE_TONEAREST)
d5f4f26a
JH
1027static NV my_rint(NV x)
1028{
1029#ifdef FE_TONEAREST
1030 switch (my_fegetround()) {
c4125715
JH
1031 case FE_TONEAREST: return MY_ROUND_NEAREST(x);
1032 case FE_TOWARDZERO: return MY_ROUND_TRUNC(x);
1033 case FE_DOWNWARD: return MY_ROUND_DOWN(x);
1034 case FE_UPWARD: return MY_ROUND_UP(x);
9d491117 1035 default: return NV_NAN;
e0939537
JH
1036 }
1037#elif defined(HAS_FPGETROUND)
1038 switch (fpgetround()) {
c4125715
JH
1039 case FP_RN: return MY_ROUND_NEAREST(x);
1040 case FP_RZ: return MY_ROUND_TRUNC(x);
1041 case FP_RM: return MY_ROUND_DOWN(x);
1042 case FE_RP: return MY_ROUND_UP(x);
9d491117 1043 default: return NV_NAN;
d5f4f26a
JH
1044 }
1045#else
1046 return NV_NAN;
1047#endif
1048}
5a4dabf8 1049#endif
d5f4f26a
JH
1050
1051/* XXX nearbyint() and rint() are not really identical -- but the difference
1052 * is messy: nearbyint is defined NOT to raise FE_INEXACT floating point
1053 * exceptions, while rint() is defined to MAYBE raise them. At the moment
1054 * Perl is blissfully unaware of such fine detail of floating point. */
1055#ifndef c99_nearbyint
1056# ifdef FE_TONEAREST
1057# define c99_nearbyrint my_rint
1058# endif
1059#endif
1060
1061#ifndef c99_lrint
1062# ifdef FE_TONEAREST
c40e90c4 1063static IV my_lrint(NV x)
d5f4f26a
JH
1064{
1065 return (IV)my_rint(x);
1066}
1067# define c99_lrint my_lrint
1068# endif
1069#endif
1070
9e010b89
JH
1071#ifndef c99_lround
1072static IV my_lround(NV x)
1073{
c63c00af 1074 return (IV)MY_ROUND_NEAREST(x);
9e010b89
JH
1075}
1076# define c99_lround my_lround
1077#endif
1078
d5f4f26a
JH
1079/* XXX remainder */
1080
1081/* XXX remquo */
1082
1083#ifndef c99_rint
1084# ifdef FE_TONEAREST
1085# define c99_rint my_rint
1086# endif
1087#endif
1088
39b5f1c4
JH
1089#ifndef c99_round
1090static NV my_round(NV x)
1091{
c4125715 1092 return MY_ROUND_NEAREST(x);
39b5f1c4
JH
1093}
1094# define c99_round my_round
1095#endif
1096
1097#ifndef c99_scalbn
93ddb856 1098# if defined(Perl_ldexp) && FLT_RADIX == 2
ea464252 1099static NV my_scalbn(NV x, int y)
39b5f1c4
JH
1100{
1101 return Perl_ldexp(x, y);
1102}
1103# define c99_scalbn my_scalbn
1104# endif
1105#endif
1106
1ae51000 1107/* XXX sinh (though c89) */
39b5f1c4 1108
2e9cdb62 1109/* tgamma -- see lgamma */
bfce4ab3 1110
1ae51000 1111/* XXX tanh (though c89) */
d5f4f26a
JH
1112
1113#ifndef c99_trunc
1114static NV my_trunc(NV x)
1115{
c4125715 1116 return MY_ROUND_TRUNC(x);
d5f4f26a
JH
1117}
1118# define c99_trunc my_trunc
1119#endif
1120
07bb61ac
JH
1121#undef NV_PAYLOAD_DEBUG
1122
1123/* NOTE: the NaN payload API implementation is hand-rolled, since the
1124 * APIs are only proposed ones as of June 2015, so very few, if any,
1125 * platforms have implementations yet, so HAS_SETPAYLOAD and such are
1126 * unlikely to be helpful.
1127 *
1128 * XXX - if the core numification wants to actually generate
1129 * the nan payload in "nan(123)", and maybe "nans(456)", for
1130 * signaling payload", this needs to be moved to e.g. numeric.c
1131 * (look for grok_infnan)
1132 *
1133 * Conversely, if the core stringification wants the nan payload
1134 * and/or the nan quiet/signaling distinction, S_getpayload()
1135 * from this file needs to be moved, to e.g. sv.c (look for S_infnan_2pv),
1136 * and the (trivial) functionality of issignaling() copied
1137 * (for generating "NaNS", or maybe even "NaNQ") -- or maybe there
1138 * are too many formatting parameters for simple stringification?
1139 */
1140
1141/* While it might make sense for the payload to be UV or IV,
1142 * to avoid conversion loss, the proposed ISO interfaces use
1143 * a floating point input, which is then truncated to integer,
1144 * and only the integer part being used. This is workable,
1145 * except for: (1) the conversion loss (2) suboptimal for
1146 * 32-bit integer platforms. A workaround API for (2) and
1147 * in general for bit-honesty would be an array of integers
1148 * as the payload... but the proposed C API does nothing of
1149 * the kind. */
1150#if NVSIZE == UVSIZE
1151# define NV_PAYLOAD_TYPE UV
1152#else
1153# define NV_PAYLOAD_TYPE NV
1154#endif
1155
d80a6052 1156#if defined(USE_LONG_DOUBLE) && defined(LONGDOUBLE_DOUBLEDOUBLE)
07bb61ac
JH
1157# define NV_PAYLOAD_SIZEOF_ASSERT(a) assert(sizeof(a) == NVSIZE / 2)
1158#else
1159# define NV_PAYLOAD_SIZEOF_ASSERT(a) assert(sizeof(a) == NVSIZE)
1160#endif
1161
1162static void S_setpayload(NV* nvp, NV_PAYLOAD_TYPE payload, bool signaling)
1163{
1164 dTHX;
1165 static const U8 m[] = { NV_NAN_PAYLOAD_MASK };
1166 static const U8 p[] = { NV_NAN_PAYLOAD_PERM };
1167 UV a[(NVSIZE + UVSIZE - 1) / UVSIZE] = { 0 };
1168 int i;
1169 NV_PAYLOAD_SIZEOF_ASSERT(m);
1170 NV_PAYLOAD_SIZEOF_ASSERT(p);
1171 *nvp = NV_NAN;
1172 /* Divide the input into the array in "base unsigned integer" in
1173 * little-endian order. Note that the integer might be smaller than
1174 * an NV (if UV is U32, for example). */
1175#if NVSIZE == UVSIZE
1176 a[0] = payload; /* The trivial case. */
1177#else
1178 {
1179 NV t1 = c99_trunc(payload); /* towards zero (drop fractional) */
1180#ifdef NV_PAYLOAD_DEBUG
1181 Perl_warn(aTHX_ "t1 = %"NVgf" (payload %"NVgf")\n", t1, payload);
1182#endif
1183 if (t1 <= UV_MAX) {
1184 a[0] = (UV)t1; /* Fast path, also avoids rounding errors (right?) */
1185 } else {
1186 /* UVSIZE < NVSIZE or payload > UV_MAX.
1187 *
1188 * This may happen for example if:
1189 * (1) UVSIZE == 32 and common 64-bit double NV
1190 * (32-bit system not using -Duse64bitint)
1191 * (2) UVSIZE == 64 and the x86-style 80-bit long double NV
1192 * (note that here the room for payload is actually the 64 bits)
1193 * (3) UVSIZE == 64 and the 128-bit IEEE 764 quadruple NV
1194 * (112 bits in mantissa, 111 bits room for payload)
1195 *
1196 * NOTE: this is very sensitive to correctly functioning
1197 * fmod()/fmodl(), and correct casting of big-unsigned-integer to NV.
1198 * If these don't work right, especially the low order bits
1199 * are in danger. For example Solaris and AIX seem to have issues
1200 * here, especially if using 32-bit UVs. */
1201 NV t2;
1202 for (i = 0, t2 = t1; i < (int)C_ARRAY_LENGTH(a); i++) {
1203 a[i] = (UV)Perl_fmod(t2, (NV)UV_MAX);
1204 t2 = Perl_floor(t2 / (NV)UV_MAX);
1205 }
1206 }
1207 }
1208#endif
1209#ifdef NV_PAYLOAD_DEBUG
1210 for (i = 0; i < (int)C_ARRAY_LENGTH(a); i++) {
1211 Perl_warn(aTHX_ "a[%d] = 0x%"UVxf"\n", i, a[i]);
1212 }
1213#endif
1214 for (i = 0; i < (int)sizeof(p); i++) {
1215 if (m[i] && p[i] < sizeof(p)) {
1216 U8 s = (p[i] % UVSIZE) << 3;
1217 UV u = a[p[i] / UVSIZE] & ((UV)0xFF << s);
1218 U8 b = (U8)((u >> s) & m[i]);
1219 ((U8 *)(nvp))[i] &= ~m[i]; /* For NaNs with non-zero payload bits. */
1220 ((U8 *)(nvp))[i] |= b;
1221#ifdef NV_PAYLOAD_DEBUG
1222 Perl_warn(aTHX_ "set p[%2d] = %02x (i = %d, m = %02x, s = %2d, b = %02x, u = %08"UVxf")\n", i, ((U8 *)(nvp))[i], i, m[i], s, b, u);
1223#endif
1224 a[p[i] / UVSIZE] &= ~u;
1225 }
1226 }
1227 if (signaling) {
1228 NV_NAN_SET_SIGNALING(nvp);
1229 }
1230#ifdef USE_LONG_DOUBLE
1231# if LONG_DOUBLEKIND == 3 || LONG_DOUBLEKIND == 4
2f125fcc 1232# if LONG_DOUBLESIZE > 10
07bb61ac 1233 memset((char *)nvp + 10, '\0', LONG_DOUBLESIZE - 10); /* x86 long double */
2f125fcc 1234# endif
07bb61ac
JH
1235# endif
1236#endif
1237 for (i = 0; i < (int)C_ARRAY_LENGTH(a); i++) {
1238 if (a[i]) {
1239 Perl_warn(aTHX_ "payload lost bits (%"UVxf")", a[i]);
1240 break;
1241 }
1242 }
1243#ifdef NV_PAYLOAD_DEBUG
1244 for (i = 0; i < NVSIZE; i++) {
1245 PerlIO_printf(Perl_debug_log, "%02x ", ((U8 *)(nvp))[i]);
1246 }
1247 PerlIO_printf(Perl_debug_log, "\n");
1248#endif
1249}
1250
1251static NV_PAYLOAD_TYPE S_getpayload(NV nv)
1252{
1253 dTHX;
1254 static const U8 m[] = { NV_NAN_PAYLOAD_MASK };
1255 static const U8 p[] = { NV_NAN_PAYLOAD_PERM };
1256 UV a[(NVSIZE + UVSIZE - 1) / UVSIZE] = { 0 };
1257 int i;
1258 NV payload;
1259 NV_PAYLOAD_SIZEOF_ASSERT(m);
1260 NV_PAYLOAD_SIZEOF_ASSERT(p);
1261 payload = 0;
1262 for (i = 0; i < (int)sizeof(p); i++) {
1263 if (m[i] && p[i] < NVSIZE) {
1264 U8 s = (p[i] % UVSIZE) << 3;
1265 a[p[i] / UVSIZE] |= (UV)(((U8 *)(&nv))[i] & m[i]) << s;
1266 }
1267 }
1268 for (i = (int)C_ARRAY_LENGTH(a) - 1; i >= 0; i--) {
1269#ifdef NV_PAYLOAD_DEBUG
1270 Perl_warn(aTHX_ "a[%d] = %"UVxf"\n", i, a[i]);
1271#endif
1272 payload *= UV_MAX;
1273 payload += a[i];
1274 }
1275#ifdef NV_PAYLOAD_DEBUG
1276 for (i = 0; i < NVSIZE; i++) {
1277 PerlIO_printf(Perl_debug_log, "%02x ", ((U8 *)(&nv))[i]);
1278 }
1279 PerlIO_printf(Perl_debug_log, "\n");
1280#endif
1281 return payload;
1282}
1283
3609ea0d 1284/* XXX This comment is just to make I_TERMIO and I_SGTTY visible to
a0d0e21e
LW
1285 metaconfig for future extension writers. We don't use them in POSIX.
1286 (This is really sneaky :-) --AD
1287*/
1288#if defined(I_TERMIOS)
1289#include <termios.h>
1290#endif
a0d0e21e 1291#ifdef I_STDLIB
2304df62 1292#include <stdlib.h>
a0d0e21e 1293#endif
5518ecd4 1294#ifndef __ultrix__
2304df62 1295#include <string.h>
5518ecd4 1296#endif
2304df62 1297#include <sys/stat.h>
2304df62 1298#include <sys/types.h>
2304df62 1299#include <time.h>
6dead956 1300#ifdef I_UNISTD
1d2dff63 1301#include <unistd.h>
6dead956 1302#endif
71be2cbc 1303#include <fcntl.h>
1304
e2465f50 1305#ifdef HAS_TZNAME
fb207d52 1306# if !defined(WIN32) && !defined(__CYGWIN__) && !defined(NETWARE) && !defined(__UWIN__)
e2465f50
JH
1307extern char *tzname[];
1308# endif
1309#else
fb207d52 1310#if !defined(WIN32) && !defined(__UWIN__) || (defined(__MINGW32__) && !defined(tzname))
e2465f50
JH
1311char *tzname[] = { "" , "" };
1312#endif
cb2479a8
JH
1313#endif
1314
6c418a22 1315#if defined(__VMS) && !defined(__POSIX_SOURCE)
294c8bc4
CB
1316
1317# include <utsname.h>
6c418a22 1318
6990d991 1319# undef mkfifo
6c418a22 1320# define mkfifo(a,b) (not_here("mkfifo"),-1)
6c418a22 1321
1322 /* The POSIX notion of ttyname() is better served by getname() under VMS */
1323 static char ttnambuf[64];
1324# define ttyname(fd) (isatty(fd) > 0 ? getname(fd,ttnambuf,0) : NULL)
1325
6c418a22 1326#else
d308986b 1327#if defined (__CYGWIN__)
f89d6eaa
EF
1328# define tzname _tzname
1329#endif
2986a63f 1330#if defined (WIN32) || defined (NETWARE)
6990d991 1331# undef mkfifo
6dead956 1332# define mkfifo(a,b) not_here("mkfifo")
873ef191 1333# define ttyname(a) (char*)not_here("ttyname")
6dead956 1334# define sigset_t long
86200d5c 1335# define pid_t long
6dead956
GS
1336# ifdef _MSC_VER
1337# define mode_t short
1338# endif
62520c91
GS
1339# ifdef __MINGW32__
1340# define mode_t short
f6c6487a
GS
1341# ifndef tzset
1342# define tzset() not_here("tzset")
1343# endif
1344# ifndef _POSIX_OPEN_MAX
1345# define _POSIX_OPEN_MAX FOPEN_MAX /* XXX bogus ? */
1346# endif
62520c91 1347# endif
6dead956
GS
1348# define sigaction(a,b,c) not_here("sigaction")
1349# define sigpending(a) not_here("sigpending")
1350# define sigprocmask(a,b,c) not_here("sigprocmask")
1351# define sigsuspend(a) not_here("sigsuspend")
1352# define sigemptyset(a) not_here("sigemptyset")
1353# define sigaddset(a,b) not_here("sigaddset")
1354# define sigdelset(a,b) not_here("sigdelset")
1355# define sigfillset(a) not_here("sigfillset")
1356# define sigismember(a,b) not_here("sigismember")
2986a63f 1357#ifndef NETWARE
6e22d046
JH
1358# undef setuid
1359# undef setgid
2986a63f
JH
1360# define setuid(a) not_here("setuid")
1361# define setgid(a) not_here("setgid")
1362#endif /* NETWARE */
d172007e 1363#ifndef USE_LONG_DOUBLE
73e21afd 1364# define strtold(s1,s2) not_here("strtold")
d172007e 1365#endif /* USE_LONG_DOUBLE */
6dead956 1366#else
6990d991
JH
1367
1368# ifndef HAS_MKFIFO
b3599c2e 1369# if defined(OS2) || defined(__amigaos4__)
d6a255e6 1370# define mkfifo(a,b) not_here("mkfifo")
3609ea0d 1371# else /* !( defined OS2 ) */
d6a255e6
IZ
1372# ifndef mkfifo
1373# define mkfifo(path, mode) (mknod((path), (mode) | S_IFIFO, 0))
1374# endif
6990d991
JH
1375# endif
1376# endif /* !HAS_MKFIFO */
1377
e37778c2
NC
1378# ifdef I_GRP
1379# include <grp.h>
1380# endif
1381# include <sys/times.h>
1382# ifdef HAS_UNAME
1383# include <sys/utsname.h>
6c418a22 1384# endif
ea34f6bd
AB
1385# ifndef __amigaos4__
1386# include <sys/wait.h>
1387# endif
6c418a22 1388# ifdef I_UTIME
1389# include <utime.h>
1390# endif
2986a63f 1391#endif /* WIN32 || NETWARE */
6dead956 1392#endif /* __VMS */
2304df62
AD
1393
1394typedef int SysRet;
a0d0e21e 1395typedef long SysRetLong;
2304df62
AD
1396typedef sigset_t* POSIX__SigSet;
1397typedef HV* POSIX__SigAction;
69b5fd06 1398typedef int POSIX__SigNo;
ddc7c5c7 1399typedef int POSIX__Fd;
a0d0e21e
LW
1400#ifdef I_TERMIOS
1401typedef struct termios* POSIX__Termios;
1402#else /* Define termios types to int, and call not_here for the functions.*/
1403#define POSIX__Termios int
1404#define speed_t int
1405#define tcflag_t int
1406#define cc_t int
1407#define cfgetispeed(x) not_here("cfgetispeed")
1408#define cfgetospeed(x) not_here("cfgetospeed")
1409#define tcdrain(x) not_here("tcdrain")
1410#define tcflush(x,y) not_here("tcflush")
1411#define tcsendbreak(x,y) not_here("tcsendbreak")
1412#define cfsetispeed(x,y) not_here("cfsetispeed")
1413#define cfsetospeed(x,y) not_here("cfsetospeed")
1414#define ctermid(x) (char *) not_here("ctermid")
1415#define tcflow(x,y) not_here("tcflow")
1416#define tcgetattr(x,y) not_here("tcgetattr")
1417#define tcsetattr(x,y,z) not_here("tcsetattr")
1418#endif
1419
1420/* Possibly needed prototypes */
6e22d046 1421#ifndef WIN32
a2e65780 1422START_EXTERN_C
20ce7b12
GS
1423double strtod (const char *, char **);
1424long strtol (const char *, char **, int);
1425unsigned long strtoul (const char *, char **, int);
0ff7b9da
JH
1426#ifdef HAS_STRTOLD
1427long double strtold (const char *, char **);
1428#endif
a2e65780 1429END_EXTERN_C
6e22d046 1430#endif
a0d0e21e 1431
a0d0e21e
LW
1432#ifndef HAS_DIFFTIME
1433#ifndef difftime
1434#define difftime(a,b) not_here("difftime")
1435#endif
1436#endif
1437#ifndef HAS_FPATHCONF
3609ea0d 1438#define fpathconf(f,n) (SysRetLong) not_here("fpathconf")
a0d0e21e
LW
1439#endif
1440#ifndef HAS_MKTIME
1441#define mktime(a) not_here("mktime")
8990e307
LW
1442#endif
1443#ifndef HAS_NICE
1444#define nice(a) not_here("nice")
1445#endif
a0d0e21e 1446#ifndef HAS_PATHCONF
3609ea0d 1447#define pathconf(f,n) (SysRetLong) not_here("pathconf")
a0d0e21e
LW
1448#endif
1449#ifndef HAS_SYSCONF
3609ea0d 1450#define sysconf(n) (SysRetLong) not_here("sysconf")
a0d0e21e 1451#endif
8990e307
LW
1452#ifndef HAS_READLINK
1453#define readlink(a,b,c) not_here("readlink")
1454#endif
1455#ifndef HAS_SETPGID
1456#define setpgid(a,b) not_here("setpgid")
1457#endif
8990e307
LW
1458#ifndef HAS_SETSID
1459#define setsid() not_here("setsid")
1460#endif
a0d0e21e
LW
1461#ifndef HAS_STRCOLL
1462#define strcoll(s1,s2) not_here("strcoll")
1463#endif
a89d8a78
DH
1464#ifndef HAS_STRTOD
1465#define strtod(s1,s2) not_here("strtod")
1466#endif
0ff7b9da
JH
1467#ifndef HAS_STRTOLD
1468#define strtold(s1,s2) not_here("strtold")
1469#endif
a89d8a78
DH
1470#ifndef HAS_STRTOL
1471#define strtol(s1,s2,b) not_here("strtol")
1472#endif
1473#ifndef HAS_STRTOUL
1474#define strtoul(s1,s2,b) not_here("strtoul")
1475#endif
a0d0e21e
LW
1476#ifndef HAS_STRXFRM
1477#define strxfrm(s1,s2,n) not_here("strxfrm")
8990e307
LW
1478#endif
1479#ifndef HAS_TCGETPGRP
1480#define tcgetpgrp(a) not_here("tcgetpgrp")
1481#endif
1482#ifndef HAS_TCSETPGRP
1483#define tcsetpgrp(a,b) not_here("tcsetpgrp")
1484#endif
1485#ifndef HAS_TIMES
2986a63f 1486#ifndef NETWARE
8990e307 1487#define times(a) not_here("times")
2986a63f 1488#endif /* NETWARE */
8990e307
LW
1489#endif
1490#ifndef HAS_UNAME
1491#define uname(a) not_here("uname")
1492#endif
1493#ifndef HAS_WAITPID
1494#define waitpid(a,b,c) not_here("waitpid")
1495#endif
1496
a0d0e21e
LW
1497#ifndef HAS_MBLEN
1498#ifndef mblen
1499#define mblen(a,b) not_here("mblen")
1500#endif
1501#endif
1502#ifndef HAS_MBSTOWCS
1503#define mbstowcs(s, pwcs, n) not_here("mbstowcs")
1504#endif
1505#ifndef HAS_MBTOWC
1506#define mbtowc(pwc, s, n) not_here("mbtowc")
1507#endif
1508#ifndef HAS_WCSTOMBS
1509#define wcstombs(s, pwcs, n) not_here("wcstombs")
1510#endif
1511#ifndef HAS_WCTOMB
1512#define wctomb(s, wchar) not_here("wcstombs")
1513#endif
1514#if !defined(HAS_MBLEN) && !defined(HAS_MBSTOWCS) && !defined(HAS_MBTOWC) && !defined(HAS_WCSTOMBS) && !defined(HAS_WCTOMB)
1515/* If we don't have these functions, then we wouldn't have gotten a typedef
1516 for wchar_t, the wide character type. Defining wchar_t allows the
1517 functions referencing it to compile. Its actual type is then meaningless,
1518 since without the above functions, all sections using it end up calling
1519 not_here() and croak. --Kaveh Ghazi (ghazi@noc.rutgers.edu) 9/18/94. */
1520#ifndef wchar_t
1521#define wchar_t char
1522#endif
1523#endif
1524
3f3bcbfc
KW
1525#ifndef HAS_LOCALECONV
1526# define localeconv() not_here("localeconv")
1527#else
2f0945cb
NC
1528struct lconv_offset {
1529 const char *name;
1530 size_t offset;
1531};
1532
0b057af7 1533static const struct lconv_offset lconv_strings[] = {
03ceeedf 1534#ifdef USE_LOCALE_NUMERIC
3800c318
JH
1535 {"decimal_point", STRUCT_OFFSET(struct lconv, decimal_point)},
1536 {"thousands_sep", STRUCT_OFFSET(struct lconv, thousands_sep)},
03ceeedf 1537# ifndef NO_LOCALECONV_GROUPING
3800c318 1538 {"grouping", STRUCT_OFFSET(struct lconv, grouping)},
03ceeedf 1539# endif
2f0945cb 1540#endif
03ceeedf 1541#ifdef USE_LOCALE_MONETARY
3800c318
JH
1542 {"int_curr_symbol", STRUCT_OFFSET(struct lconv, int_curr_symbol)},
1543 {"currency_symbol", STRUCT_OFFSET(struct lconv, currency_symbol)},
1544 {"mon_decimal_point", STRUCT_OFFSET(struct lconv, mon_decimal_point)},
03ceeedf 1545# ifndef NO_LOCALECONV_MON_THOUSANDS_SEP
3800c318 1546 {"mon_thousands_sep", STRUCT_OFFSET(struct lconv, mon_thousands_sep)},
03ceeedf
KW
1547# endif
1548# ifndef NO_LOCALECONV_MON_GROUPING
3800c318 1549 {"mon_grouping", STRUCT_OFFSET(struct lconv, mon_grouping)},
03ceeedf 1550# endif
3800c318
JH
1551 {"positive_sign", STRUCT_OFFSET(struct lconv, positive_sign)},
1552 {"negative_sign", STRUCT_OFFSET(struct lconv, negative_sign)},
03ceeedf 1553#endif
2f0945cb
NC
1554 {NULL, 0}
1555};
1556
c1284011
KW
1557#ifdef USE_LOCALE_NUMERIC
1558
1559/* The Linux man pages say these are the field names for the structure
1560 * components that are LC_NUMERIC; the rest being LC_MONETARY */
f33b12f3
JH
1561# define isLC_NUMERIC_STRING(name) (strEQ(name, "decimal_point") \
1562 || strEQ(name, "thousands_sep") \
c1284011
KW
1563 \
1564 /* There should be no harm done \
1565 * checking for this, even if \
1566 * NO_LOCALECONV_GROUPING */ \
f33b12f3 1567 || strEQ(name, "grouping"))
c1284011
KW
1568#else
1569# define isLC_NUMERIC_STRING(name) (0)
1570#endif
1571
0b057af7 1572static const struct lconv_offset lconv_integers[] = {
03ceeedf 1573#ifdef USE_LOCALE_MONETARY
3800c318
JH
1574 {"int_frac_digits", STRUCT_OFFSET(struct lconv, int_frac_digits)},
1575 {"frac_digits", STRUCT_OFFSET(struct lconv, frac_digits)},
1576 {"p_cs_precedes", STRUCT_OFFSET(struct lconv, p_cs_precedes)},
1577 {"p_sep_by_space", STRUCT_OFFSET(struct lconv, p_sep_by_space)},
1578 {"n_cs_precedes", STRUCT_OFFSET(struct lconv, n_cs_precedes)},
1579 {"n_sep_by_space", STRUCT_OFFSET(struct lconv, n_sep_by_space)},
1580 {"p_sign_posn", STRUCT_OFFSET(struct lconv, p_sign_posn)},
1581 {"n_sign_posn", STRUCT_OFFSET(struct lconv, n_sign_posn)},
b15c1b56
AF
1582#ifdef HAS_LC_MONETARY_2008
1583 {"int_p_cs_precedes", STRUCT_OFFSET(struct lconv, int_p_cs_precedes)},
1584 {"int_p_sep_by_space", STRUCT_OFFSET(struct lconv, int_p_sep_by_space)},
1585 {"int_n_cs_precedes", STRUCT_OFFSET(struct lconv, int_n_cs_precedes)},
1586 {"int_n_sep_by_space", STRUCT_OFFSET(struct lconv, int_n_sep_by_space)},
1587 {"int_p_sign_posn", STRUCT_OFFSET(struct lconv, int_p_sign_posn)},
1588 {"int_n_sign_posn", STRUCT_OFFSET(struct lconv, int_n_sign_posn)},
1589#endif
03ceeedf 1590#endif
2f0945cb
NC
1591 {NULL, 0}
1592};
1593
3f3bcbfc 1594#endif /* HAS_LOCALECONV */
a0d0e21e 1595
172ea7c8 1596#ifdef HAS_LONG_DOUBLE
53796371 1597# if LONG_DOUBLESIZE > NVSIZE
172ea7c8
JH
1598# undef HAS_LONG_DOUBLE /* XXX until we figure out how to use them */
1599# endif
1600#endif
1601
1602#ifndef HAS_LONG_DOUBLE
1603#ifdef LDBL_MAX
1604#undef LDBL_MAX
1605#endif
1606#ifdef LDBL_MIN
1607#undef LDBL_MIN
1608#endif
1609#ifdef LDBL_EPSILON
1610#undef LDBL_EPSILON
1611#endif
1612#endif
1613
ec193bec
JH
1614/* Background: in most systems the low byte of the wait status
1615 * is the signal (the lowest 7 bits) and the coredump flag is
1616 * the eight bit, and the second lowest byte is the exit status.
1617 * BeOS bucks the trend and has the bytes in different order.
1618 * See beos/beos.c for how the reality is bent even in BeOS
1619 * to follow the traditional. However, to make the POSIX
1620 * wait W*() macros to work in BeOS, we need to unbend the
1621 * reality back in place. --jhi */
17028706
IW
1622/* In actual fact the code below is to blame here. Perl has an internal
1623 * representation of the exit status ($?), which it re-composes from the
1624 * OS's representation using the W*() POSIX macros. The code below
1625 * incorrectly uses the W*() macros on the internal representation,
1626 * which fails for OSs that have a different representation (namely BeOS
1627 * and Haiku). WMUNGE() is a hack that converts the internal
1628 * representation into the OS specific one, so that the W*() macros work
1629 * as expected. The better solution would be not to use the W*() macros
1630 * in the first place, though. -- Ingo Weinhold
1631 */
b6c36746 1632#if defined(__HAIKU__)
ec193bec
JH
1633# define WMUNGE(x) (((x) & 0xFF00) >> 8 | ((x) & 0x00FF) << 8)
1634#else
1635# define WMUNGE(x) (x)
1636#endif
1637
8990e307 1638static int
4b48cf39 1639not_here(const char *s)
8990e307
LW
1640{
1641 croak("POSIX::%s not implemented on this architecture", s);
1642 return -1;
1643}
463ee0b2 1644
1cb0fb50 1645#include "const-c.inc"
a290f238 1646
1dfe7606 1647static void
40b7a5f5 1648restore_sigmask(pTHX_ SV *osset_sv)
1dfe7606 1649{
7feb700b
JH
1650 /* Fortunately, restoring the signal mask can't fail, because
1651 * there's nothing we can do about it if it does -- we're not
1652 * supposed to return -1 from sigaction unless the disposition
1653 * was unaffected.
1654 */
30b42e09 1655#if !(defined(__amigaos4__) && defined(__NEWLIB__))
7feb700b
JH
1656 sigset_t *ossetp = (sigset_t *) SvPV_nolen( osset_sv );
1657 (void)sigprocmask(SIG_SETMASK, ossetp, (sigset_t *)0);
30b42e09 1658#endif
1dfe7606
AJ
1659}
1660
a2261f90
NC
1661static void *
1662allocate_struct(pTHX_ SV *rv, const STRLEN size, const char *packname) {
1663 SV *const t = newSVrv(rv, packname);
1664 void *const p = sv_grow(t, size + 1);
1665
706d6f2a
DM
1666 /* Ensure at least one use of not_here() to avoid "defined but not
1667 * used" warning. This is not at all related to allocate_struct(); I
1668 * just needed somewhere to dump it - DAPM */
1669 if (0) { not_here(""); }
1670
a2261f90
NC
1671 SvCUR_set(t, size);
1672 SvPOK_on(t);
1673 return p;
1674}
1675
81ab4c44
SH
1676#ifdef WIN32
1677
1678/*
1679 * (1) The CRT maintains its own copy of the environment, separate from
1680 * the Win32API copy.
1681 *
1682 * (2) CRT getenv() retrieves from this copy. CRT putenv() updates this
1683 * copy, and then calls SetEnvironmentVariableA() to update the Win32API
1684 * copy.
1685 *
1686 * (3) win32_getenv() and win32_putenv() call GetEnvironmentVariableA() and
1687 * SetEnvironmentVariableA() directly, bypassing the CRT copy of the
1688 * environment.
1689 *
1690 * (4) The CRT strftime() "%Z" implementation calls __tzset(). That
1691 * calls CRT tzset(), but only the first time it is called, and in turn
1692 * that uses CRT getenv("TZ") to retrieve the timezone info from the CRT
1693 * local copy of the environment and hence gets the original setting as
1694 * perl never updates the CRT copy when assigning to $ENV{TZ}.
1695 *
1696 * Therefore, we need to retrieve the value of $ENV{TZ} and call CRT
1697 * putenv() to update the CRT copy of the environment (if it is different)
1698 * whenever we're about to call tzset().
1699 *
1700 * In addition to all that, when perl is built with PERL_IMPLICIT_SYS
1701 * defined:
1702 *
1703 * (a) Each interpreter has its own copy of the environment inside the
1704 * perlhost structure. That allows applications that host multiple
1705 * independent Perl interpreters to isolate environment changes from
1706 * each other. (This is similar to how the perlhost mechanism keeps a
1707 * separate working directory for each Perl interpreter, so that calling
1708 * chdir() will not affect other interpreters.)
1709 *
1710 * (b) Only the first Perl interpreter instantiated within a process will
1711 * "write through" environment changes to the process environment.
1712 *
1713 * (c) Even the primary Perl interpreter won't update the CRT copy of the
1714 * the environment, only the Win32API copy (it calls win32_putenv()).
1715 *
1716 * As with CPerlHost::Getenv() and CPerlHost::Putenv() themselves, it makes
1717 * sense to only update the process environment when inside the main
1718 * interpreter, but we don't have access to CPerlHost's m_bTopLevel member
1719 * from here so we'll just have to check PL_curinterp instead.
1720 *
1721 * Therefore, we can simply #undef getenv() and putenv() so that those names
1722 * always refer to the CRT functions, and explicitly call win32_getenv() to
1723 * access perl's %ENV.
1724 *
1725 * We also #undef malloc() and free() to be sure we are using the CRT
1726 * functions otherwise under PERL_IMPLICIT_SYS they are redefined to calls
1727 * into VMem::Malloc() and VMem::Free() and all allocations will be freed
1728 * when the Perl interpreter is being destroyed so we'd end up with a pointer
1729 * into deallocated memory in environ[] if a program embedding a Perl
1730 * interpreter continues to operate even after the main Perl interpreter has
1731 * been destroyed.
1732 *
1733 * Note that we don't free() the malloc()ed memory unless and until we call
1734 * malloc() again ourselves because the CRT putenv() function simply puts its
b7b1e41b 1735 * pointer argument into the environ[] array (it doesn't make a copy of it)
81ab4c44
SH
1736 * so this memory must otherwise be leaked.
1737 */
1738
1739#undef getenv
1740#undef putenv
1741#undef malloc
1742#undef free
1743
1744static void
1745fix_win32_tzenv(void)
1746{
1747 static char* oldenv = NULL;
1748 char* newenv;
1749 const char* perl_tz_env = win32_getenv("TZ");
1750 const char* crt_tz_env = getenv("TZ");
1751 if (perl_tz_env == NULL)
1752 perl_tz_env = "";
1753 if (crt_tz_env == NULL)
1754 crt_tz_env = "";
1755 if (strcmp(perl_tz_env, crt_tz_env) != 0) {
1756 newenv = (char*)malloc((strlen(perl_tz_env) + 4) * sizeof(char));
1757 if (newenv != NULL) {
1758 sprintf(newenv, "TZ=%s", perl_tz_env);
1759 putenv(newenv);
1760 if (oldenv != NULL)
1761 free(oldenv);
1762 oldenv = newenv;
1763 }
1764 }
1765}
1766
1767#endif
1768
1769/*
1770 * my_tzset - wrapper to tzset() with a fix to make it work (better) on Win32.
1771 * This code is duplicated in the Time-Piece module, so any changes made here
1772 * should be made there too.
1773 */
1774static void
1775my_tzset(pTHX)
1776{
1777#ifdef WIN32
1778#if defined(USE_ITHREADS) && defined(PERL_IMPLICIT_SYS)
1779 if (PL_curinterp == aTHX)
1780#endif
1781 fix_win32_tzenv();
1782#endif
1783 tzset();
1784}
1785
2304df62
AD
1786MODULE = SigSet PACKAGE = POSIX::SigSet PREFIX = sig
1787
92b39396 1788void
2304df62 1789new(packname = "POSIX::SigSet", ...)
d3f5e399 1790 const char * packname
2304df62
AD
1791 CODE:
1792 {
1793 int i;
92b39396
NC
1794 sigset_t *const s
1795 = (sigset_t *) allocate_struct(aTHX_ (ST(0) = sv_newmortal()),
1796 sizeof(sigset_t),
1797 packname);
1798 sigemptyset(s);
a0d0e21e 1799 for (i = 1; i < items; i++)
92b39396
NC
1800 sigaddset(s, SvIV(ST(i)));
1801 XSRETURN(1);
2304df62 1802 }
2304df62
AD
1803
1804SysRet
df6c2df2 1805addset(sigset, sig)
2304df62 1806 POSIX::SigSet sigset
69b5fd06 1807 POSIX::SigNo sig
df6c2df2
NC
1808 ALIAS:
1809 delset = 1
1810 CODE:
1811 RETVAL = ix ? sigdelset(sigset, sig) : sigaddset(sigset, sig);
1812 OUTPUT:
1813 RETVAL
2304df62
AD
1814
1815SysRet
df6c2df2 1816emptyset(sigset)
2304df62 1817 POSIX::SigSet sigset
df6c2df2
NC
1818 ALIAS:
1819 fillset = 1
1820 CODE:
1821 RETVAL = ix ? sigfillset(sigset) : sigemptyset(sigset);
1822 OUTPUT:
1823 RETVAL
2304df62
AD
1824
1825int
1826sigismember(sigset, sig)
1827 POSIX::SigSet sigset
69b5fd06 1828 POSIX::SigNo sig
2304df62 1829
a0d0e21e
LW
1830MODULE = Termios PACKAGE = POSIX::Termios PREFIX = cf
1831
11a39fe4 1832void
a0d0e21e 1833new(packname = "POSIX::Termios", ...)
d3f5e399 1834 const char * packname
a0d0e21e
LW
1835 CODE:
1836 {
1837#ifdef I_TERMIOS
a2261f90
NC
1838 void *const p = allocate_struct(aTHX_ (ST(0) = sv_newmortal()),
1839 sizeof(struct termios), packname);
11a39fe4
NC
1840 /* The previous implementation stored a pointer to an uninitialised
1841 struct termios. Seems safer to initialise it, particularly as
1842 this implementation exposes the struct to prying from perl-space.
1843 */
a2261f90 1844 memset(p, 0, 1 + sizeof(struct termios));
11a39fe4 1845 XSRETURN(1);
a0d0e21e
LW
1846#else
1847 not_here("termios");
1848#endif
1849 }
a0d0e21e
LW
1850
1851SysRet
1852getattr(termios_ref, fd = 0)
1853 POSIX::Termios termios_ref
ddc7c5c7 1854 POSIX::Fd fd
a0d0e21e
LW
1855 CODE:
1856 RETVAL = tcgetattr(fd, termios_ref);
1857 OUTPUT:
1858 RETVAL
1859
e08f19f5
TC
1860# If we define TCSANOW here then both a found and not found constant sub
1861# are created causing a Constant subroutine TCSANOW redefined warning
518487b2 1862#ifndef TCSANOW
e08f19f5
TC
1863# define DEF_SETATTR_ACTION 0
1864#else
1865# define DEF_SETATTR_ACTION TCSANOW
518487b2 1866#endif
a0d0e21e 1867SysRet
e08f19f5 1868setattr(termios_ref, fd = 0, optional_actions = DEF_SETATTR_ACTION)
a0d0e21e 1869 POSIX::Termios termios_ref
ddc7c5c7 1870 POSIX::Fd fd
a0d0e21e
LW
1871 int optional_actions
1872 CODE:
ddc7c5c7
JH
1873 /* The second argument to the call is mandatory, but we'd like to give
1874 it a useful default. 0 isn't valid on all operating systems - on
1875 Solaris (at least) TCSANOW, TCSADRAIN and TCSAFLUSH have the same
1876 values as the equivalent ioctls, TCSETS, TCSETSW and TCSETSF. */
1877 if (optional_actions < 0) {
1878 SETERRNO(EINVAL, LIB_INVARG);
8481e3d3 1879 RETVAL = -1;
ddc7c5c7
JH
1880 } else {
1881 RETVAL = tcsetattr(fd, optional_actions, termios_ref);
8481e3d3 1882 }
a0d0e21e
LW
1883 OUTPUT:
1884 RETVAL
1885
1886speed_t
2a59a32c 1887getispeed(termios_ref)
a0d0e21e 1888 POSIX::Termios termios_ref
2a59a32c
NC
1889 ALIAS:
1890 getospeed = 1
a0d0e21e 1891 CODE:
2a59a32c 1892 RETVAL = ix ? cfgetospeed(termios_ref) : cfgetispeed(termios_ref);
a0d0e21e
LW
1893 OUTPUT:
1894 RETVAL
1895
1896tcflag_t
2a59a32c 1897getiflag(termios_ref)
a0d0e21e 1898 POSIX::Termios termios_ref
2a59a32c
NC
1899 ALIAS:
1900 getoflag = 1
1901 getcflag = 2
1902 getlflag = 3
a0d0e21e
LW
1903 CODE:
1904#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
2a59a32c
NC
1905 switch(ix) {
1906 case 0:
1907 RETVAL = termios_ref->c_iflag;
1908 break;
1909 case 1:
1910 RETVAL = termios_ref->c_oflag;
1911 break;
1912 case 2:
1913 RETVAL = termios_ref->c_cflag;
1914 break;
1915 case 3:
1916 RETVAL = termios_ref->c_lflag;
1917 break;
df164f52
DM
1918 default:
1919 RETVAL = 0; /* silence compiler warning */
2a59a32c 1920 }
a0d0e21e 1921#else
2a59a32c
NC
1922 not_here(GvNAME(CvGV(cv)));
1923 RETVAL = 0;
a0d0e21e
LW
1924#endif
1925 OUTPUT:
1926 RETVAL
1927
1928cc_t
1929getcc(termios_ref, ccix)
1930 POSIX::Termios termios_ref
b56fc9ec 1931 unsigned int ccix
a0d0e21e
LW
1932 CODE:
1933#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
1934 if (ccix >= NCCS)
1935 croak("Bad getcc subscript");
1936 RETVAL = termios_ref->c_cc[ccix];
1937#else
640cc986
HM
1938 not_here("getcc");
1939 RETVAL = 0;
a0d0e21e
LW
1940#endif
1941 OUTPUT:
1942 RETVAL
1943
1944SysRet
2a59a32c 1945setispeed(termios_ref, speed)
a0d0e21e
LW
1946 POSIX::Termios termios_ref
1947 speed_t speed
2a59a32c
NC
1948 ALIAS:
1949 setospeed = 1
a0d0e21e 1950 CODE:
2a59a32c
NC
1951 RETVAL = ix
1952 ? cfsetospeed(termios_ref, speed) : cfsetispeed(termios_ref, speed);
1953 OUTPUT:
1954 RETVAL
a0d0e21e
LW
1955
1956void
2a59a32c 1957setiflag(termios_ref, flag)
a0d0e21e 1958 POSIX::Termios termios_ref
2a59a32c
NC
1959 tcflag_t flag
1960 ALIAS:
1961 setoflag = 1
1962 setcflag = 2
1963 setlflag = 3
a0d0e21e
LW
1964 CODE:
1965#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
2a59a32c
NC
1966 switch(ix) {
1967 case 0:
1968 termios_ref->c_iflag = flag;
1969 break;
1970 case 1:
1971 termios_ref->c_oflag = flag;
1972 break;
1973 case 2:
1974 termios_ref->c_cflag = flag;
1975 break;
1976 case 3:
1977 termios_ref->c_lflag = flag;
1978 break;
1979 }
a0d0e21e 1980#else
2a59a32c 1981 not_here(GvNAME(CvGV(cv)));
a0d0e21e
LW
1982#endif
1983
1984void
1985setcc(termios_ref, ccix, cc)
1986 POSIX::Termios termios_ref
b56fc9ec 1987 unsigned int ccix
a0d0e21e
LW
1988 cc_t cc
1989 CODE:
1990#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
1991 if (ccix >= NCCS)
1992 croak("Bad setcc subscript");
1993 termios_ref->c_cc[ccix] = cc;
1994#else
1995 not_here("setcc");
1996#endif
1997
1998
a0d0e21e
LW
1999MODULE = POSIX PACKAGE = POSIX
2000
1cb0fb50 2001INCLUDE: const-xs.inc
a290f238 2002
e99d581a
NC
2003int
2004WEXITSTATUS(status)
2005 int status
72bfe1b2
NC
2006 ALIAS:
2007 POSIX::WIFEXITED = 1
2008 POSIX::WIFSIGNALED = 2
2009 POSIX::WIFSTOPPED = 3
2010 POSIX::WSTOPSIG = 4
2011 POSIX::WTERMSIG = 5
2012 CODE:
fabb67aa
SK
2013#if !defined(WEXITSTATUS) || !defined(WIFEXITED) || !defined(WIFSIGNALED) \
2014 || !defined(WIFSTOPPED) || !defined(WSTOPSIG) || !defined(WTERMSIG)
19c4478c
NC
2015 RETVAL = 0; /* Silence compilers that notice this, but don't realise
2016 that not_here() can't return. */
2017#endif
72bfe1b2
NC
2018 switch(ix) {
2019 case 0:
d49025b7 2020#ifdef WEXITSTATUS
17028706 2021 RETVAL = WEXITSTATUS(WMUNGE(status));
d49025b7
NC
2022#else
2023 not_here("WEXITSTATUS");
2024#endif
72bfe1b2
NC
2025 break;
2026 case 1:
d49025b7 2027#ifdef WIFEXITED
17028706 2028 RETVAL = WIFEXITED(WMUNGE(status));
d49025b7
NC
2029#else
2030 not_here("WIFEXITED");
2031#endif
72bfe1b2
NC
2032 break;
2033 case 2:
d49025b7 2034#ifdef WIFSIGNALED
17028706 2035 RETVAL = WIFSIGNALED(WMUNGE(status));
d49025b7
NC
2036#else
2037 not_here("WIFSIGNALED");
2038#endif
72bfe1b2
NC
2039 break;
2040 case 3:
d49025b7 2041#ifdef WIFSTOPPED
17028706 2042 RETVAL = WIFSTOPPED(WMUNGE(status));
d49025b7
NC
2043#else
2044 not_here("WIFSTOPPED");
2045#endif
72bfe1b2
NC
2046 break;
2047 case 4:
d49025b7 2048#ifdef WSTOPSIG
17028706 2049 RETVAL = WSTOPSIG(WMUNGE(status));
d49025b7
NC
2050#else
2051 not_here("WSTOPSIG");
2052#endif
72bfe1b2
NC
2053 break;
2054 case 5:
d49025b7 2055#ifdef WTERMSIG
17028706 2056 RETVAL = WTERMSIG(WMUNGE(status));
d49025b7
NC
2057#else
2058 not_here("WTERMSIG");
2059#endif
72bfe1b2
NC
2060 break;
2061 default:
42c07143 2062 croak("Illegal alias %d for POSIX::W*", (int)ix);
72bfe1b2
NC
2063 }
2064 OUTPUT:
2065 RETVAL
2304df62 2066
2304df62
AD
2067SysRet
2068open(filename, flags = O_RDONLY, mode = 0666)
2069 char * filename
2070 int flags
a0d0e21e 2071 Mode_t mode
748a9306
LW
2072 CODE:
2073 if (flags & (O_APPEND|O_CREAT|O_TRUNC|O_RDWR|O_WRONLY|O_EXCL))
2074 TAINT_PROPER("open");
2075 RETVAL = open(filename, flags, mode);
2076 OUTPUT:
2077 RETVAL
2078
2304df62
AD
2079
2080HV *
2081localeconv()
2082 CODE:
3f3bcbfc
KW
2083#ifndef HAS_LOCALECONV
2084 localeconv(); /* A stub to call not_here(). */
2085#else
2304df62 2086 struct lconv *lcbuf;
a835cd47
KW
2087
2088 /* localeconv() deals with both LC_NUMERIC and LC_MONETARY, but
2089 * LC_MONETARY is already in the correct locale */
67d796ae
KW
2090 DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
2091 STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
a835cd47 2092
2304df62 2093 RETVAL = newHV();
c4e79b56 2094 sv_2mortal((SV*)RETVAL);
8063af02 2095 if ((lcbuf = localeconv())) {
2f0945cb
NC
2096 const struct lconv_offset *strings = lconv_strings;
2097 const struct lconv_offset *integers = lconv_integers;
2098 const char *ptr = (const char *) lcbuf;
2099
e3bf3304 2100 while (strings->name) {
c1284011
KW
2101 /* This string may be controlled by either LC_NUMERIC, or
2102 * LC_MONETARY */
2103 bool is_utf8_locale
2104#if defined(USE_LOCALE_NUMERIC) && defined(USE_LOCALE_MONETARY)
2105 = _is_cur_LC_category_utf8((isLC_NUMERIC_STRING(strings->name))
2106 ? LC_NUMERIC
2107 : LC_MONETARY);
2108#elif defined(USE_LOCALE_NUMERIC)
2109 = _is_cur_LC_category_utf8(LC_NUMERIC);
2110#elif defined(USE_LOCALE_MONETARY)
2111 = _is_cur_LC_category_utf8(LC_MONETARY);
2112#else
2113 = FALSE;
2114#endif
2115
2f0945cb
NC
2116 const char *value = *((const char **)(ptr + strings->offset));
2117
c1284011
KW
2118 if (value && *value) {
2119 (void) hv_store(RETVAL,
2120 strings->name,
2121 strlen(strings->name),
2122 newSVpvn_utf8(value,
2123 strlen(value),
2124
2125 /* We mark it as UTF-8 if a utf8 locale
9f10db87 2126 * and is valid and variant under UTF-8 */
c1284011 2127 is_utf8_locale
9f10db87 2128 && ! is_invariant_string((U8 *) value, 0)
c1284011
KW
2129 && is_utf8_string((U8 *) value, 0)),
2130 0);
e3bf3304
KW
2131 }
2132 strings++;
2133 }
2f0945cb 2134
e3bf3304 2135 while (integers->name) {
2f0945cb
NC
2136 const char value = *((const char *)(ptr + integers->offset));
2137
2138 if (value != CHAR_MAX)
2139 (void) hv_store(RETVAL, integers->name,
2140 strlen(integers->name), newSViv(value), 0);
e3bf3304
KW
2141 integers++;
2142 }
2304df62 2143 }
67d796ae 2144 RESTORE_LC_NUMERIC_STANDARD();
3f3bcbfc 2145#endif /* HAS_LOCALECONV */
2304df62
AD
2146 OUTPUT:
2147 RETVAL
2148
2149char *
c28ee57b 2150setlocale(category, locale = 0)
2304df62 2151 int category
8e70cf7a 2152 const char * locale
1ba01ae3
SH
2153 PREINIT:
2154 char * retval;
c28ee57b 2155 CODE:
49efabc8
KW
2156#ifdef USE_LOCALE_NUMERIC
2157 /* A 0 (or NULL) locale means only query what the current one is. We
2158 * have the LC_NUMERIC name saved, because we are normally switched
2159 * into the C locale for it. Switch back so an LC_ALL query will yield
2160 * the correct results; all other categories don't require special
2161 * handling */
2162 if (locale == 0) {
2163 if (category == LC_NUMERIC) {
2164 XSRETURN_PV(PL_numeric_name);
2165 }
2166# ifdef LC_ALL
2167 else if (category == LC_ALL) {
67d796ae 2168 SET_NUMERIC_UNDERLYING();
49efabc8
KW
2169 }
2170# endif
2171 }
2172#endif
b385bb4d
KW
2173#ifdef WIN32 /* Use wrapper on Windows */
2174 retval = Perl_my_setlocale(aTHX_ category, locale);
2175#else
1ba01ae3 2176 retval = setlocale(category, locale);
b385bb4d 2177#endif
bbc98134
KW
2178 DEBUG_L(PerlIO_printf(Perl_debug_log,
2179 "%s:%d: %s\n", __FILE__, __LINE__,
2180 _setlocale_debug_string(category, locale, retval)));
fbd840df 2181 if (! retval) {
49efabc8
KW
2182 /* Should never happen that a query would return an error, but be
2183 * sure and reset to C locale */
2184 if (locale == 0) {
2185 SET_NUMERIC_STANDARD();
2186 }
fbd840df
KW
2187 XSRETURN_UNDEF;
2188 }
49efabc8
KW
2189
2190 /* Save retval since subsequent setlocale() calls may overwrite it. */
2191 retval = savepv(retval);
54bc7615 2192 SAVEFREEPV(retval);
49efabc8 2193
67d796ae
KW
2194 /* For locale == 0, we may have switched to NUMERIC_UNDERLYING. Switch
2195 * back */
49efabc8
KW
2196 if (locale == 0) {
2197 SET_NUMERIC_STANDARD();
2198 XSRETURN_PV(retval);
2199 }
fbd840df 2200 else {
49efabc8 2201 RETVAL = retval;
36477c24 2202#ifdef USE_LOCALE_CTYPE
bbce6d69 2203 if (category == LC_CTYPE
2204#ifdef LC_ALL
2205 || category == LC_ALL
2206#endif
2207 )
2208 {
2209 char *newctype;
2210#ifdef LC_ALL
bbc98134 2211 if (category == LC_ALL) {
bbce6d69 2212 newctype = setlocale(LC_CTYPE, NULL);
bbc98134
KW
2213 DEBUG_Lv(PerlIO_printf(Perl_debug_log,
2214 "%s:%d: %s\n", __FILE__, __LINE__,
2215 _setlocale_debug_string(LC_CTYPE, NULL, newctype)));
2216 }
bbce6d69 2217 else
2218#endif
2219 newctype = RETVAL;
864dbfa3 2220 new_ctype(newctype);
bbce6d69 2221 }
36477c24 2222#endif /* USE_LOCALE_CTYPE */
2223#ifdef USE_LOCALE_COLLATE
bbce6d69 2224 if (category == LC_COLLATE
2225#ifdef LC_ALL
2226 || category == LC_ALL
2227#endif
2228 )
2229 {
2230 char *newcoll;
2231#ifdef LC_ALL
bbc98134 2232 if (category == LC_ALL) {
bbce6d69 2233 newcoll = setlocale(LC_COLLATE, NULL);
bbc98134
KW
2234 DEBUG_Lv(PerlIO_printf(Perl_debug_log,
2235 "%s:%d: %s\n", __FILE__, __LINE__,
2236 _setlocale_debug_string(LC_COLLATE, NULL, newcoll)));
2237 }
bbce6d69 2238 else
2239#endif
2240 newcoll = RETVAL;
864dbfa3 2241 new_collate(newcoll);
bbce6d69 2242 }
36477c24 2243#endif /* USE_LOCALE_COLLATE */
2244#ifdef USE_LOCALE_NUMERIC
bbce6d69 2245 if (category == LC_NUMERIC
2246#ifdef LC_ALL
2247 || category == LC_ALL
2248#endif
2249 )
2250 {
2251 char *newnum;
2252#ifdef LC_ALL
bbc98134 2253 if (category == LC_ALL) {
bbce6d69 2254 newnum = setlocale(LC_NUMERIC, NULL);
bbc98134
KW
2255 DEBUG_Lv(PerlIO_printf(Perl_debug_log,
2256 "%s:%d: %s\n", __FILE__, __LINE__,
2257 _setlocale_debug_string(LC_NUMERIC, NULL, newnum)));
2258 }
bbce6d69 2259 else
2260#endif
2261 newnum = RETVAL;
864dbfa3 2262 new_numeric(newnum);
bbce6d69 2263 }
36477c24 2264#endif /* USE_LOCALE_NUMERIC */
bbce6d69 2265 }
c28ee57b
JH
2266 OUTPUT:
2267 RETVAL
2304df62 2268
e1ca407b 2269NV
2304df62 2270acos(x)
e1ca407b 2271 NV x
b256643b 2272 ALIAS:
7965edec
JH
2273 acosh = 1
2274 asin = 2
2275 asinh = 3
2276 atan = 4
2277 atanh = 5
2278 cbrt = 6
2279 ceil = 7
2280 cosh = 8
2281 erf = 9
2282 erfc = 10
2283 exp2 = 11
2284 expm1 = 12
2285 floor = 13
2286 j0 = 14
2287 j1 = 15
2288 lgamma = 16
2289 log10 = 17
2290 log1p = 18
2291 log2 = 19
2292 logb = 20
2293 nearbyint = 21
2294 rint = 22
2295 round = 23
2296 sinh = 24
2297 tan = 25
2298 tanh = 26
2299 tgamma = 27
2300 trunc = 28
2301 y0 = 29
2302 y1 = 30
b256643b 2303 CODE:
7f4bfd0b 2304 PERL_UNUSED_VAR(x);
78a0541a 2305 RETVAL = NV_NAN;
b256643b
NC
2306 switch (ix) {
2307 case 0:
8a00eddc 2308 RETVAL = Perl_acos(x); /* C89 math */
b256643b
NC
2309 break;
2310 case 1:
5716d070 2311#ifdef c99_acosh
7965edec 2312 RETVAL = c99_acosh(x);
5716d070
JH
2313#else
2314 not_here("acosh");
2315#endif
b256643b
NC
2316 break;
2317 case 2:
8a00eddc 2318 RETVAL = Perl_asin(x); /* C89 math */
b256643b
NC
2319 break;
2320 case 3:
5716d070 2321#ifdef c99_asinh
7965edec 2322 RETVAL = c99_asinh(x);
5716d070
JH
2323#else
2324 not_here("asinh");
2325#endif
b256643b
NC
2326 break;
2327 case 4:
8a00eddc 2328 RETVAL = Perl_atan(x); /* C89 math */
b256643b
NC
2329 break;
2330 case 5:
5716d070 2331#ifdef c99_atanh
7965edec 2332 RETVAL = c99_atanh(x);
5716d070
JH
2333#else
2334 not_here("atanh");
2335#endif
b256643b
NC
2336 break;
2337 case 6:
5716d070 2338#ifdef c99_cbrt
7965edec 2339 RETVAL = c99_cbrt(x);
5716d070
JH
2340#else
2341 not_here("cbrt");
2342#endif
b256643b
NC
2343 break;
2344 case 7:
8a00eddc 2345 RETVAL = Perl_ceil(x); /* C89 math */
b256643b
NC
2346 break;
2347 case 8:
8a00eddc 2348 RETVAL = Perl_cosh(x); /* C89 math */
7965edec
JH
2349 break;
2350 case 9:
5716d070 2351#ifdef c99_erf
7965edec 2352 RETVAL = c99_erf(x);
5716d070
JH
2353#else
2354 not_here("erf");
2355#endif
7965edec
JH
2356 break;
2357 case 10:
5716d070 2358#ifdef c99_erfc
d5799f37 2359 RETVAL = c99_erfc(x);
5716d070
JH
2360#else
2361 not_here("erfc");
2362#endif
7965edec
JH
2363 break;
2364 case 11:
5716d070 2365#ifdef c99_exp2
7965edec 2366 RETVAL = c99_exp2(x);
5716d070
JH
2367#else
2368 not_here("exp2");
2369#endif
7965edec
JH
2370 break;
2371 case 12:
5716d070 2372#ifdef c99_expm1
7965edec 2373 RETVAL = c99_expm1(x);
5716d070
JH
2374#else
2375 not_here("expm1");
2376#endif
7965edec
JH
2377 break;
2378 case 13:
8a00eddc 2379 RETVAL = Perl_floor(x); /* C89 math */
7965edec
JH
2380 break;
2381 case 14:
5716d070 2382#ifdef bessel_j0
7965edec 2383 RETVAL = bessel_j0(x);
5716d070 2384#else
85c93440 2385 not_here("j0");
5716d070 2386#endif
7965edec
JH
2387 break;
2388 case 15:
5716d070 2389#ifdef bessel_j1
7965edec 2390 RETVAL = bessel_j1(x);
5716d070 2391#else
85c93440 2392 not_here("j1");
5716d070 2393#endif
7965edec
JH
2394 break;
2395 case 16:
2e9cdb62 2396 /* XXX Note: the lgamma modifies a global variable (signgam),
d334ccbe 2397 * which is evil. Some platforms have lgamma_r, which has
2e9cdb62 2398 * extra output parameter instead of the global variable. */
5716d070 2399#ifdef c99_lgamma
7965edec 2400 RETVAL = c99_lgamma(x);
5716d070
JH
2401#else
2402 not_here("lgamma");
2403#endif
7965edec
JH
2404 break;
2405 case 17:
5716d070 2406 RETVAL = log10(x); /* C89 math */
7965edec
JH
2407 break;
2408 case 18:
5716d070 2409#ifdef c99_log1p
7965edec 2410 RETVAL = c99_log1p(x);
5716d070
JH
2411#else
2412 not_here("log1p");
2413#endif
7965edec
JH
2414 break;
2415 case 19:
5716d070 2416#ifdef c99_log2
7965edec 2417 RETVAL = c99_log2(x);
5716d070
JH
2418#else
2419 not_here("log2");
2420#endif
7965edec
JH
2421 break;
2422 case 20:
5716d070 2423#ifdef c99_logb
7965edec 2424 RETVAL = c99_logb(x);
eec978e5
JH
2425#elif defined(c99_log2) && FLT_RADIX == 2
2426 RETVAL = Perl_floor(c99_log2(PERL_ABS(x)));
5716d070
JH
2427#else
2428 not_here("logb");
2429#endif
7965edec
JH
2430 break;
2431 case 21:
5716d070 2432#ifdef c99_nearbyint
7965edec 2433 RETVAL = c99_nearbyint(x);
5716d070
JH
2434#else
2435 not_here("nearbyint");
2436#endif
7965edec
JH
2437 break;
2438 case 22:
5716d070 2439#ifdef c99_rint
7965edec 2440 RETVAL = c99_rint(x);
5716d070
JH
2441#else
2442 not_here("rint");
2443#endif
7965edec
JH
2444 break;
2445 case 23:
5716d070 2446#ifdef c99_round
7965edec 2447 RETVAL = c99_round(x);
5716d070
JH
2448#else
2449 not_here("round");
2450#endif
7965edec
JH
2451 break;
2452 case 24:
8a00eddc 2453 RETVAL = Perl_sinh(x); /* C89 math */
7965edec
JH
2454 break;
2455 case 25:
8a00eddc 2456 RETVAL = Perl_tan(x); /* C89 math */
b256643b 2457 break;
7965edec 2458 case 26:
8a00eddc 2459 RETVAL = Perl_tanh(x); /* C89 math */
7965edec
JH
2460 break;
2461 case 27:
5716d070 2462#ifdef c99_tgamma
7965edec 2463 RETVAL = c99_tgamma(x);
5716d070
JH
2464#else
2465 not_here("tgamma");
2466#endif
7965edec
JH
2467 break;
2468 case 28:
5716d070 2469#ifdef c99_trunc
7965edec 2470 RETVAL = c99_trunc(x);
5716d070
JH
2471#else
2472 not_here("trunc");
2473#endif
7965edec
JH
2474 break;
2475 case 29:
5716d070 2476#ifdef bessel_y0
7965edec 2477 RETVAL = bessel_y0(x);
5716d070 2478#else
85c93440 2479 not_here("y0");
5716d070 2480#endif
7965edec
JH
2481 break;
2482 case 30:
2483 default:
5716d070 2484#ifdef bessel_y1
7965edec 2485 RETVAL = bessel_y1(x);
5716d070 2486#else
85c93440 2487 not_here("y1");
5716d070 2488#endif
7965edec
JH
2489 }
2490 OUTPUT:
2491 RETVAL
2492
2493IV
a5713e21
JH
2494fegetround()
2495 CODE:
78a0541a 2496#ifdef HAS_FEGETROUND
d5f4f26a 2497 RETVAL = my_fegetround();
78a0541a
JH
2498#else
2499 RETVAL = -1;
a5713e21
JH
2500 not_here("fegetround");
2501#endif
2502 OUTPUT:
2503 RETVAL
2504
2505IV
2506fesetround(x)
2507 IV x
2508 CODE:
2509#ifdef HAS_FEGETROUND /* canary for fesetround */
2510 RETVAL = fesetround(x);
879d23d2 2511#elif defined(HAS_FPGETROUND) /* canary for fpsetround */
e0939537 2512 switch (x) {
e0939537
JH
2513 case FE_TONEAREST: RETVAL = fpsetround(FP_RN); break;
2514 case FE_TOWARDZERO: RETVAL = fpsetround(FP_RZ); break;
2515 case FE_DOWNWARD: RETVAL = fpsetround(FP_RM); break;
2516 case FE_UPWARD: RETVAL = fpsetround(FP_RP); break;
ebac59ac 2517 default: RETVAL = -1; break;
e0939537 2518 }
877206df
JH
2519#elif defined(__osf__) /* Tru64 */
2520 switch (x) {
2521 case FE_TONEAREST: RETVAL = write_rnd(FP_RND_RN); break;
2522 case FE_TOWARDZERO: RETVAL = write_rnd(FP_RND_RZ); break;
2523 case FE_DOWNWARD: RETVAL = write_rnd(FP_RND_RM); break;
2524 case FE_UPWARD: RETVAL = write_rnd(FP_RND_RP); break;
2525 default: RETVAL = -1; break;
2526 }
a5713e21 2527#else
7f4bfd0b 2528 PERL_UNUSED_VAR(x);
78a0541a 2529 RETVAL = -1;
a5713e21
JH
2530 not_here("fesetround");
2531#endif
2532 OUTPUT:
2533 RETVAL
2534
2535IV
7965edec
JH
2536fpclassify(x)
2537 NV x
2538 ALIAS:
2539 ilogb = 1
2540 isfinite = 2
2541 isinf = 3
2542 isnan = 4
2543 isnormal = 5
3823048b
JH
2544 lrint = 6
2545 lround = 7
2546 signbit = 8
7965edec 2547 CODE:
7f4bfd0b 2548 PERL_UNUSED_VAR(x);
78a0541a 2549 RETVAL = -1;
7965edec
JH
2550 switch (ix) {
2551 case 0:
5716d070 2552#ifdef c99_fpclassify
7965edec 2553 RETVAL = c99_fpclassify(x);
5716d070
JH
2554#else
2555 not_here("fpclassify");
2556#endif
7965edec
JH
2557 break;
2558 case 1:
5716d070 2559#ifdef c99_ilogb
7965edec 2560 RETVAL = c99_ilogb(x);
5716d070
JH
2561#else
2562 not_here("ilogb");
2563#endif
7965edec
JH
2564 break;
2565 case 2:
2566 RETVAL = Perl_isfinite(x);
2567 break;
2568 case 3:
2569 RETVAL = Perl_isinf(x);
2570 break;
2571 case 4:
2572 RETVAL = Perl_isnan(x);
2573 break;
2574 case 5:
5716d070 2575#ifdef c99_isnormal
7965edec 2576 RETVAL = c99_isnormal(x);
5716d070
JH
2577#else
2578 not_here("isnormal");
2579#endif
7965edec
JH
2580 break;
2581 case 6:
d5f4f26a
JH
2582#ifdef c99_lrint
2583 RETVAL = c99_lrint(x);
2584#else
2585 not_here("lrint");
2586#endif
2587 break;
3823048b 2588 case 7:
9e010b89
JH
2589#ifdef c99_lround
2590 RETVAL = c99_lround(x);
2591#else
2592 not_here("lround");
2593#endif
2594 break;
3823048b 2595 case 8:
7965edec 2596 default:
5716d070
JH
2597#ifdef Perl_signbit
2598 RETVAL = Perl_signbit(x);
2a7bb164
JH
2599#else
2600 RETVAL = (x < 0) || (x == -0.0);
5716d070 2601#endif
7965edec 2602 break;
b256643b
NC
2603 }
2604 OUTPUT:
2605 RETVAL
2304df62 2606
e1ca407b 2607NV
07bb61ac
JH
2608getpayload(nv)
2609 NV nv
2610 CODE:
2611 RETVAL = S_getpayload(nv);
2612 OUTPUT:
2613 RETVAL
2614
2615void
2616setpayload(nv, payload)
2617 NV nv
2618 NV payload
2619 CODE:
2620 S_setpayload(&nv, payload, FALSE);
2621 OUTPUT:
2622 nv
2623
2624void
2625setpayloadsig(nv, payload)
2626 NV nv
2627 NV payload
2628 CODE:
2629 nv = NV_NAN;
2630 S_setpayload(&nv, payload, TRUE);
2631 OUTPUT:
2632 nv
2633
2634int
2635issignaling(nv)
2636 NV nv
2637 CODE:
2638 RETVAL = Perl_isnan(nv) && NV_NAN_IS_SIGNALING(&nv);
2639 OUTPUT:
2640 RETVAL
2641
2642NV
7965edec 2643copysign(x,y)
e1ca407b
A
2644 NV x
2645 NV y
7965edec
JH
2646 ALIAS:
2647 fdim = 1
2648 fmax = 2
2649 fmin = 3
2650 fmod = 4
2651 hypot = 5
2652 isgreater = 6
2653 isgreaterequal = 7
2654 isless = 8
2655 islessequal = 9
2656 islessgreater = 10
2657 isunordered = 11
2658 nextafter = 12
2659 nexttoward = 13
2660 remainder = 14
2661 CODE:
7f4bfd0b
JH
2662 PERL_UNUSED_VAR(x);
2663 PERL_UNUSED_VAR(y);
78a0541a 2664 RETVAL = NV_NAN;
7965edec
JH
2665 switch (ix) {
2666 case 0:
5716d070 2667#ifdef c99_copysign
7965edec 2668 RETVAL = c99_copysign(x, y);
5716d070
JH
2669#else
2670 not_here("copysign");
2671#endif
7965edec
JH
2672 break;
2673 case 1:
5716d070 2674#ifdef c99_fdim
7965edec 2675 RETVAL = c99_fdim(x, y);
5716d070
JH
2676#else
2677 not_here("fdim");
2678#endif
7965edec
JH
2679 break;
2680 case 2:
5716d070 2681#ifdef c99_fmax
7965edec 2682 RETVAL = c99_fmax(x, y);
5716d070
JH
2683#else
2684 not_here("fmax");
2685#endif
7965edec
JH
2686 break;
2687 case 3:
5716d070 2688#ifdef c99_fmin
7965edec 2689 RETVAL = c99_fmin(x, y);
5716d070
JH
2690#else
2691 not_here("fmin");
2692#endif
7965edec
JH
2693 break;
2694 case 4:
8a00eddc 2695 RETVAL = Perl_fmod(x, y); /* C89 math */
7965edec
JH
2696 break;
2697 case 5:
5716d070 2698#ifdef c99_hypot
7965edec 2699 RETVAL = c99_hypot(x, y);
5716d070
JH
2700#else
2701 not_here("hypot");
2702#endif
7965edec
JH
2703 break;
2704 case 6:
5716d070 2705#ifdef c99_isgreater
7965edec 2706 RETVAL = c99_isgreater(x, y);
5716d070
JH
2707#else
2708 not_here("isgreater");
2709#endif
7965edec
JH
2710 break;
2711 case 7:
5716d070 2712#ifdef c99_isgreaterequal
7965edec 2713 RETVAL = c99_isgreaterequal(x, y);
5716d070
JH
2714#else
2715 not_here("isgreaterequal");
2716#endif
7965edec
JH
2717 break;
2718 case 8:
5716d070 2719#ifdef c99_isless
7965edec 2720 RETVAL = c99_isless(x, y);
5716d070
JH
2721#else
2722 not_here("isless");
2723#endif
7965edec
JH
2724 break;
2725 case 9:
5716d070 2726#ifdef c99_islessequal
7965edec 2727 RETVAL = c99_islessequal(x, y);
5716d070
JH
2728#else
2729 not_here("islessequal");
2730#endif
7965edec
JH
2731 break;
2732 case 10:
5716d070 2733#ifdef c99_islessgreater
7965edec 2734 RETVAL = c99_islessgreater(x, y);
5716d070
JH
2735#else
2736 not_here("islessgreater");
2737#endif
7965edec
JH
2738 break;
2739 case 11:
5716d070 2740#ifdef c99_isunordered
7965edec 2741 RETVAL = c99_isunordered(x, y);
5716d070
JH
2742#else
2743 not_here("isunordered");
2744#endif
7965edec
JH
2745 break;
2746 case 12:
5716d070 2747#ifdef c99_nextafter
7965edec 2748 RETVAL = c99_nextafter(x, y);
5716d070
JH
2749#else
2750 not_here("nextafter");
2751#endif
7965edec
JH
2752 break;
2753 case 13:
5716d070 2754#ifdef c99_nexttoward
7965edec 2755 RETVAL = c99_nexttoward(x, y);
5716d070
JH
2756#else
2757 not_here("nexttoward");
2758#endif
7965edec
JH
2759 break;
2760 case 14:
2761 default:
5716d070 2762#ifdef c99_remainder
7f4bfd0b 2763 RETVAL = c99_remainder(x, y);
5716d070 2764#else
7f4bfd0b 2765 not_here("remainder");
5716d070 2766#endif
7965edec
JH
2767 break;
2768 }
2769 OUTPUT:
2770 RETVAL
2304df62
AD
2771
2772void
2773frexp(x)
e1ca407b 2774 NV x
2304df62
AD
2775 PPCODE:
2776 int expvar;
2304df62 2777 /* (We already know stack is long enough.) */
5716d070 2778 PUSHs(sv_2mortal(newSVnv(Perl_frexp(x,&expvar)))); /* C89 math */
2304df62
AD
2779 PUSHs(sv_2mortal(newSViv(expvar)));
2780
e1ca407b 2781NV
2304df62 2782ldexp(x,exp)
e1ca407b 2783 NV x
2304df62
AD
2784 int exp
2785
2304df62
AD
2786void
2787modf(x)
e1ca407b 2788 NV x
2304df62 2789 PPCODE:
e1ca407b 2790 NV intvar;
2304df62 2791 /* (We already know stack is long enough.) */
5716d070 2792 PUSHs(sv_2mortal(newSVnv(Perl_modf(x,&intvar)))); /* C89 math */
2304df62
AD
2793 PUSHs(sv_2mortal(newSVnv(intvar)));
2794
7965edec
JH
2795void
2796remquo(x,y)
2797 NV x
2798 NV y
2799 PPCODE:
5716d070 2800#ifdef c99_remquo
7965edec
JH
2801 int intvar;
2802 PUSHs(sv_2mortal(newSVnv(c99_remquo(x,y,&intvar))));
2803 PUSHs(sv_2mortal(newSVnv(intvar)));
5716d070 2804#else
7f4bfd0b
JH
2805 PERL_UNUSED_VAR(x);
2806 PERL_UNUSED_VAR(y);
5716d070
JH
2807 not_here("remquo");
2808#endif
7965edec
JH
2809
2810NV
2811scalbn(x,y)
2812 NV x
2813 IV y
2814 CODE:
5716d070 2815#ifdef c99_scalbn
7965edec 2816 RETVAL = c99_scalbn(x, y);
5716d070 2817#else
7f4bfd0b
JH
2818 PERL_UNUSED_VAR(x);
2819 PERL_UNUSED_VAR(y);
78a0541a 2820 RETVAL = NV_NAN;
5716d070
JH
2821 not_here("scalbn");
2822#endif
7965edec
JH
2823 OUTPUT:
2824 RETVAL
2825
2826NV
2827fma(x,y,z)
2828 NV x
2829 NV y
2830 NV z
2831 CODE:
5716d070 2832#ifdef c99_fma
6b13befe
JH
2833 RETVAL = c99_fma(x, y, z);
2834#else
7f4bfd0b
JH
2835 PERL_UNUSED_VAR(x);
2836 PERL_UNUSED_VAR(y);
2837 PERL_UNUSED_VAR(z);
6b13befe 2838 not_here("fma");
5716d070 2839#endif
7965edec
JH
2840 OUTPUT:
2841 RETVAL
2842
2843NV
07bb61ac
JH
2844nan(payload = 0)
2845 NV payload
7965edec 2846 CODE:
07bb61ac
JH
2847#ifdef NV_NAN
2848 /* If no payload given, just return the default NaN.
2849 * This makes a difference in platforms where the default
2850 * NaN is not all zeros. */
2851 if (items == 0) {
2852 RETVAL = NV_NAN;
2853 } else {
2854 S_setpayload(&RETVAL, payload, FALSE);
2855 }
2856#elif defined(c99_nan)
2857 {
2858 STRLEN elen = my_snprintf(PL_efloatbuf, PL_efloatsize, "%g", nv);
2859 if ((IV)elen == -1) {
2860 RETVAL = NV_NAN;
2861 } else {
2862 RETVAL = c99_nan(PL_efloatbuf);
2863 }
2864 }
7c7d45f1 2865#else
5716d070
JH
2866 not_here("nan");
2867#endif
7965edec
JH
2868 OUTPUT:
2869 RETVAL
2870
2871NV
2872jn(x,y)
2873 IV x
2874 NV y
2875 ALIAS:
2876 yn = 1
2877 CODE:
78a0541a 2878 RETVAL = NV_NAN;
7965edec
JH
2879 switch (ix) {
2880 case 0:
5716d070 2881#ifdef bessel_jn
7f4bfd0b 2882 RETVAL = bessel_jn(x, y);
5716d070 2883#else
6b13befe
JH
2884 PERL_UNUSED_VAR(x);
2885 PERL_UNUSED_VAR(y);
7f4bfd0b 2886 not_here("jn");
5716d070 2887#endif
7965edec
JH
2888 break;
2889 case 1:
2890 default:
5716d070 2891#ifdef bessel_yn
7f4bfd0b 2892 RETVAL = bessel_yn(x, y);
5716d070 2893#else
6b13befe
JH
2894 PERL_UNUSED_VAR(x);
2895 PERL_UNUSED_VAR(y);
7f4bfd0b 2896 not_here("yn");
5716d070 2897#endif
7965edec
JH
2898 break;
2899 }
2900 OUTPUT:
2901 RETVAL
2902
2304df62 2903SysRet
1dfe7606 2904sigaction(sig, optaction, oldaction = 0)
2304df62 2905 int sig
1dfe7606 2906 SV * optaction
2304df62
AD
2907 POSIX::SigAction oldaction
2908 CODE:
30b42e09 2909#if defined(WIN32) || defined(NETWARE) || (defined(__amigaos4__) && defined(__NEWLIB__))
6dead956
GS
2910 RETVAL = not_here("sigaction");
2911#else
3a8a1642 2912# This code is really grody because we are trying to make the signal
2304df62
AD
2913# interface look beautiful, which is hard.
2914
2304df62 2915 {
27da23d5 2916 dVAR;
1dfe7606 2917 POSIX__SigAction action;
f584eb2d 2918 GV *siggv = gv_fetchpvs("SIG", GV_ADD, SVt_PVHV);
2304df62
AD
2919 struct sigaction act;
2920 struct sigaction oact;
1dfe7606 2921 sigset_t sset;
183bde56 2922 SV *osset_sv;
27c1a449 2923 sigset_t osset;
2304df62
AD
2924 POSIX__SigSet sigset;
2925 SV** svp;
1d81eac9 2926 SV** sigsvp;
3609ea0d 2927
516d25e8
SP
2928 if (sig < 0) {
2929 croak("Negative signals are not allowed");
2930 }
2931
1d81eac9 2932 if (sig == 0 && SvPOK(ST(0))) {
aa07b2f6 2933 const char *s = SvPVX_const(ST(0));
1d81eac9
JH
2934 int i = whichsig(s);
2935
2936 if (i < 0 && memEQ(s, "SIG", 3))
2937 i = whichsig(s + 3);
2938 if (i < 0) {
2939 if (ckWARN(WARN_SIGNAL))
2940 Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
2941 "No such signal: SIG%s", s);
2942 XSRETURN_UNDEF;
2943 }
2944 else
2945 sig = i;
2946 }
3609ea0d
JH
2947#ifdef NSIG
2948 if (sig > NSIG) { /* NSIG - 1 is still okay. */
2949 Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
2950 "No such signal: %d", sig);
2951 XSRETURN_UNDEF;
2952 }
2953#endif
1d81eac9
JH
2954 sigsvp = hv_fetch(GvHVn(siggv),
2955 PL_sig_name[sig],
2956 strlen(PL_sig_name[sig]),
2957 TRUE);
2304df62 2958
1dfe7606
AJ
2959 /* Check optaction and set action */
2960 if(SvTRUE(optaction)) {
2961 if(sv_isa(optaction, "POSIX::SigAction"))
2962 action = (HV*)SvRV(optaction);
2963 else
2964 croak("action is not of type POSIX::SigAction");
2965 }
2966 else {
2967 action=0;
2968 }
2969
2970 /* sigaction() is supposed to look atomic. In particular, any
2971 * signal handler invoked during a sigaction() call should
2972 * see either the old or the new disposition, and not something
2973 * in between. We use sigprocmask() to make it so.
2974 */
2975 sigfillset(&sset);
2976 RETVAL=sigprocmask(SIG_BLOCK, &sset, &osset);
2977 if(RETVAL == -1)
15c0d34a 2978 XSRETURN_UNDEF;
1dfe7606
AJ
2979 ENTER;
2980 /* Restore signal mask no matter how we exit this block. */
f584eb2d 2981 osset_sv = newSVpvn((char *)(&osset), sizeof(sigset_t));
183bde56 2982 SAVEFREESV( osset_sv );
40b7a5f5 2983 SAVEDESTRUCTOR_X(restore_sigmask, osset_sv);
1dfe7606
AJ
2984
2985 RETVAL=-1; /* In case both oldaction and action are 0. */
2986
2987 /* Remember old disposition if desired. */
2304df62 2988 if (oldaction) {
017a3ce5 2989 svp = hv_fetchs(oldaction, "HANDLER", TRUE);
1dfe7606
AJ
2990 if(!svp)
2991 croak("Can't supply an oldaction without a HANDLER");
2992 if(SvTRUE(*sigsvp)) { /* TBD: what if "0"? */
2993 sv_setsv(*svp, *sigsvp);
2994 }
2995 else {
f584eb2d 2996 sv_setpvs(*svp, "DEFAULT");
1dfe7606
AJ
2997 }
2998 RETVAL = sigaction(sig, (struct sigaction *)0, & oact);
6ca4bbc9
GG
2999 if(RETVAL == -1) {
3000 LEAVE;
15c0d34a 3001 XSRETURN_UNDEF;
6ca4bbc9 3002 }
1dfe7606 3003 /* Get back the mask. */
017a3ce5 3004 svp = hv_fetchs(oldaction, "MASK", TRUE);
1dfe7606 3005 if (sv_isa(*svp, "POSIX::SigSet")) {
92b39396 3006 sigset = (sigset_t *) SvPV_nolen(SvRV(*svp));
1dfe7606
AJ
3007 }
3008 else {
92b39396
NC
3009 sigset = (sigset_t *) allocate_struct(aTHX_ *svp,
3010 sizeof(sigset_t),
3011 "POSIX::SigSet");
1dfe7606
AJ
3012 }
3013 *sigset = oact.sa_mask;
3014
3015 /* Get back the flags. */
017a3ce5 3016 svp = hv_fetchs(oldaction, "FLAGS", TRUE);
1dfe7606 3017 sv_setiv(*svp, oact.sa_flags);
d36b6582
CS
3018
3019 /* Get back whether the old handler used safe signals. */
017a3ce5 3020 svp = hv_fetchs(oldaction, "SAFE", TRUE);
e91e3b10
RB
3021 sv_setiv(*svp,
3022 /* compare incompatible pointers by casting to integer */
3023 PTR2nat(oact.sa_handler) == PTR2nat(PL_csighandlerp));
2304df62
AD
3024 }
3025
3026 if (action) {
d36b6582
CS
3027 /* Safe signals use "csighandler", which vectors through the
3028 PL_sighandlerp pointer when it's safe to do so.
3029 (BTW, "csighandler" is very different from "sighandler".) */
017a3ce5 3030 svp = hv_fetchs(action, "SAFE", FALSE);
e91e3b10
RB
3031 act.sa_handler =
3032 DPTR2FPTR(
87d46f97 3033 void (*)(int),
e91e3b10
RB
3034 (*svp && SvTRUE(*svp))
3035 ? PL_csighandlerp : PL_sighandlerp
3036 );
d36b6582
CS
3037
3038 /* Vector new Perl handler through %SIG.
3039 (The core signal handlers read %SIG to dispatch.) */
017a3ce5 3040 svp = hv_fetchs(action, "HANDLER", FALSE);
2304df62
AD
3041 if (!svp)
3042 croak("Can't supply an action without a HANDLER");
1dfe7606 3043 sv_setsv(*sigsvp, *svp);
d36b6582
CS
3044
3045 /* This call actually calls sigaction() with almost the
3046 right settings, including appropriate interpretation
3047 of DEFAULT and IGNORE. However, why are we doing
3048 this when we're about to do it again just below? XXX */
17cffb37 3049 SvSETMAGIC(*sigsvp);
d36b6582
CS
3050
3051 /* And here again we duplicate -- DEFAULT/IGNORE checking. */
1dfe7606 3052 if(SvPOK(*svp)) {
aa07b2f6 3053 const char *s=SvPVX_const(*svp);
1dfe7606
AJ
3054 if(strEQ(s,"IGNORE")) {
3055 act.sa_handler = SIG_IGN;
3056 }
3057 else if(strEQ(s,"DEFAULT")) {
3058 act.sa_handler = SIG_DFL;
3059 }
1dfe7606 3060 }
2304df62
AD
3061
3062 /* Set up any desired mask. */
017a3ce5 3063 svp = hv_fetchs(action, "MASK", FALSE);
2304df62 3064 if (svp && sv_isa(*svp, "POSIX::SigSet")) {
92b39396 3065 sigset = (sigset_t *) SvPV_nolen(SvRV(*svp));
2304df62
AD
3066 act.sa_mask = *sigset;
3067 }
3068 else
85e6fe83 3069 sigemptyset(& act.sa_mask);
2304df62
AD
3070
3071 /* Set up any desired flags. */
017a3ce5 3072 svp = hv_fetchs(action, "FLAGS", FALSE);
2304df62 3073 act.sa_flags = svp ? SvIV(*svp) : 0;
2304df62 3074
1dfe7606
AJ
3075 /* Don't worry about cleaning up *sigsvp if this fails,
3076 * because that means we tried to disposition a
3077 * nonblockable signal, in which case *sigsvp is
3078 * essentially meaningless anyway.
3079 */
6c418a22 3080 RETVAL = sigaction(sig, & act, (struct sigaction *)0);
6ca4bbc9
GG
3081 if(RETVAL == -1) {
3082 LEAVE;
a7aad5de 3083 XSRETURN_UNDEF;
6ca4bbc9 3084 }
2304df62 3085 }
1dfe7606
AJ
3086
3087 LEAVE;
2304df62 3088 }
6dead956 3089#endif
2304df62
AD
3090 OUTPUT:
3091 RETVAL
3092
3093SysRet
3094sigpending(sigset)
3095 POSIX::SigSet sigset
7a004119
NC
3096 ALIAS:
3097 sigsuspend = 1
3098 CODE:
ea34f6bd 3099#ifdef __amigaos4__
30b42e09
AB
3100 RETVAL = not_here("sigpending");
3101#else
7a004119 3102 RETVAL = ix ? sigsuspend(sigset) : sigpending(sigset);
32a14dd4 3103#endif
7a004119
NC
3104 OUTPUT:
3105 RETVAL
20120e59
LT
3106 CLEANUP:
3107 PERL_ASYNC_CHECK();
2304df62
AD
3108
3109SysRet
3110sigprocmask(how, sigset, oldsigset = 0)
3111 int how
b13bbac7 3112 POSIX::SigSet sigset = NO_INIT
33c27489
GS
3113 POSIX::SigSet oldsigset = NO_INIT
3114INIT:
a3b811a7 3115 if (! SvOK(ST(1))) {
b13bbac7 3116 sigset = NULL;
a3b811a7 3117 } else if (sv_isa(ST(1), "POSIX::SigSet")) {
92b39396 3118 sigset = (sigset_t *) SvPV_nolen(SvRV(ST(1)));
b13bbac7
AB
3119 } else {
3120 croak("sigset is not of type POSIX::SigSet");
33c27489 3121 }
b13bbac7 3122
194cfca0 3123 if (items < 3 || ! SvOK(ST(2))) {
b13bbac7 3124 oldsigset = NULL;
a3b811a7 3125 } else if (sv_isa(ST(2), "POSIX::SigSet")) {
92b39396 3126 oldsigset = (sigset_t *) SvPV_nolen(SvRV(ST(2)));
b13bbac7
AB
3127 } else {
3128 croak("oldsigset is not of type POSIX::SigSet");
33c27489 3129 }
2304df62 3130
2304df62
AD
3131void
3132_exit(status)
3133 int status
8990e307 3134
85e6fe83 3135SysRet
8990e307
LW
3136dup2(fd1, fd2)
3137 int fd1
3138 int fd2
ad413e46 3139 CODE:
6e7b1a26 3140 if (fd1 >= 0 && fd2 >= 0) {
ad413e46 3141#ifdef WIN32
6e7b1a26
JH
3142 /* RT #98912 - More Microsoft muppetry - failing to
3143 actually implemented the well known documented POSIX
3144 behaviour for a POSIX API.
3145 http://msdn.microsoft.com/en-us/library/8syseb29.aspx */
3146 RETVAL = dup2(fd1, fd2) == -1 ? -1 : fd2;
ad413e46 3147#else
6e7b1a26 3148 RETVAL = dup2(fd1, fd2);
ad413e46 3149#endif
6e7b1a26
JH
3150 } else {
3151 SETERRNO(EBADF,RMS_IFI);
3152 RETVAL = -1;
3153 }
ad413e46
NC
3154 OUTPUT:
3155 RETVAL
8990e307 3156
4a9d6100 3157SV *
a0d0e21e 3158lseek(fd, offset, whence)
ddc7c5c7 3159 POSIX::Fd fd
85e6fe83
LW
3160 Off_t offset
3161 int whence
4a9d6100 3162 CODE:
ddc7c5c7
JH
3163 {
3164 Off_t pos = PerlLIO_lseek(fd, offset, whence);
3165 RETVAL = sizeof(Off_t) > sizeof(IV)
3166 ? newSVnv((NV)pos) : newSViv((IV)pos);
511343a2 3167 }
4a9d6100
GS
3168 OUTPUT:
3169 RETVAL
8990e307 3170
c5661c80 3171void
8990e307
LW
3172nice(incr)
3173 int incr
15f0f28a
AE
3174 PPCODE:
3175 errno = 0;
3176 if ((incr = nice(incr)) != -1 || errno == 0) {
3177 if (incr == 0)
d3d34884 3178 XPUSHs(newSVpvs_flags("0 but true", SVs_TEMP));
15f0f28a
AE
3179 else
3180 XPUSHs(sv_2mortal(newSViv(incr)));
3181 }
8990e307 3182
8063af02 3183void
8990e307 3184pipe()
85e6fe83
LW
3185 PPCODE:
3186 int fds[2];
85e6fe83 3187 if (pipe(fds) != -1) {
924508f0 3188 EXTEND(SP,2);
85e6fe83
LW
3189 PUSHs(sv_2mortal(newSViv(fds[0])));
3190 PUSHs(sv_2mortal(newSViv(fds[1])));
3191 }
8990e307 3192
85e6fe83 3193SysRet
a0d0e21e 3194read(fd, buffer, nbytes)
7747499c
TB
3195 PREINIT:
3196 SV *sv_buffer = SvROK(ST(1)) ? SvRV(ST(1)) : ST(1);
3197 INPUT:
ddc7c5c7 3198 POSIX::Fd fd
7747499c
TB
3199 size_t nbytes
3200 char * buffer = sv_grow( sv_buffer, nbytes+1 );
a0d0e21e 3201 CLEANUP:
7747499c 3202 if (RETVAL >= 0) {
b162af07 3203 SvCUR_set(sv_buffer, RETVAL);
7747499c
TB
3204 SvPOK_only(sv_buffer);
3205 *SvEND(sv_buffer) = '\0';
bbce6d69 3206 SvTAINTED_on(sv_buffer);
7747499c 3207 }
8990e307 3208
85e6fe83 3209SysRet
8990e307 3210setpgid(pid, pgid)
86200d5c
JH
3211 pid_t pid
3212 pid_t pgid
8990e307 3213
86200d5c 3214pid_t
8990e307
LW
3215setsid()
3216
86200d5c 3217pid_t
8990e307 3218tcgetpgrp(fd)
ddc7c5c7 3219 POSIX::Fd fd
8990e307 3220
85e6fe83 3221SysRet
8990e307 3222tcsetpgrp(fd, pgrp_id)
ddc7c5c7 3223 POSIX::Fd fd
86200d5c 3224 pid_t pgrp_id
8990e307 3225
8063af02 3226void
8990e307 3227uname()
2304df62 3228 PPCODE:
a0d0e21e 3229#ifdef HAS_UNAME
85e6fe83 3230 struct utsname buf;
85e6fe83 3231 if (uname(&buf) >= 0) {
924508f0 3232 EXTEND(SP, 5);
d3d34884
NC
3233 PUSHs(newSVpvn_flags(buf.sysname, strlen(buf.sysname), SVs_TEMP));
3234 PUSHs(newSVpvn_flags(buf.nodename, strlen(buf.nodename), SVs_TEMP));
3235 PUSHs(newSVpvn_flags(buf.release, strlen(buf.release), SVs_TEMP));
3236 PUSHs(newSVpvn_flags(buf.version, strlen(buf.version), SVs_TEMP));
3237 PUSHs(newSVpvn_flags(buf.machine, strlen(buf.machine), SVs_TEMP));
8990e307 3238 }
a0d0e21e
LW
3239#else
3240 uname((char *) 0); /* A stub to call not_here(). */
3241#endif
8990e307 3242
85e6fe83 3243SysRet
a0d0e21e 3244write(fd, buffer, nbytes)
ddc7c5c7 3245 POSIX::Fd fd
a0d0e21e
LW
3246 char * buffer
3247 size_t nbytes
3248
a0d0e21e
LW
3249void
3250abort()
3251
3252int
3253mblen(s, n)
3254 char * s
3255 size_t n
3256
3257size_t
3258mbstowcs(s, pwcs, n)
3259 wchar_t * s
3260 char * pwcs
3261 size_t n
3262
3263int
3264mbtowc(pwc, s, n)
3265 wchar_t * pwc
3266 char * s
3267 size_t n
3268
3269int
3270wcstombs(s, pwcs, n)
3271 char * s
3272 wchar_t * pwcs
3273 size_t n
3274
3275int
3276wctomb(s, wchar)
3277 char * s
3278 wchar_t wchar
3279
3280int
3281strcoll(s1, s2)
3282 char * s1
3283 char * s2
3284
a89d8a78
DH
3285void
3286strtod(str)
3287 char * str
3288 PREINIT:
3289 double num;
3290 char *unparsed;
3291 PPCODE:
67d796ae
KW
3292 DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
3293 STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
a89d8a78
DH
3294 num = strtod(str, &unparsed);
3295 PUSHs(sv_2mortal(newSVnv(num)));
de915ff5 3296 if (GIMME_V == G_ARRAY) {
924508f0 3297 EXTEND(SP, 1);
a89d8a78
DH
3298 if (unparsed)
3299 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3300 else
6b88bc9c 3301 PUSHs(&PL_sv_undef);
a89d8a78 3302 }
67d796ae 3303 RESTORE_LC_NUMERIC_STANDARD();
a89d8a78 3304
0ff7b9da
JH
3305#ifdef HAS_STRTOLD
3306
3307void
3308strtold(str)
3309 char * str
3310 PREINIT:
3311 long double num;
3312 char *unparsed;
3313 PPCODE:
67d796ae
KW
3314 DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
3315 STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
0ff7b9da
JH
3316 num = strtold(str, &unparsed);
3317 PUSHs(sv_2mortal(newSVnv(num)));
de915ff5 3318 if (GIMME_V == G_ARRAY) {
0ff7b9da
JH
3319 EXTEND(SP, 1);
3320 if (unparsed)
3321 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3322 else
3323 PUSHs(&PL_sv_undef);
3324 }
67d796ae 3325 RESTORE_LC_NUMERIC_STANDARD();
0ff7b9da
JH
3326
3327#endif
3328
a89d8a78
DH
3329void
3330strtol(str, base = 0)
3331 char * str
3332 int base
3333 PREINIT:
3334 long num;
3335 char *unparsed;
3336 PPCODE:
e80fee22
JH
3337 if (base == 0 || (base >= 2 && base <= 36)) {
3338 num = strtol(str, &unparsed, base);
188f97e0 3339#if IVSIZE < LONGSIZE
e80fee22
JH
3340 if (num < IV_MIN || num > IV_MAX)
3341 PUSHs(sv_2mortal(newSVnv((double)num)));
3342 else
3343#endif
3344 PUSHs(sv_2mortal(newSViv((IV)num)));
3345 if (GIMME_V == G_ARRAY) {
3346 EXTEND(SP, 1);
3347 if (unparsed)
3348 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3349 else
3350 PUSHs(&PL_sv_undef);
3351 }
3352 } else {
3353 SETERRNO(EINVAL, LIB_INVARG);
3354 PUSHs(&PL_sv_undef);
3355 if (GIMME_V == G_ARRAY) {
3356 EXTEND(SP, 1);
3357 PUSHs(&PL_sv_undef);
3358 }
3359 }
a89d8a78
DH
3360
3361void
3362strtoul(str, base = 0)
4b48cf39 3363 const char * str
a89d8a78
DH
3364 int base
3365 PREINIT:
3366 unsigned long num;
3367 char *unparsed;
3368 PPCODE:
0f17be83
JH
3369 PERL_UNUSED_VAR(str);
3370 PERL_UNUSED_VAR(base);
e80fee22
JH
3371 if (base == 0 || (base >= 2 && base <= 36)) {
3372 num = strtoul(str, &unparsed, base);
84c133a0 3373#if IVSIZE <= LONGSIZE
e80fee22
JH
3374 if (num > IV_MAX)
3375 PUSHs(sv_2mortal(newSVnv((double)num)));
3376 else
3377#endif
3378 PUSHs(sv_2mortal(newSViv((IV)num)));
3379 if (GIMME_V == G_ARRAY) {
3380 EXTEND(SP, 1);
3381 if (unparsed)
3382 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3383 else
3384 PUSHs(&PL_sv_undef);
3385 }
3386 } else {
3387 SETERRNO(EINVAL, LIB_INVARG);
3388 PUSHs(&PL_sv_undef);
3389 if (GIMME_V == G_ARRAY) {
3390 EXTEND(SP, 1);
3391 PUSHs(&PL_sv_undef);
3392 }
3393 }
a89d8a78 3394
8063af02 3395void
a0d0e21e
LW
3396strxfrm(src)
3397 SV * src
85e6fe83 3398 CODE:
a0d0e21e
LW
3399 {
3400 STRLEN srclen;
3401 STRLEN dstlen;
6ec5f825 3402 STRLEN buflen;
a0d0e21e
LW
3403 char *p = SvPV(src,srclen);
3404 srclen++;
6ec5f825
TC
3405 buflen = srclen * 4 + 1;
3406 ST(0) = sv_2mortal(newSV(buflen));
3407 dstlen = strxfrm(SvPVX(ST(0)), p, (size_t)buflen);
3408 if (dstlen >= buflen) {
a0d0e21e
LW
3409 dstlen++;
3410 SvGROW(ST(0), dstlen);
3411 strxfrm(SvPVX(ST(0)), p, (size_t)dstlen);
3412 dstlen--;
3413 }
b162af07 3414 SvCUR_set(ST(0), dstlen);
a0d0e21e
LW
3415 SvPOK_only(ST(0));
3416 }
3417
3418SysRet
3419mkfifo(filename, mode)
3420 char * filename
3421 Mode_t mode
b5890904
NC
3422 ALIAS:
3423 access = 1
748a9306 3424 CODE:
b5890904
NC
3425 if(ix) {
3426 RETVAL = access(filename, mode);
3427 } else {
3428 TAINT_PROPER("mkfifo");
3429 RETVAL = mkfifo(filename, mode);
3430 }
748a9306
LW
3431 OUTPUT:
3432 RETVAL
a0d0e21e
LW
3433
3434SysRet
3435tcdrain(fd)
ddc7c5c7 3436 POSIX::Fd fd
9163475a
NC
3437 ALIAS:
3438 close = 1
3439 dup = 2
3440 CODE:
05732f97
JH
3441 if (fd >= 0) {
3442 RETVAL = ix == 1 ? close(fd)
3443 : (ix < 1 ? tcdrain(fd) : dup(fd));
3444 } else {
3445 SETERRNO(EBADF,RMS_IFI);
3446 RETVAL = -1;
3447 }
9163475a
NC
3448 OUTPUT:
3449 RETVAL
a0d0e21e
LW
3450
3451
3452SysRet
3453tcflow(fd, action)
ddc7c5c7 3454 POSIX::Fd fd
a0d0e21e 3455 int action
7a004119
NC
3456 ALIAS:
3457 tcflush = 1
3458 tcsendbreak = 2
3459 CODE:
ddc7c5c7 3460 if (action >= 0) {
af823f60
JH
3461 RETVAL = ix == 1 ? tcflush(fd, action)
3462 : (ix < 1 ? tcflow(fd, action) : tcsendbreak(fd, action));
3463 } else {
ddc7c5c7 3464 SETERRNO(EINVAL,LIB_INVARG);
af823f60
JH
3465 RETVAL = -1;
3466 }
7a004119
NC
3467 OUTPUT:
3468 RETVAL
a0d0e21e 3469
250d97fd 3470void
c1646883 3471asctime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = -1)
a0d0e21e
LW
3472 int sec
3473 int min
3474 int hour
3475 int mday
3476 int mon
3477 int year
3478 int wday
3479 int yday
3480 int isdst
250d97fd
NC
3481 ALIAS:
3482 mktime = 1
3483 PPCODE:
a0d0e21e 3484 {
250d97fd 3485 dXSTARG;
a0d0e21e 3486 struct tm mytm;
a748fe11 3487 init_tm(&mytm); /* XXX workaround - see init_tm() in core util.c */
a0d0e21e
LW
3488 mytm.tm_sec = sec;
3489 mytm.tm_min = min;
3490 mytm.tm_hour = hour;
3491 mytm.tm_mday = mday;
3492 mytm.tm_mon = mon;
3493 mytm.tm_year = year;
3494 mytm.tm_wday = wday;
3495 mytm.tm_yday = yday;
3496 mytm.tm_isdst = isdst;
250d97fd 3497 if (ix) {
e2054bce
TC
3498 const time_t result = mktime(&mytm);
3499 if (result == (time_t)-1)
250d97fd
NC
3500 SvOK_off(TARG);
3501 else if (result == 0)
3502 sv_setpvn(TARG, "0 but true", 10);
3503 else
3504 sv_setiv(TARG, (IV)result);
3505 } else {
3506 sv_setpv(TARG, asctime(&mytm));
3507 }
3508 ST(0) = TARG;
3509 XSRETURN(1);
a0d0e21e 3510 }
a0d0e21e
LW
3511
3512long
3513clock()
3514
3515char *
3516ctime(time)
748a9306 3517 Time_t &time
8990e307 3518
37120919
AD
3519void
3520times()
3521 PPCODE:
3522 struct tms tms;
3523 clock_t realtime;
3524 realtime = times( &tms );
924508f0 3525 EXTEND(SP,5);
9607fc9c 3526 PUSHs( sv_2mortal( newSViv( (IV) realtime ) ) );
3527 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_utime ) ) );
3528 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_stime ) ) );
3529 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cutime ) ) );
3530 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cstime ) ) );
37120919 3531
a0d0e21e
LW
3532double
3533difftime(time1, time2)
3534 Time_t time1
3535 Time_t time2
3536
8063af02
DM
3537#XXX: if $xsubpp::WantOptimize is always the default
3538# sv_setpv(TARG, ...) could be used rather than
3539# ST(0) = sv_2mortal(newSVpv(...))
3540void
e44f695e 3541strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1)
dc57de01 3542 SV * fmt
a0d0e21e
LW
3543 int sec
3544 int min
3545 int hour
3546 int mday
3547 int mon
3548 int year
3549 int wday
3550 int yday
3551 int isdst
3552 CODE:
3553 {
5d37acd6 3554 char *buf;
f406a445 3555 SV *sv;
5d37acd6
DM
3556
3557 /* allowing user-supplied (rather than literal) formats
3558 * is normally frowned upon as a potential security risk;
3559 * but this is part of the API so we have to allow it */
3560 GCC_DIAG_IGNORE(-Wformat-nonliteral);
3561 buf = my_strftime(SvPV_nolen(fmt), sec, min, hour, mday, mon, year, wday, yday, isdst);
3562 GCC_DIAG_RESTORE;
f406a445 3563 sv = sv_newmortal();
2a74cb2d 3564 if (buf) {
9717af6d
KW
3565 STRLEN len = strlen(buf);
3566 sv_usepvn_flags(sv, buf, len, SV_HAS_TRAILING_NUL);
3567 if (SvUTF8(fmt)
9f10db87 3568 || (! is_invariant_string((U8*) buf, len)
9717af6d 3569 && is_utf8_string((U8*) buf, len)
323fd7cc 3570#ifdef USE_LOCALE_TIME
130c5df3
KW
3571 && _is_cur_LC_category_utf8(LC_TIME)
3572#endif
3573 )) {
8dbe7cf7
NC
3574 SvUTF8_on(sv);
3575 }
f406a445
KW
3576 }
3577 else { /* We can't distinguish between errors and just an empty
3578 * return; in all cases just return an empty string */
3579 SvUPGRADE(sv, SVt_PV);
3580 SvPV_set(sv, (char *) "");
3581 SvPOK_on(sv);
3582 SvCUR_set(sv, 0);
3583 SvLEN_set(sv, 0); /* Won't attempt to free the string when sv
3584 gets destroyed */
3585 }
3586 ST(0) = sv;
a0d0e21e
LW
3587 }
3588
3589void
3590tzset()
81ab4c44
SH
3591 PPCODE:
3592 my_tzset(aTHX);
a0d0e21e
LW
3593
3594void
3595tzname()
3596 PPCODE:
924508f0 3597 EXTEND(SP,2);
d3d34884
NC
3598 PUSHs(newSVpvn_flags(tzname[0], strlen(tzname[0]), SVs_TEMP));
3599 PUSHs(newSVpvn_flags(tzname[1], strlen(tzname[1]), SVs_TEMP));
a0d0e21e 3600
a0d0e21e
LW
3601char *
3602ctermid(s = 0)
3ab23a19
RGS
3603 char * s = 0;
3604 CODE:
3605#ifdef HAS_CTERMID_R
e02b9112 3606 s = (char *) safemalloc((size_t) L_ctermid);
3ab23a19
RGS
3607#endif
3608 RETVAL = ctermid(s);
3609 OUTPUT:
3610 RETVAL
d1fd7089 3611 CLEANUP:
3ab23a19 3612#ifdef HAS_CTERMID_R
d1fd7089 3613 Safefree(s);
3ab23a19 3614#endif
a0d0e21e
LW
3615
3616char *
3617cuserid(s = 0)
3618 char * s = 0;
56f4542c
TJ
3619 CODE:
3620#ifdef HAS_CUSERID
3621 RETVAL = cuserid(s);
3622#else
3d50e539 3623 PERL_UNUSED_VAR(s);
56f4542c
TJ
3624 RETVAL = 0;
3625 not_here("cuserid");
3626#endif
3627 OUTPUT:
3628 RETVAL
a0d0e21e
LW
3629
3630SysRetLong
3631fpathconf(fd, name)
ddc7c5c7 3632 POSIX::Fd fd
a0d0e21e
LW
3633 int name
3634
3635SysRetLong
3636pathconf(filename, name)
3637 char * filename
3638 int name
3639
3640SysRet
3641pause()
20120e59
LT
3642 CLEANUP:
3643 PERL_ASYNC_CHECK();
a0d0e21e 3644
a387c53a
NC
3645unsigned int
3646sleep(seconds)
3647 unsigned int seconds
3648 CODE:
3649 RETVAL = PerlProc_sleep(seconds);
3650 OUTPUT:
3651 RETVAL
3652
a043a685
GW
3653SysRet
3654setgid(gid)
3655 Gid_t gid
3656
3657SysRet
3658setuid(uid)
3659 Uid_t uid
3660
a0d0e21e
LW
3661SysRetLong
3662sysconf(name)
3663 int name
3664
3665char *
3666ttyname(fd)
ddc7c5c7 3667 POSIX::Fd fd
a043a685 3668