7 * Ideally this should be somewhere down in the includes
8 * but putting it in other places is giving compiler errors.
9 * Also here I am unable to check for HAS_UNAME since it wouldn't have
10 * yet come into the file at this stage - sgp 18th Oct 2000
12 #include <sys/utsname.h>
15 #define PERL_NO_GET_CONTEXT
18 #define PERLIO_NOT_STDIO 1
22 static int not_here(const char *s);
24 #if defined(PERL_IMPLICIT_SYS)
28 # define open PerlLIO_open3
31 #ifdef I_DIRENT /* XXX maybe better to just rely on perl.h? */
36 #include <sys/errno2.h>
40 #if !(defined(__vax__) && defined(__NetBSD__))
60 # include <sys/time.h>
64 # include <sys/resource.h>
67 /* Cygwin's stdio.h doesn't make cuserid() visible with -D_GNU_SOURCE,
74 #if defined(USE_QUADMATH) && defined(I_QUADMATH)
91 # define M_LOG2E M_LOG2Eq
92 # define M_LOG10E M_LOG10Eq
94 # define M_LN10 M_LN10q
96 # define M_PI_2 M_PI_2q
97 # define M_PI_4 M_PI_4q
98 # define M_1_PI M_1_PIq
99 # define M_2_PI M_2_PIq
100 # define M_2_SQRTPI M_2_SQRTPIq
101 # define M_SQRT2 M_SQRT2q
102 # define M_SQRT1_2 M_SQRT1_2q
106 # ifdef USE_LONG_DOUBLE
120 # define FLOAT_C(c) CAT2(c,L)
122 # define FLOAT_C(c) (c)
126 # define M_E FLOAT_C(2.71828182845904523536028747135266250)
129 # define M_LOG2E FLOAT_C(1.44269504088896340735992468100189214)
132 # define M_LOG10E FLOAT_C(0.434294481903251827651128918916605082)
135 # define M_LN2 FLOAT_C(0.693147180559945309417232121458176568)
138 # define M_LN10 FLOAT_C(2.30258509299404568401799145468436421)
141 # define M_PI FLOAT_C(3.14159265358979323846264338327950288)
144 # define M_PI_2 FLOAT_C(1.57079632679489661923132169163975144)
147 # define M_PI_4 FLOAT_C(0.785398163397448309615660845819875721)
150 # define M_1_PI FLOAT_C(0.318309886183790671537767526745028724)
153 # define M_2_PI FLOAT_C(0.636619772367581343075535053490057448)
156 # define M_2_SQRTPI FLOAT_C(1.12837916709551257389615890312154517)
159 # define M_SQRT2 FLOAT_C(1.41421356237309504880168872420969808)
162 # define M_SQRT1_2 FLOAT_C(0.707106781186547524400844362104849039)
167 #if !defined(INFINITY) && defined(NV_INF)
168 # define INFINITY NV_INF
171 #if !defined(NAN) && defined(NV_NAN)
175 #if !defined(Inf) && defined(NV_INF)
179 #if !defined(NaN) && defined(NV_NAN)
183 /* We will have an emulation. */
185 # define FP_INFINITE 0
188 # define FP_SUBNORMAL 3
192 /* We will have an emulation. */
194 # define FE_TOWARDZERO 0
195 # define FE_TONEAREST 1
197 # define FE_DOWNWARD 3
202 acos asin atan atan2 ceil cos cosh exp fabs floor fmod frexp ldexp
203 log log10 modf pow sin sinh sqrt tan tanh
205 * Implemented in core:
207 atan2 cos exp log pow sin sqrt
211 acosh asinh atanh cbrt copysign erf erfc exp2 expm1 fdim fma fmax
212 fmin fpclassify hypot ilogb isfinite isgreater isgreaterequal isinf
213 isless islessequal islessgreater isnan isnormal isunordered lgamma
214 log1p log2 logb lrint lround nan nearbyint nextafter nexttoward remainder
215 remquo rint round scalbn signbit tgamma trunc
218 http://pubs.opengroup.org/onlinepubs/009695399/basedefs/math.h.html
220 * Berkeley/SVID extensions:
224 * Configure already (5.21.5) scans for:
226 copysign*l* fpclassify isfinite isinf isnan isnan*l* ilogb*l* signbit scalbn*l*
228 * For floating-point round mode (which matters for e.g. lrint and rint)
230 fegetround fesetround
234 /* XXX Constant FP_FAST_FMA (if true, FMA is faster) */
236 /* XXX Add ldiv(), lldiv()? It's C99, but from stdlib.h, not math.h */
238 /* XXX Beware old gamma() -- one cannot know whether that is the
239 * gamma or the log of gamma, that's why the new tgamma and lgamma.
240 * Though also remember lgamma_r. */
242 /* Certain AIX releases have the C99 math, but not in long double.
243 * The <math.h> has them, e.g. __expl128, but no library has them!
245 * Also see the comments in hints/aix.sh about long doubles. */
247 #if defined(USE_QUADMATH) && defined(I_QUADMATH)
248 # define c99_acosh acoshq
249 # define c99_asinh asinhq
250 # define c99_atanh atanhq
251 # define c99_cbrt cbrtq
252 # define c99_copysign copysignq
253 # define c99_erf erfq
254 # define c99_erfc erfcq
256 # define c99_expm1 expm1q
257 # define c99_fdim fdimq
258 # define c99_fma fmaq
259 # define c99_fmax fmaxq
260 # define c99_fmin fminq
261 # define c99_hypot hypotq
262 # define c99_ilogb ilogbq
263 # define c99_lgamma lgammaq
264 # define c99_log1p log1pq
265 # define c99_log2 log2q
267 # if defined(USE_64_BIT_INT) && QUADKIND == QUAD_IS_LONG_LONG
268 # define c99_lrint llrintq
269 # define c99_lround llroundq
271 # define c99_lrint lrintq
272 # define c99_lround lroundq
274 # define c99_nan nanq
275 # define c99_nearbyint nearbyintq
276 # define c99_nextafter nextafterq
278 # define c99_remainder remainderq
279 # define c99_remquo remquoq
280 # define c99_rint rintq
281 # define c99_round roundq
282 # define c99_scalbn scalbnq
283 # define c99_signbit signbitq
284 # define c99_tgamma tgammaq
285 # define c99_trunc truncq
286 # define bessel_j0 j0q
287 # define bessel_j1 j1q
288 # define bessel_jn jnq
289 # define bessel_y0 y0q
290 # define bessel_y1 y1q
291 # define bessel_yn ynq
292 #elif defined(USE_LONG_DOUBLE) && \
293 (defined(HAS_FREXPL) || defined(HAS_ILOGBL)) && defined(HAS_SQRTL)
294 /* Use some of the Configure scans for long double math functions
295 * as the canary for all the C99 *l variants being defined. */
296 # define c99_acosh acoshl
297 # define c99_asinh asinhl
298 # define c99_atanh atanhl
299 # define c99_cbrt cbrtl
300 # define c99_copysign copysignl
301 # define c99_erf erfl
302 # define c99_erfc erfcl
303 # define c99_exp2 exp2l
304 # define c99_expm1 expm1l
305 # define c99_fdim fdiml
306 # define c99_fma fmal
307 # define c99_fmax fmaxl
308 # define c99_fmin fminl
309 # define c99_hypot hypotl
310 # define c99_ilogb ilogbl
311 # define c99_lgamma lgammal
312 # define c99_log1p log1pl
313 # define c99_log2 log2l
314 # define c99_logb logbl
315 # if defined(USE_64_BIT_INT) && QUADKIND == QUAD_IS_LONG_LONG && defined(HAS_LLRINTL)
316 # define c99_lrint llrintl
317 # elif defined(HAS_LRINTL)
318 # define c99_lrint lrintl
320 # if defined(USE_64_BIT_INT) && QUADKIND == QUAD_IS_LONG_LONG && defined(HAS_LLROUNDL)
321 # define c99_lround llroundl
322 # elif defined(HAS_LROUNDL)
323 # define c99_lround lroundl
325 # define c99_nan nanl
326 # define c99_nearbyint nearbyintl
327 # define c99_nextafter nextafterl
328 # define c99_nexttoward nexttowardl
329 # define c99_remainder remainderl
330 # define c99_remquo remquol
331 # define c99_rint rintl
332 # define c99_round roundl
333 # define c99_scalbn scalbnl
334 # ifdef HAS_SIGNBIT /* possibly bad assumption */
335 # define c99_signbit signbitl
337 # define c99_tgamma tgammal
338 # define c99_trunc truncl
340 # define c99_acosh acosh
341 # define c99_asinh asinh
342 # define c99_atanh atanh
343 # define c99_cbrt cbrt
344 # define c99_copysign copysign
346 # define c99_erfc erfc
347 # define c99_exp2 exp2
348 # define c99_expm1 expm1
349 # define c99_fdim fdim
351 # define c99_fmax fmax
352 # define c99_fmin fmin
353 # define c99_hypot hypot
354 # define c99_ilogb ilogb
355 # define c99_lgamma lgamma
356 # define c99_log1p log1p
357 # define c99_log2 log2
358 # define c99_logb logb
359 # if defined(USE_64_BIT_INT) && QUADKIND == QUAD_IS_LONG_LONG && defined(HAS_LLRINT)
360 # define c99_lrint llrint
362 # define c99_lrint lrint
364 # if defined(USE_64_BIT_INT) && QUADKIND == QUAD_IS_LONG_LONG && defined(HAS_LLROUND)
365 # define c99_lround llround
367 # define c99_lround lround
370 # define c99_nearbyint nearbyint
371 # define c99_nextafter nextafter
372 # define c99_nexttoward nexttoward
373 # define c99_remainder remainder
374 # define c99_remquo remquo
375 # define c99_rint rint
376 # define c99_round round
377 # define c99_scalbn scalbn
378 /* We already define Perl_signbit in perl.h. */
380 # define c99_signbit signbit
382 # define c99_tgamma tgamma
383 # define c99_trunc trunc
386 /* AIX xlc (__IBMC__) really doesn't have the following long double
387 * math interfaces (no __acoshl128 aka acoshl, etc.), see
388 * hints/aix.sh. These are in the -lc128 but fail to be found
389 * during dynamic linking/loading.
391 * XXX1 Better Configure scans
392 * XXX2 Is this xlc version dependent? */
393 #if defined(USE_LONG_DOUBLE) && defined(__IBMC__)
413 # undef c99_nearbyint
414 # undef c99_nextafter
415 # undef c99_nexttoward
416 # undef c99_remainder
427 # define isunordered(x, y) (Perl_isnan(x) || Perl_isnan(y))
428 # elif defined(HAS_UNORDERED)
429 # define isunordered(x, y) unordered(x, y)
433 /* XXX these isgreater/isnormal/isunordered macros definitions should
434 * be moved further in the file to be part of the emulations, so that
435 * platforms can e.g. #undef c99_isunordered and have it work like
436 * it does for the other interfaces. */
438 #if !defined(isgreater) && defined(isunordered)
439 # define isgreater(x, y) (!isunordered((x), (y)) && (x) > (y))
440 # define isgreaterequal(x, y) (!isunordered((x), (y)) && (x) >= (y))
441 # define isless(x, y) (!isunordered((x), (y)) && (x) < (y))
442 # define islessequal(x, y) (!isunordered((x), (y)) && (x) <= (y))
443 # define islessgreater(x, y) (!isunordered((x), (y)) && \
444 ((x) > (y) || (y) > (x)))
447 /* Check both the Configure symbol and the macro-ness (like C99 promises). */
448 #if defined(HAS_FPCLASSIFY) && defined(fpclassify)
449 # define c99_fpclassify fpclassify
451 /* Like isnormal(), the isfinite(), isinf(), and isnan() are also C99
452 and also (sizeof-arg-aware) macros, but they are already well taken
453 care of by Configure et al, and defined in perl.h as
454 Perl_isfinite(), Perl_isinf(), and Perl_isnan(). */
456 # define c99_isnormal isnormal
458 #ifdef isgreater /* canary for all the C99 is*<cmp>* macros. */
459 # define c99_isgreater isgreater
460 # define c99_isgreaterequal isgreaterequal
461 # define c99_isless isless
462 # define c99_islessequal islessequal
463 # define c99_islessgreater islessgreater
464 # define c99_isunordered isunordered
467 /* The Great Wall of Undef where according to the definedness of HAS_FOO symbols
468 * the corresponding c99_foo wrappers are undefined. This list doesn't include
469 * the isfoo() interfaces because they are either type-aware macros, or dealt
470 * separately, already in perl.h */
511 #ifndef HAS_FPCLASSIFY
512 # undef c99_fpclassify
541 #ifndef HAS_NEARBYINT
542 # undef c99_nearbyint
544 #ifndef HAS_NEXTAFTER
545 # undef c99_nextafter
547 #ifndef HAS_NEXTTOWARD
548 # undef c99_nexttoward
550 #ifndef HAS_REMAINDER
551 # undef c99_remainder
577 /* Some APIs exist under Win32 with "underbar" names. */
580 # undef c99_nextafter
581 # define c99_hypot _hypot
582 # define c99_logb _logb
583 # define c99_nextafter _nextafter
585 # define bessel_j0 _j0
586 # define bessel_j1 _j1
587 # define bessel_jn _jn
588 # define bessel_y0 _y0
589 # define bessel_y1 _y1
590 # define bessel_yn _yn
594 /* The Bessel functions: BSD, SVID, XPG4, and POSIX. But not C99. */
595 #if defined(HAS_J0) && !defined(bessel_j0)
596 # if defined(USE_LONG_DOUBLE) && defined(HAS_J0L)
597 # define bessel_j0 j0l
598 # define bessel_j1 j1l
599 # define bessel_jn jnl
600 # define bessel_y0 y0l
601 # define bessel_y1 y1l
602 # define bessel_yn ynl
604 # define bessel_j0 j0
605 # define bessel_j1 j1
606 # define bessel_jn jn
607 # define bessel_y0 y0
608 # define bessel_y1 y1
609 # define bessel_yn yn
613 /* Emulations for missing math APIs.
615 * Keep in mind that the point of many of these functions is that
616 * they, if available, are supposed to give more precise/more
617 * numerically stable results.
619 * See e.g. http://www.johndcook.com/math_h.html
623 static NV my_acosh(NV x)
625 return Perl_log(x + Perl_sqrt(x * x - 1));
627 # define c99_acosh my_acosh
631 static NV my_asinh(NV x)
633 return Perl_log(x + Perl_sqrt(x * x + 1));
635 # define c99_asinh my_asinh
639 static NV my_atanh(NV x)
641 return (Perl_log(1 + x) - Perl_log(1 - x)) / 2;
643 # define c99_atanh my_atanh
647 static NV my_cbrt(NV x)
649 static const NV one_third = (NV)1.0/3;
650 return x >= 0.0 ? Perl_pow(x, one_third) : -Perl_pow(-x, one_third);
652 # define c99_cbrt my_cbrt
656 static NV my_copysign(NV x, NV y)
658 return y >= 0 ? (x < 0 ? -x : x) : (x < 0 ? x : -x);
660 # define c99_copysign my_copysign
663 /* XXX cosh (though c89) */
666 static NV my_erf(NV x)
668 /* http://www.johndcook.com/cpp_erf.html -- public domain */
670 NV a2 = -0.284496736;
672 NV a4 = -1.453152027;
676 int sign = x < 0 ? -1 : 1; /* Save the sign. */
679 /* Abramowitz and Stegun formula 7.1.26 */
680 t = 1.0 / (1.0 + p * x);
681 y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1) * t * Perl_exp(-x*x);
685 # define c99_erf my_erf
689 static NV my_erfc(NV x) {
690 /* This is not necessarily numerically stable, but better than nothing. */
691 return 1.0 - c99_erf(x);
693 # define c99_erfc my_erfc
697 static NV my_exp2(NV x)
699 return Perl_pow((NV)2.0, x);
701 # define c99_exp2 my_exp2
705 static NV my_expm1(NV x)
707 if (PERL_ABS(x) < 1e-5)
708 /* http://www.johndcook.com/cpp_expm1.html -- public domain.
709 * Taylor series, the first four terms (the last term quartic). */
710 /* Probably not enough for long doubles. */
711 return x * (1.0 + x * (1/2.0 + x * (1/6.0 + x/24.0)));
713 return Perl_exp(x) - 1;
715 # define c99_expm1 my_expm1
719 static NV my_fdim(NV x, NV y)
722 return (Perl_isnan(x) || Perl_isnan(y)) ? NV_NAN : (x > y ? x - y : 0);
724 return (x > y ? x - y : 0);
727 # define c99_fdim my_fdim
731 static NV my_fma(NV x, NV y, NV z)
735 # define c99_fma my_fma
739 static NV my_fmax(NV x, NV y)
743 return Perl_isnan(y) ? NV_NAN : y;
744 } else if (Perl_isnan(y)) {
748 return x > y ? x : y;
750 # define c99_fmax my_fmax
754 static NV my_fmin(NV x, NV y)
758 return Perl_isnan(y) ? NV_NAN : y;
759 } else if (Perl_isnan(y)) {
763 return x < y ? x : y;
765 # define c99_fmin my_fmin
768 #ifndef c99_fpclassify
770 static IV my_fpclassify(NV x)
772 #ifdef Perl_fp_class_inf
773 if (Perl_fp_class_inf(x)) return FP_INFINITE;
774 if (Perl_fp_class_nan(x)) return FP_NAN;
775 if (Perl_fp_class_norm(x)) return FP_NORMAL;
776 if (Perl_fp_class_denorm(x)) return FP_SUBNORMAL;
777 if (Perl_fp_class_zero(x)) return FP_ZERO;
778 # define c99_fpclassify my_fpclassify
786 static NV my_hypot(NV x, NV y)
788 /* http://en.wikipedia.org/wiki/Hypot */
790 x = PERL_ABS(x); /* Take absolute values. */
798 if (x < y) { /* Swap so that y is less. */
804 return x * Perl_sqrt(1.0 + t * t);
806 # define c99_hypot my_hypot
810 static IV my_ilogb(NV x)
812 return (IV)(Perl_log(x) * M_LOG2E);
814 # define c99_ilogb my_ilogb
817 /* tgamma and lgamma emulations based on
818 * http://www.johndcook.com/cpp_gamma.html,
819 * code placed in public domain.
821 * Note that these implementations (neither the johndcook originals
822 * nor these) do NOT set the global signgam variable. This is not
823 * necessarily a bad thing. */
825 /* Note that the tgamma() and lgamma() implementations
826 * here depend on each other. */
828 #if !defined(HAS_TGAMMA) || !defined(c99_tgamma)
829 static NV my_tgamma(NV x);
830 # define c99_tgamma my_tgamma
831 # define USE_MY_TGAMMA
833 #if !defined(HAS_LGAMMA) || !defined(c99_lgamma)
834 static NV my_lgamma(NV x);
835 # define c99_lgamma my_lgamma
836 # define USE_MY_LGAMMA
840 static NV my_tgamma(NV x)
842 const NV gamma = 0.577215664901532860606512090; /* Euler's gamma constant. */
844 if (Perl_isnan(x) || x < 0.0)
848 if (x == 0.0 || x == NV_INF)
849 #ifdef DOUBLE_IS_IEEE_FORMAT
850 return x == -0.0 ? -NV_INF : NV_INF;
856 /* The function domain is split into three intervals:
857 * (0, 0.001), [0.001, 12), and (12, infinity) */
859 /* First interval: (0, 0.001)
860 * For small values, 1/tgamma(x) has power series x + gamma x^2,
861 * so in this range, 1/tgamma(x) = x + gamma x^2 with error on the order of x^3.
862 * The relative error over this interval is less than 6e-7. */
864 return 1.0 / (x * (1.0 + gamma * x));
866 /* Second interval: [0.001, 12) */
868 double y = x; /* Working copy. */
870 /* Numerator coefficients for approximation over the interval (1,2) */
871 static const NV p[] = {
872 -1.71618513886549492533811E+0,
873 2.47656508055759199108314E+1,
874 -3.79804256470945635097577E+2,
875 6.29331155312818442661052E+2,
876 8.66966202790413211295064E+2,
877 -3.14512729688483675254357E+4,
878 -3.61444134186911729807069E+4,
879 6.64561438202405440627855E+4
881 /* Denominator coefficients for approximation over the interval (1, 2) */
882 static const NV q[] = {
883 -3.08402300119738975254353E+1,
884 3.15350626979604161529144E+2,
885 -1.01515636749021914166146E+3,
886 -3.10777167157231109440444E+3,
887 2.25381184209801510330112E+4,
888 4.75584627752788110767815E+3,
889 -1.34659959864969306392456E+5,
890 -1.15132259675553483497211E+5
901 n = (int)Perl_floor(y) - 1;
905 for (i = 0; i < 8; i++) {
906 num = (num + p[i]) * z;
907 den = den * z + q[i];
909 result = num / den + 1.0;
912 /* Use the identity tgamma(z) = tgamma(z+1)/z
913 * The variable "result" now holds tgamma of the original y + 1
914 * Thus we use y - 1 to get back the original y. */
918 /* Use the identity tgamma(z+n) = z*(z+1)* ... *(z+n-1)*tgamma(z) */
919 for (i = 0; i < n; i++)
927 /* Third interval: [12, +Inf) */
928 #if LDBL_MANT_DIG == 113 /* IEEE quad prec */
939 return Perl_exp(c99_lgamma(x));
944 static NV my_lgamma(NV x)
951 if (x <= 0 || x == NV_INF)
954 if (x == 1.0 || x == 2.0)
957 return Perl_log(PERL_ABS(c99_tgamma(x)));
958 /* Abramowitz and Stegun 6.1.41
959 * Asymptotic series should be good to at least 11 or 12 figures
960 * For error analysis, see Whittiker and Watson
961 * A Course in Modern Analysis (1927), page 252 */
963 static const NV c[8] = {
973 NV z = 1.0 / (x * x);
975 static const NV half_log_of_two_pi =
976 0.91893853320467274178032973640562;
979 for (i = 6; i >= 0; i--) {
984 return (x - 0.5) * Perl_log(x) - x + half_log_of_two_pi + series;
990 static NV my_log1p(NV x)
992 /* http://www.johndcook.com/cpp_log_one_plus_x.html -- public domain.
993 * Taylor series, the first four terms (the last term quartic). */
1002 if (PERL_ABS(x) > 1e-4)
1003 return Perl_log(1.0 + x);
1005 /* Probably not enough for long doubles. */
1006 return x * (1.0 + x * (-1/2.0 + x * (1/3.0 - x/4.0)));
1008 # define c99_log1p my_log1p
1012 static NV my_log2(NV x)
1014 return Perl_log(x) * M_LOG2E;
1016 # define c99_log2 my_log2
1021 /* XXX nexttoward */
1023 static int my_fegetround()
1025 #ifdef HAS_FEGETROUND
1026 return fegetround();
1027 #elif defined(HAS_FPGETROUND)
1028 switch (fpgetround()) {
1029 case FP_RN: return FE_TONEAREST;
1030 case FP_RZ: return FE_TOWARDZERO;
1031 case FP_RM: return FE_DOWNWARD;
1032 case FP_RP: return FE_UPWARD;
1035 #elif defined(FLT_ROUNDS)
1036 switch (FLT_ROUNDS) {
1037 case 0: return FE_TOWARDZERO;
1038 case 1: return FE_TONEAREST;
1039 case 2: return FE_UPWARD;
1040 case 3: return FE_DOWNWARD;
1043 #elif defined(__osf__) /* Tru64 */
1044 switch (read_rnd()) {
1045 case FP_RND_RN: return FE_TONEAREST;
1046 case FP_RND_RZ: return FE_TOWARDZERO;
1047 case FP_RND_RM: return FE_DOWNWARD;
1048 case FP_RND_RP: return FE_UPWARD;
1056 /* Toward closest integer. */
1057 #define MY_ROUND_NEAREST(x) ((NV)((IV)((x) >= 0.0 ? (x) + 0.5 : (x) - 0.5)))
1060 #define MY_ROUND_TRUNC(x) ((NV)((IV)(x)))
1062 /* Toward minus infinity. */
1063 #define MY_ROUND_DOWN(x) ((NV)((IV)((x) >= 0.0 ? (x) : (x) - 0.5)))
1065 /* Toward plus infinity. */
1066 #define MY_ROUND_UP(x) ((NV)((IV)((x) >= 0.0 ? (x) + 0.5 : (x))))
1068 #if (!defined(c99_nearbyint) || !defined(c99_lrint)) && defined(FE_TONEAREST)
1069 static NV my_rint(NV x)
1072 switch (my_fegetround()) {
1073 case FE_TONEAREST: return MY_ROUND_NEAREST(x);
1074 case FE_TOWARDZERO: return MY_ROUND_TRUNC(x);
1075 case FE_DOWNWARD: return MY_ROUND_DOWN(x);
1076 case FE_UPWARD: return MY_ROUND_UP(x);
1079 #elif defined(HAS_FPGETROUND)
1080 switch (fpgetround()) {
1081 case FP_RN: return MY_ROUND_NEAREST(x);
1082 case FP_RZ: return MY_ROUND_TRUNC(x);
1083 case FP_RM: return MY_ROUND_DOWN(x);
1084 case FE_RP: return MY_ROUND_UP(x);
1089 NOT_REACHED; /* NOTREACHED */
1093 /* XXX nearbyint() and rint() are not really identical -- but the difference
1094 * is messy: nearbyint is defined NOT to raise FE_INEXACT floating point
1095 * exceptions, while rint() is defined to MAYBE raise them. At the moment
1096 * Perl is blissfully unaware of such fine detail of floating point. */
1097 #ifndef c99_nearbyint
1098 # ifdef FE_TONEAREST
1099 # define c99_nearbyrint my_rint
1104 # ifdef FE_TONEAREST
1105 static IV my_lrint(NV x)
1107 return (IV)my_rint(x);
1109 # define c99_lrint my_lrint
1114 static IV my_lround(NV x)
1116 return (IV)MY_ROUND_NEAREST(x);
1118 # define c99_lround my_lround
1126 # ifdef FE_TONEAREST
1127 # define c99_rint my_rint
1132 static NV my_round(NV x)
1134 return MY_ROUND_NEAREST(x);
1136 # define c99_round my_round
1140 # if defined(Perl_ldexp) && FLT_RADIX == 2
1141 static NV my_scalbn(NV x, int y)
1143 return Perl_ldexp(x, y);
1145 # define c99_scalbn my_scalbn
1149 /* XXX sinh (though c89) */
1151 /* tgamma -- see lgamma */
1153 /* XXX tanh (though c89) */
1156 static NV my_trunc(NV x)
1158 return MY_ROUND_TRUNC(x);
1160 # define c99_trunc my_trunc
1165 #undef NV_PAYLOAD_DEBUG
1167 /* NOTE: the NaN payload API implementation is hand-rolled, since the
1168 * APIs are only proposed ones as of June 2015, so very few, if any,
1169 * platforms have implementations yet, so HAS_SETPAYLOAD and such are
1170 * unlikely to be helpful.
1172 * XXX - if the core numification wants to actually generate
1173 * the nan payload in "nan(123)", and maybe "nans(456)", for
1174 * signaling payload", this needs to be moved to e.g. numeric.c
1175 * (look for grok_infnan)
1177 * Conversely, if the core stringification wants the nan payload
1178 * and/or the nan quiet/signaling distinction, S_getpayload()
1179 * from this file needs to be moved, to e.g. sv.c (look for S_infnan_2pv),
1180 * and the (trivial) functionality of issignaling() copied
1181 * (for generating "NaNS", or maybe even "NaNQ") -- or maybe there
1182 * are too many formatting parameters for simple stringification?
1185 /* While it might make sense for the payload to be UV or IV,
1186 * to avoid conversion loss, the proposed ISO interfaces use
1187 * a floating point input, which is then truncated to integer,
1188 * and only the integer part being used. This is workable,
1189 * except for: (1) the conversion loss (2) suboptimal for
1190 * 32-bit integer platforms. A workaround API for (2) and
1191 * in general for bit-honesty would be an array of integers
1192 * as the payload... but the proposed C API does nothing of
1194 #if NVSIZE == UVSIZE
1195 # define NV_PAYLOAD_TYPE UV
1197 # define NV_PAYLOAD_TYPE NV
1200 #if defined(USE_LONG_DOUBLE) && defined(LONGDOUBLE_DOUBLEDOUBLE)
1201 # define NV_PAYLOAD_SIZEOF_ASSERT(a) \
1202 STATIC_ASSERT_STMT(sizeof(a) == NVSIZE / 2)
1204 # define NV_PAYLOAD_SIZEOF_ASSERT(a) \
1205 STATIC_ASSERT_STMT(sizeof(a) == NVSIZE)
1208 static void S_setpayload(NV* nvp, NV_PAYLOAD_TYPE payload, bool signaling)
1211 static const U8 m[] = { NV_NAN_PAYLOAD_MASK };
1212 static const U8 p[] = { NV_NAN_PAYLOAD_PERM };
1213 UV a[(NVSIZE + UVSIZE - 1) / UVSIZE] = { 0 };
1215 NV_PAYLOAD_SIZEOF_ASSERT(m);
1216 NV_PAYLOAD_SIZEOF_ASSERT(p);
1218 /* Divide the input into the array in "base unsigned integer" in
1219 * little-endian order. Note that the integer might be smaller than
1220 * an NV (if UV is U32, for example). */
1221 #if NVSIZE == UVSIZE
1222 a[0] = payload; /* The trivial case. */
1225 NV t1 = c99_trunc(payload); /* towards zero (drop fractional) */
1226 #ifdef NV_PAYLOAD_DEBUG
1227 Perl_warn(aTHX_ "t1 = %" NVgf " (payload %" NVgf ")\n", t1, payload);
1230 a[0] = (UV)t1; /* Fast path, also avoids rounding errors (right?) */
1232 /* UVSIZE < NVSIZE or payload > UV_MAX.
1234 * This may happen for example if:
1235 * (1) UVSIZE == 32 and common 64-bit double NV
1236 * (32-bit system not using -Duse64bitint)
1237 * (2) UVSIZE == 64 and the x86-style 80-bit long double NV
1238 * (note that here the room for payload is actually the 64 bits)
1239 * (3) UVSIZE == 64 and the 128-bit IEEE 764 quadruple NV
1240 * (112 bits in mantissa, 111 bits room for payload)
1242 * NOTE: this is very sensitive to correctly functioning
1243 * fmod()/fmodl(), and correct casting of big-unsigned-integer to NV.
1244 * If these don't work right, especially the low order bits
1245 * are in danger. For example Solaris and AIX seem to have issues
1246 * here, especially if using 32-bit UVs. */
1248 for (i = 0, t2 = t1; i < (int)C_ARRAY_LENGTH(a); i++) {
1249 a[i] = (UV)Perl_fmod(t2, (NV)UV_MAX);
1250 t2 = Perl_floor(t2 / (NV)UV_MAX);
1255 #ifdef NV_PAYLOAD_DEBUG
1256 for (i = 0; i < (int)C_ARRAY_LENGTH(a); i++) {
1257 Perl_warn(aTHX_ "a[%d] = 0x%" UVxf "\n", i, a[i]);
1260 for (i = 0; i < (int)sizeof(p); i++) {
1261 if (m[i] && p[i] < sizeof(p)) {
1262 U8 s = (p[i] % UVSIZE) << 3;
1263 UV u = a[p[i] / UVSIZE] & ((UV)0xFF << s);
1264 U8 b = (U8)((u >> s) & m[i]);
1265 ((U8 *)(nvp))[i] &= ~m[i]; /* For NaNs with non-zero payload bits. */
1266 ((U8 *)(nvp))[i] |= b;
1267 #ifdef NV_PAYLOAD_DEBUG
1269 "set p[%2d] = %02x (i = %d, m = %02x, s = %2d, b = %02x, u = %08"
1270 UVxf ")\n", i, ((U8 *)(nvp))[i], i, m[i], s, b, u);
1272 a[p[i] / UVSIZE] &= ~u;
1276 NV_NAN_SET_SIGNALING(nvp);
1278 #ifdef USE_LONG_DOUBLE
1279 # if LONG_DOUBLEKIND == 3 || LONG_DOUBLEKIND == 4
1280 # if LONG_DOUBLESIZE > 10
1281 memset((char *)nvp + 10, '\0', LONG_DOUBLESIZE - 10); /* x86 long double */
1285 for (i = 0; i < (int)C_ARRAY_LENGTH(a); i++) {
1287 Perl_warn(aTHX_ "payload lost bits (%" UVxf ")", a[i]);
1291 #ifdef NV_PAYLOAD_DEBUG
1292 for (i = 0; i < NVSIZE; i++) {
1293 PerlIO_printf(Perl_debug_log, "%02x ", ((U8 *)(nvp))[i]);
1295 PerlIO_printf(Perl_debug_log, "\n");
1299 static NV_PAYLOAD_TYPE S_getpayload(NV nv)
1302 static const U8 m[] = { NV_NAN_PAYLOAD_MASK };
1303 static const U8 p[] = { NV_NAN_PAYLOAD_PERM };
1304 UV a[(NVSIZE + UVSIZE - 1) / UVSIZE] = { 0 };
1307 NV_PAYLOAD_SIZEOF_ASSERT(m);
1308 NV_PAYLOAD_SIZEOF_ASSERT(p);
1310 for (i = 0; i < (int)sizeof(p); i++) {
1311 if (m[i] && p[i] < NVSIZE) {
1312 U8 s = (p[i] % UVSIZE) << 3;
1313 a[p[i] / UVSIZE] |= (UV)(((U8 *)(&nv))[i] & m[i]) << s;
1316 for (i = (int)C_ARRAY_LENGTH(a) - 1; i >= 0; i--) {
1317 #ifdef NV_PAYLOAD_DEBUG
1318 Perl_warn(aTHX_ "a[%d] = %" UVxf "\n", i, a[i]);
1323 #ifdef NV_PAYLOAD_DEBUG
1324 for (i = 0; i < NVSIZE; i++) {
1325 PerlIO_printf(Perl_debug_log, "%02x ", ((U8 *)(&nv))[i]);
1327 PerlIO_printf(Perl_debug_log, "\n");
1332 #endif /* #ifdef NV_NAN */
1334 /* XXX This comment is just to make I_TERMIO and I_SGTTY visible to
1335 metaconfig for future extension writers. We don't use them in POSIX.
1336 (This is really sneaky :-) --AD
1338 #if defined(I_TERMIOS)
1339 #include <termios.h>
1345 #include <sys/stat.h>
1346 #include <sys/types.h>
1354 # if !defined(WIN32) && !defined(__CYGWIN__) && !defined(NETWARE) && !defined(__UWIN__)
1355 extern char *tzname[];
1358 #if !defined(WIN32) && !defined(__UWIN__) || (defined(__MINGW32__) && !defined(tzname))
1359 char *tzname[] = { "" , "" };
1363 #if defined(__VMS) && !defined(__POSIX_SOURCE)
1365 # include <utsname.h>
1368 # define mkfifo(a,b) (not_here("mkfifo"),-1)
1370 /* The POSIX notion of ttyname() is better served by getname() under VMS */
1371 static char ttnambuf[64];
1372 # define ttyname(fd) (isatty(fd) > 0 ? getname(fd,ttnambuf,0) : NULL)
1375 #if defined (__CYGWIN__)
1376 # define tzname _tzname
1378 #if defined (WIN32) || defined (NETWARE)
1380 # define mkfifo(a,b) not_here("mkfifo")
1381 # define ttyname(a) (char*)not_here("ttyname")
1382 # define sigset_t long
1385 # define mode_t short
1388 # define mode_t short
1390 # define tzset() not_here("tzset")
1392 # ifndef _POSIX_OPEN_MAX
1393 # define _POSIX_OPEN_MAX FOPEN_MAX /* XXX bogus ? */
1396 # define sigaction(a,b,c) not_here("sigaction")
1397 # define sigpending(a) not_here("sigpending")
1398 # define sigprocmask(a,b,c) not_here("sigprocmask")
1399 # define sigsuspend(a) not_here("sigsuspend")
1400 # define sigemptyset(a) not_here("sigemptyset")
1401 # define sigaddset(a,b) not_here("sigaddset")
1402 # define sigdelset(a,b) not_here("sigdelset")
1403 # define sigfillset(a) not_here("sigfillset")
1404 # define sigismember(a,b) not_here("sigismember")
1408 # define setuid(a) not_here("setuid")
1409 # define setgid(a) not_here("setgid")
1410 #endif /* NETWARE */
1411 #ifndef USE_LONG_DOUBLE
1412 # define strtold(s1,s2) not_here("strtold")
1413 #endif /* USE_LONG_DOUBLE */
1417 # if defined(OS2) || defined(__amigaos4__)
1418 # define mkfifo(a,b) not_here("mkfifo")
1419 # else /* !( defined OS2 ) */
1421 # define mkfifo(path, mode) (mknod((path), (mode) | S_IFIFO, 0))
1424 # endif /* !HAS_MKFIFO */
1429 # include <sys/times.h>
1431 # include <sys/utsname.h>
1433 # ifndef __amigaos4__
1434 # include <sys/wait.h>
1439 #endif /* WIN32 || NETWARE */
1443 typedef long SysRetLong;
1444 typedef sigset_t* POSIX__SigSet;
1445 typedef HV* POSIX__SigAction;
1446 typedef int POSIX__SigNo;
1447 typedef int POSIX__Fd;
1449 typedef struct termios* POSIX__Termios;
1450 #else /* Define termios types to int, and call not_here for the functions.*/
1451 #define POSIX__Termios int
1453 #define tcflag_t int
1455 #define cfgetispeed(x) not_here("cfgetispeed")
1456 #define cfgetospeed(x) not_here("cfgetospeed")
1457 #define tcdrain(x) not_here("tcdrain")
1458 #define tcflush(x,y) not_here("tcflush")
1459 #define tcsendbreak(x,y) not_here("tcsendbreak")
1460 #define cfsetispeed(x,y) not_here("cfsetispeed")
1461 #define cfsetospeed(x,y) not_here("cfsetospeed")
1462 #define ctermid(x) (char *) not_here("ctermid")
1463 #define tcflow(x,y) not_here("tcflow")
1464 #define tcgetattr(x,y) not_here("tcgetattr")
1465 #define tcsetattr(x,y,z) not_here("tcsetattr")
1468 /* Possibly needed prototypes */
1471 double strtod (const char *, char **);
1472 long strtol (const char *, char **, int);
1473 unsigned long strtoul (const char *, char **, int);
1475 long double strtold (const char *, char **);
1480 #ifndef HAS_DIFFTIME
1482 #define difftime(a,b) not_here("difftime")
1485 #ifndef HAS_FPATHCONF
1486 #define fpathconf(f,n) (SysRetLong) not_here("fpathconf")
1489 #define mktime(a) not_here("mktime")
1492 #define nice(a) not_here("nice")
1494 #ifndef HAS_PATHCONF
1495 #define pathconf(f,n) (SysRetLong) not_here("pathconf")
1498 #define sysconf(n) (SysRetLong) not_here("sysconf")
1500 #ifndef HAS_READLINK
1501 #define readlink(a,b,c) not_here("readlink")
1504 #define setpgid(a,b) not_here("setpgid")
1507 #define setsid() not_here("setsid")
1510 #define strcoll(s1,s2) not_here("strcoll")
1513 #define strtod(s1,s2) not_here("strtod")
1516 #define strtold(s1,s2) not_here("strtold")
1519 #define strtol(s1,s2,b) not_here("strtol")
1522 #define strtoul(s1,s2,b) not_here("strtoul")
1525 #define strxfrm(s1,s2,n) not_here("strxfrm")
1527 #ifndef HAS_TCGETPGRP
1528 #define tcgetpgrp(a) not_here("tcgetpgrp")
1530 #ifndef HAS_TCSETPGRP
1531 #define tcsetpgrp(a,b) not_here("tcsetpgrp")
1535 #define times(a) not_here("times")
1536 #endif /* NETWARE */
1539 #define uname(a) not_here("uname")
1542 #define waitpid(a,b,c) not_here("waitpid")
1547 #define mblen(a,b) not_here("mblen")
1550 #ifndef HAS_MBSTOWCS
1551 #define mbstowcs(s, pwcs, n) not_here("mbstowcs")
1554 #define mbtowc(pwc, s, n) not_here("mbtowc")
1556 #ifndef HAS_WCSTOMBS
1557 #define wcstombs(s, pwcs, n) not_here("wcstombs")
1560 #define wctomb(s, wchar) not_here("wcstombs")
1562 #if !defined(HAS_MBLEN) && !defined(HAS_MBSTOWCS) && !defined(HAS_MBTOWC) && !defined(HAS_WCSTOMBS) && !defined(HAS_WCTOMB)
1563 /* If we don't have these functions, then we wouldn't have gotten a typedef
1564 for wchar_t, the wide character type. Defining wchar_t allows the
1565 functions referencing it to compile. Its actual type is then meaningless,
1566 since without the above functions, all sections using it end up calling
1567 not_here() and croak. --Kaveh Ghazi (ghazi@noc.rutgers.edu) 9/18/94. */
1569 #define wchar_t char
1573 #ifndef HAS_LOCALECONV
1574 # define localeconv() not_here("localeconv")
1576 struct lconv_offset {
1581 static const struct lconv_offset lconv_strings[] = {
1582 #ifdef USE_LOCALE_NUMERIC
1583 {"decimal_point", STRUCT_OFFSET(struct lconv, decimal_point)},
1584 {"thousands_sep", STRUCT_OFFSET(struct lconv, thousands_sep)},
1585 # ifndef NO_LOCALECONV_GROUPING
1586 {"grouping", STRUCT_OFFSET(struct lconv, grouping)},
1589 #ifdef USE_LOCALE_MONETARY
1590 {"int_curr_symbol", STRUCT_OFFSET(struct lconv, int_curr_symbol)},
1591 {"currency_symbol", STRUCT_OFFSET(struct lconv, currency_symbol)},
1592 {"mon_decimal_point", STRUCT_OFFSET(struct lconv, mon_decimal_point)},
1593 # ifndef NO_LOCALECONV_MON_THOUSANDS_SEP
1594 {"mon_thousands_sep", STRUCT_OFFSET(struct lconv, mon_thousands_sep)},
1596 # ifndef NO_LOCALECONV_MON_GROUPING
1597 {"mon_grouping", STRUCT_OFFSET(struct lconv, mon_grouping)},
1599 {"positive_sign", STRUCT_OFFSET(struct lconv, positive_sign)},
1600 {"negative_sign", STRUCT_OFFSET(struct lconv, negative_sign)},
1605 #ifdef USE_LOCALE_NUMERIC
1607 /* The Linux man pages say these are the field names for the structure
1608 * components that are LC_NUMERIC; the rest being LC_MONETARY */
1609 # define isLC_NUMERIC_STRING(name) ( strEQ(name, "decimal_point") \
1610 || strEQ(name, "thousands_sep") \
1612 /* There should be no harm done \
1613 * checking for this, even if \
1614 * NO_LOCALECONV_GROUPING */ \
1615 || strEQ(name, "grouping"))
1617 # define isLC_NUMERIC_STRING(name) (0)
1620 static const struct lconv_offset lconv_integers[] = {
1621 #ifdef USE_LOCALE_MONETARY
1622 {"int_frac_digits", STRUCT_OFFSET(struct lconv, int_frac_digits)},
1623 {"frac_digits", STRUCT_OFFSET(struct lconv, frac_digits)},
1624 {"p_cs_precedes", STRUCT_OFFSET(struct lconv, p_cs_precedes)},
1625 {"p_sep_by_space", STRUCT_OFFSET(struct lconv, p_sep_by_space)},
1626 {"n_cs_precedes", STRUCT_OFFSET(struct lconv, n_cs_precedes)},
1627 {"n_sep_by_space", STRUCT_OFFSET(struct lconv, n_sep_by_space)},
1628 {"p_sign_posn", STRUCT_OFFSET(struct lconv, p_sign_posn)},
1629 {"n_sign_posn", STRUCT_OFFSET(struct lconv, n_sign_posn)},
1630 #ifdef HAS_LC_MONETARY_2008
1631 {"int_p_cs_precedes", STRUCT_OFFSET(struct lconv, int_p_cs_precedes)},
1632 {"int_p_sep_by_space", STRUCT_OFFSET(struct lconv, int_p_sep_by_space)},
1633 {"int_n_cs_precedes", STRUCT_OFFSET(struct lconv, int_n_cs_precedes)},
1634 {"int_n_sep_by_space", STRUCT_OFFSET(struct lconv, int_n_sep_by_space)},
1635 {"int_p_sign_posn", STRUCT_OFFSET(struct lconv, int_p_sign_posn)},
1636 {"int_n_sign_posn", STRUCT_OFFSET(struct lconv, int_n_sign_posn)},
1642 #endif /* HAS_LOCALECONV */
1644 #ifdef HAS_LONG_DOUBLE
1645 # if LONG_DOUBLESIZE > NVSIZE
1646 # undef HAS_LONG_DOUBLE /* XXX until we figure out how to use them */
1650 #ifndef HAS_LONG_DOUBLE
1662 /* Background: in most systems the low byte of the wait status
1663 * is the signal (the lowest 7 bits) and the coredump flag is
1664 * the eight bit, and the second lowest byte is the exit status.
1665 * BeOS bucks the trend and has the bytes in different order.
1666 * See beos/beos.c for how the reality is bent even in BeOS
1667 * to follow the traditional. However, to make the POSIX
1668 * wait W*() macros to work in BeOS, we need to unbend the
1669 * reality back in place. --jhi */
1670 /* In actual fact the code below is to blame here. Perl has an internal
1671 * representation of the exit status ($?), which it re-composes from the
1672 * OS's representation using the W*() POSIX macros. The code below
1673 * incorrectly uses the W*() macros on the internal representation,
1674 * which fails for OSs that have a different representation (namely BeOS
1675 * and Haiku). WMUNGE() is a hack that converts the internal
1676 * representation into the OS specific one, so that the W*() macros work
1677 * as expected. The better solution would be not to use the W*() macros
1678 * in the first place, though. -- Ingo Weinhold
1680 #if defined(__HAIKU__)
1681 # define WMUNGE(x) (((x) & 0xFF00) >> 8 | ((x) & 0x00FF) << 8)
1683 # define WMUNGE(x) (x)
1687 not_here(const char *s)
1689 croak("POSIX::%s not implemented on this architecture", s);
1693 #include "const-c.inc"
1696 restore_sigmask(pTHX_ SV *osset_sv)
1698 /* Fortunately, restoring the signal mask can't fail, because
1699 * there's nothing we can do about it if it does -- we're not
1700 * supposed to return -1 from sigaction unless the disposition
1703 #if !(defined(__amigaos4__) && defined(__NEWLIB__))
1704 sigset_t *ossetp = (sigset_t *) SvPV_nolen( osset_sv );
1705 (void)sigprocmask(SIG_SETMASK, ossetp, (sigset_t *)0);
1710 allocate_struct(pTHX_ SV *rv, const STRLEN size, const char *packname) {
1711 SV *const t = newSVrv(rv, packname);
1712 void *const p = sv_grow(t, size + 1);
1714 /* Ensure at least one use of not_here() to avoid "defined but not
1715 * used" warning. This is not at all related to allocate_struct(); I
1716 * just needed somewhere to dump it - DAPM */
1717 if (0) { not_here(""); }
1727 * (1) The CRT maintains its own copy of the environment, separate from
1728 * the Win32API copy.
1730 * (2) CRT getenv() retrieves from this copy. CRT putenv() updates this
1731 * copy, and then calls SetEnvironmentVariableA() to update the Win32API
1734 * (3) win32_getenv() and win32_putenv() call GetEnvironmentVariableA() and
1735 * SetEnvironmentVariableA() directly, bypassing the CRT copy of the
1738 * (4) The CRT strftime() "%Z" implementation calls __tzset(). That
1739 * calls CRT tzset(), but only the first time it is called, and in turn
1740 * that uses CRT getenv("TZ") to retrieve the timezone info from the CRT
1741 * local copy of the environment and hence gets the original setting as
1742 * perl never updates the CRT copy when assigning to $ENV{TZ}.
1744 * Therefore, we need to retrieve the value of $ENV{TZ} and call CRT
1745 * putenv() to update the CRT copy of the environment (if it is different)
1746 * whenever we're about to call tzset().
1748 * In addition to all that, when perl is built with PERL_IMPLICIT_SYS
1751 * (a) Each interpreter has its own copy of the environment inside the
1752 * perlhost structure. That allows applications that host multiple
1753 * independent Perl interpreters to isolate environment changes from
1754 * each other. (This is similar to how the perlhost mechanism keeps a
1755 * separate working directory for each Perl interpreter, so that calling
1756 * chdir() will not affect other interpreters.)
1758 * (b) Only the first Perl interpreter instantiated within a process will
1759 * "write through" environment changes to the process environment.
1761 * (c) Even the primary Perl interpreter won't update the CRT copy of the
1762 * the environment, only the Win32API copy (it calls win32_putenv()).
1764 * As with CPerlHost::Getenv() and CPerlHost::Putenv() themselves, it makes
1765 * sense to only update the process environment when inside the main
1766 * interpreter, but we don't have access to CPerlHost's m_bTopLevel member
1767 * from here so we'll just have to check PL_curinterp instead.
1769 * Therefore, we can simply #undef getenv() and putenv() so that those names
1770 * always refer to the CRT functions, and explicitly call win32_getenv() to
1771 * access perl's %ENV.
1773 * We also #undef malloc() and free() to be sure we are using the CRT
1774 * functions otherwise under PERL_IMPLICIT_SYS they are redefined to calls
1775 * into VMem::Malloc() and VMem::Free() and all allocations will be freed
1776 * when the Perl interpreter is being destroyed so we'd end up with a pointer
1777 * into deallocated memory in environ[] if a program embedding a Perl
1778 * interpreter continues to operate even after the main Perl interpreter has
1781 * Note that we don't free() the malloc()ed memory unless and until we call
1782 * malloc() again ourselves because the CRT putenv() function simply puts its
1783 * pointer argument into the environ[] array (it doesn't make a copy of it)
1784 * so this memory must otherwise be leaked.
1793 fix_win32_tzenv(void)
1795 static char* oldenv = NULL;
1797 const char* perl_tz_env = win32_getenv("TZ");
1798 const char* crt_tz_env = getenv("TZ");
1799 if (perl_tz_env == NULL)
1801 if (crt_tz_env == NULL)
1803 if (strNE(perl_tz_env, crt_tz_env)) {
1804 newenv = (char*)malloc((strlen(perl_tz_env) + 4) * sizeof(char));
1805 if (newenv != NULL) {
1806 sprintf(newenv, "TZ=%s", perl_tz_env);
1818 * my_tzset - wrapper to tzset() with a fix to make it work (better) on Win32.
1819 * This code is duplicated in the Time-Piece module, so any changes made here
1820 * should be made there too.
1826 #if defined(USE_ITHREADS) && defined(PERL_IMPLICIT_SYS)
1827 if (PL_curinterp == aTHX)
1834 MODULE = SigSet PACKAGE = POSIX::SigSet PREFIX = sig
1837 new(packname = "POSIX::SigSet", ...)
1838 const char * packname
1843 = (sigset_t *) allocate_struct(aTHX_ (ST(0) = sv_newmortal()),
1847 for (i = 1; i < items; i++)
1848 sigaddset(s, SvIV(ST(i)));
1854 POSIX::SigSet sigset
1859 RETVAL = ix ? sigdelset(sigset, sig) : sigaddset(sigset, sig);
1865 POSIX::SigSet sigset
1869 RETVAL = ix ? sigfillset(sigset) : sigemptyset(sigset);
1874 sigismember(sigset, sig)
1875 POSIX::SigSet sigset
1878 MODULE = Termios PACKAGE = POSIX::Termios PREFIX = cf
1881 new(packname = "POSIX::Termios", ...)
1882 const char * packname
1886 void *const p = allocate_struct(aTHX_ (ST(0) = sv_newmortal()),
1887 sizeof(struct termios), packname);
1888 /* The previous implementation stored a pointer to an uninitialised
1889 struct termios. Seems safer to initialise it, particularly as
1890 this implementation exposes the struct to prying from perl-space.
1892 memset(p, 0, 1 + sizeof(struct termios));
1895 not_here("termios");
1900 getattr(termios_ref, fd = 0)
1901 POSIX::Termios termios_ref
1904 RETVAL = tcgetattr(fd, termios_ref);
1908 # If we define TCSANOW here then both a found and not found constant sub
1909 # are created causing a Constant subroutine TCSANOW redefined warning
1912 # define DEF_SETATTR_ACTION 0
1914 # define DEF_SETATTR_ACTION TCSANOW
1917 setattr(termios_ref, fd = 0, optional_actions = DEF_SETATTR_ACTION)
1918 POSIX::Termios termios_ref
1920 int optional_actions
1922 /* The second argument to the call is mandatory, but we'd like to give
1923 it a useful default. 0 isn't valid on all operating systems - on
1924 Solaris (at least) TCSANOW, TCSADRAIN and TCSAFLUSH have the same
1925 values as the equivalent ioctls, TCSETS, TCSETSW and TCSETSF. */
1926 if (optional_actions < 0) {
1927 SETERRNO(EINVAL, LIB_INVARG);
1930 RETVAL = tcsetattr(fd, optional_actions, termios_ref);
1936 getispeed(termios_ref)
1937 POSIX::Termios termios_ref
1941 RETVAL = ix ? cfgetospeed(termios_ref) : cfgetispeed(termios_ref);
1946 getiflag(termios_ref)
1947 POSIX::Termios termios_ref
1953 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
1956 RETVAL = termios_ref->c_iflag;
1959 RETVAL = termios_ref->c_oflag;
1962 RETVAL = termios_ref->c_cflag;
1965 RETVAL = termios_ref->c_lflag;
1968 RETVAL = 0; /* silence compiler warning */
1971 not_here(GvNAME(CvGV(cv)));
1978 getcc(termios_ref, ccix)
1979 POSIX::Termios termios_ref
1982 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
1984 croak("Bad getcc subscript");
1985 RETVAL = termios_ref->c_cc[ccix];
1994 setispeed(termios_ref, speed)
1995 POSIX::Termios termios_ref
2001 ? cfsetospeed(termios_ref, speed) : cfsetispeed(termios_ref, speed);
2006 setiflag(termios_ref, flag)
2007 POSIX::Termios termios_ref
2014 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
2017 termios_ref->c_iflag = flag;
2020 termios_ref->c_oflag = flag;
2023 termios_ref->c_cflag = flag;
2026 termios_ref->c_lflag = flag;
2030 not_here(GvNAME(CvGV(cv)));
2034 setcc(termios_ref, ccix, cc)
2035 POSIX::Termios termios_ref
2039 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
2041 croak("Bad setcc subscript");
2042 termios_ref->c_cc[ccix] = cc;
2048 MODULE = POSIX PACKAGE = POSIX
2050 INCLUDE: const-xs.inc
2056 POSIX::WIFEXITED = 1
2057 POSIX::WIFSIGNALED = 2
2058 POSIX::WIFSTOPPED = 3
2062 #if !defined(WEXITSTATUS) || !defined(WIFEXITED) || !defined(WIFSIGNALED) \
2063 || !defined(WIFSTOPPED) || !defined(WSTOPSIG) || !defined(WTERMSIG)
2064 RETVAL = 0; /* Silence compilers that notice this, but don't realise
2065 that not_here() can't return. */
2070 RETVAL = WEXITSTATUS(WMUNGE(status));
2072 not_here("WEXITSTATUS");
2077 RETVAL = WIFEXITED(WMUNGE(status));
2079 not_here("WIFEXITED");
2084 RETVAL = WIFSIGNALED(WMUNGE(status));
2086 not_here("WIFSIGNALED");
2091 RETVAL = WIFSTOPPED(WMUNGE(status));
2093 not_here("WIFSTOPPED");
2098 RETVAL = WSTOPSIG(WMUNGE(status));
2100 not_here("WSTOPSIG");
2105 RETVAL = WTERMSIG(WMUNGE(status));
2107 not_here("WTERMSIG");
2111 croak("Illegal alias %d for POSIX::W*", (int)ix);
2117 open(filename, flags = O_RDONLY, mode = 0666)
2122 if (flags & (O_APPEND|O_CREAT|O_TRUNC|O_RDWR|O_WRONLY|O_EXCL))
2123 TAINT_PROPER("open");
2124 RETVAL = open(filename, flags, mode);
2132 #ifndef HAS_LOCALECONV
2133 localeconv(); /* A stub to call not_here(). */
2135 struct lconv *lcbuf;
2136 # if defined(USE_ITHREADS) \
2137 && defined(HAS_POSIX_2008_LOCALE) \
2138 && defined(HAS_LOCALECONV_L) /* Prefer this thread-safe version */
2139 bool do_free = FALSE;
2140 locale_t cur = NULL;
2141 # elif defined(TS_W32_BROKEN_LOCALECONV)
2142 const char * save_global;
2143 const char * save_thread;
2145 DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
2147 /* localeconv() deals with both LC_NUMERIC and LC_MONETARY, but
2148 * LC_MONETARY is already in the correct locale */
2149 # ifdef USE_LOCALE_MONETARY
2151 const bool is_monetary_utf8 = _is_cur_LC_category_utf8(LC_MONETARY);
2153 # ifdef USE_LOCALE_NUMERIC
2155 bool is_numeric_utf8;
2157 STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
2159 is_numeric_utf8 = _is_cur_LC_category_utf8(LC_NUMERIC);
2163 sv_2mortal((SV*)RETVAL);
2164 # if defined(USE_ITHREADS) \
2165 && defined(HAS_POSIX_2008_LOCALE) \
2166 && defined(HAS_LOCALECONV_L) \
2167 && defined(HAS_DUPLOCALE)
2169 cur = uselocale((locale_t) 0);
2170 if (cur == LC_GLOBAL_LOCALE) {
2171 cur = duplocale(LC_GLOBAL_LOCALE);
2175 lcbuf = localeconv_l(cur);
2177 LOCALE_LOCK_V; /* Prevent interference with other threads using
2179 # ifdef TS_W32_BROKEN_LOCALECONV
2180 /* This is a workaround for a Windows bug prior to VS 15, in which
2181 * localeconv only looks at the global locale. We toggle to the global
2182 * locale; populate the return; then toggle back. We have to use
2183 * LC_ALL instead of the individual ones because of another bug in
2186 save_thread = savepv(Perl_setlocale(LC_NUMERIC, NULL));
2188 _configthreadlocale(_DISABLE_PER_THREAD_LOCALE);
2190 save_global = savepv(Perl_setlocale(LC_ALL, NULL));
2192 Perl_setlocale(LC_ALL, save_thread);
2194 lcbuf = localeconv();
2197 const struct lconv_offset *strings = lconv_strings;
2198 const struct lconv_offset *integers = lconv_integers;
2199 const char *ptr = (const char *) lcbuf;
2201 while (strings->name) {
2202 /* This string may be controlled by either LC_NUMERIC, or
2204 const bool is_utf8_locale =
2205 # if defined(USE_LOCALE_NUMERIC) && defined(USE_LOCALE_MONETARY)
2206 (isLC_NUMERIC_STRING(strings->name))
2209 # elif defined(USE_LOCALE_NUMERIC)
2211 # elif defined(USE_LOCALE_MONETARY)
2217 const char *value = *((const char **)(ptr + strings->offset));
2219 if (value && *value) {
2220 const STRLEN value_len = strlen(value);
2222 /* We mark it as UTF-8 if a utf8 locale and is valid and
2223 * variant under UTF-8 */
2224 const bool is_utf8 = is_utf8_locale
2225 && is_utf8_non_invariant_string(
2228 (void) hv_store(RETVAL,
2230 strlen(strings->name),
2231 newSVpvn_utf8(value, value_len, is_utf8),
2237 while (integers->name) {
2238 const char value = *((const char *)(ptr + integers->offset));
2240 if (value != CHAR_MAX)
2241 (void) hv_store(RETVAL, integers->name,
2242 strlen(integers->name), newSViv(value), 0);
2246 # if defined(USE_ITHREADS) \
2247 && defined(HAS_POSIX_2008_LOCALE) \
2248 && defined(HAS_LOCALECONV_L)
2253 # ifdef TS_W32_BROKEN_LOCALECONV
2254 Perl_setlocale(LC_ALL, save_global);
2256 _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
2258 Perl_setlocale(LC_ALL, save_thread);
2260 Safefree(save_global);
2261 Safefree(save_thread);
2265 RESTORE_LC_NUMERIC();
2266 #endif /* HAS_LOCALECONV */
2271 setlocale(category, locale = 0)
2277 retval = (char *) Perl_setlocale(category, locale);
2329 RETVAL = Perl_acos(x); /* C89 math */
2333 RETVAL = c99_acosh(x);
2339 RETVAL = Perl_asin(x); /* C89 math */
2343 RETVAL = c99_asinh(x);
2349 RETVAL = Perl_atan(x); /* C89 math */
2353 RETVAL = c99_atanh(x);
2360 RETVAL = c99_cbrt(x);
2366 RETVAL = Perl_ceil(x); /* C89 math */
2369 RETVAL = Perl_cosh(x); /* C89 math */
2373 RETVAL = c99_erf(x);
2380 RETVAL = c99_erfc(x);
2387 RETVAL = c99_exp2(x);
2394 RETVAL = c99_expm1(x);
2400 RETVAL = Perl_floor(x); /* C89 math */
2404 RETVAL = bessel_j0(x);
2411 RETVAL = bessel_j1(x);
2417 /* XXX Note: the lgamma modifies a global variable (signgam),
2418 * which is evil. Some platforms have lgamma_r, which has
2419 * extra output parameter instead of the global variable. */
2421 RETVAL = c99_lgamma(x);
2427 RETVAL = Perl_log10(x); /* C89 math */
2431 RETVAL = c99_log1p(x);
2438 RETVAL = c99_log2(x);
2445 RETVAL = c99_logb(x);
2446 #elif defined(c99_log2) && FLT_RADIX == 2
2447 RETVAL = Perl_floor(c99_log2(PERL_ABS(x)));
2453 #ifdef c99_nearbyint
2454 RETVAL = c99_nearbyint(x);
2456 not_here("nearbyint");
2461 RETVAL = c99_rint(x);
2468 RETVAL = c99_round(x);
2474 RETVAL = Perl_sinh(x); /* C89 math */
2477 RETVAL = Perl_tan(x); /* C89 math */
2480 RETVAL = Perl_tanh(x); /* C89 math */
2484 RETVAL = c99_tgamma(x);
2491 RETVAL = c99_trunc(x);
2498 RETVAL = bessel_y0(x);
2506 RETVAL = bessel_y1(x);
2517 #ifdef HAS_FEGETROUND
2518 RETVAL = my_fegetround();
2521 not_here("fegetround");
2530 #ifdef HAS_FEGETROUND /* canary for fesetround */
2531 RETVAL = fesetround(x);
2532 #elif defined(HAS_FPGETROUND) /* canary for fpsetround */
2534 case FE_TONEAREST: RETVAL = fpsetround(FP_RN); break;
2535 case FE_TOWARDZERO: RETVAL = fpsetround(FP_RZ); break;
2536 case FE_DOWNWARD: RETVAL = fpsetround(FP_RM); break;
2537 case FE_UPWARD: RETVAL = fpsetround(FP_RP); break;
2538 default: RETVAL = -1; break;
2540 #elif defined(__osf__) /* Tru64 */
2542 case FE_TONEAREST: RETVAL = write_rnd(FP_RND_RN); break;
2543 case FE_TOWARDZERO: RETVAL = write_rnd(FP_RND_RZ); break;
2544 case FE_DOWNWARD: RETVAL = write_rnd(FP_RND_RM); break;
2545 case FE_UPWARD: RETVAL = write_rnd(FP_RND_RP); break;
2546 default: RETVAL = -1; break;
2551 not_here("fesetround");
2573 #ifdef c99_fpclassify
2574 RETVAL = c99_fpclassify(x);
2576 not_here("fpclassify");
2581 RETVAL = c99_ilogb(x);
2587 RETVAL = Perl_isfinite(x);
2590 RETVAL = Perl_isinf(x);
2593 RETVAL = Perl_isnan(x);
2597 RETVAL = c99_isnormal(x);
2599 not_here("isnormal");
2604 RETVAL = c99_lrint(x);
2611 RETVAL = c99_lround(x);
2619 RETVAL = Perl_signbit(x);
2622 #ifdef DOUBLE_IS_IEEE_FORMAT
2637 #ifdef DOUBLE_HAS_NAN
2638 RETVAL = S_getpayload(nv);
2640 PERL_UNUSED_VAR(nv);
2642 not_here("getpayload");
2648 setpayload(nv, payload)
2652 #ifdef DOUBLE_HAS_NAN
2653 S_setpayload(&nv, payload, FALSE);
2655 PERL_UNUSED_VAR(nv);
2656 PERL_UNUSED_VAR(payload);
2657 not_here("setpayload");
2663 setpayloadsig(nv, payload)
2667 #ifdef DOUBLE_HAS_NAN
2669 S_setpayload(&nv, payload, TRUE);
2671 PERL_UNUSED_VAR(nv);
2672 PERL_UNUSED_VAR(payload);
2673 not_here("setpayloadsig");
2682 #ifdef DOUBLE_HAS_NAN
2683 RETVAL = Perl_isnan(nv) && NV_NAN_IS_SIGNALING(&nv);
2685 PERL_UNUSED_VAR(nv);
2687 not_here("issignaling");
2722 RETVAL = c99_copysign(x, y);
2724 not_here("copysign");
2729 RETVAL = c99_fdim(x, y);
2736 RETVAL = c99_fmax(x, y);
2743 RETVAL = c99_fmin(x, y);
2749 RETVAL = Perl_fmod(x, y); /* C89 math */
2753 RETVAL = c99_hypot(x, y);
2759 #ifdef c99_isgreater
2760 RETVAL = c99_isgreater(x, y);
2762 not_here("isgreater");
2766 #ifdef c99_isgreaterequal
2767 RETVAL = c99_isgreaterequal(x, y);
2769 not_here("isgreaterequal");
2774 RETVAL = c99_isless(x, y);
2780 #ifdef c99_islessequal
2781 RETVAL = c99_islessequal(x, y);
2783 not_here("islessequal");
2787 #ifdef c99_islessgreater
2788 RETVAL = c99_islessgreater(x, y);
2790 not_here("islessgreater");
2794 #ifdef c99_isunordered
2795 RETVAL = c99_isunordered(x, y);
2797 not_here("isunordered");
2801 #ifdef c99_nextafter
2802 RETVAL = c99_nextafter(x, y);
2804 not_here("nextafter");
2808 #ifdef c99_nexttoward
2809 RETVAL = c99_nexttoward(x, y);
2811 not_here("nexttoward");
2816 #ifdef c99_remainder
2817 RETVAL = c99_remainder(x, y);
2819 not_here("remainder");
2831 /* (We already know stack is long enough.) */
2832 PUSHs(sv_2mortal(newSVnv(Perl_frexp(x,&expvar)))); /* C89 math */
2833 PUSHs(sv_2mortal(newSViv(expvar)));
2840 RETVAL = Perl_ldexp(x, exp);
2849 /* (We already know stack is long enough.) */
2850 PUSHs(sv_2mortal(newSVnv(Perl_modf(x,&intvar)))); /* C89 math */
2851 PUSHs(sv_2mortal(newSVnv(intvar)));
2860 PUSHs(sv_2mortal(newSVnv(c99_remquo(x,y,&intvar))));
2861 PUSHs(sv_2mortal(newSVnv(intvar)));
2874 RETVAL = c99_scalbn(x, y);
2891 RETVAL = c99_fma(x, y, z);
2906 /* If no payload given, just return the default NaN.
2907 * This makes a difference in platforms where the default
2908 * NaN is not all zeros. */
2912 S_setpayload(&RETVAL, payload, FALSE);
2914 #elif defined(c99_nan)
2916 STRLEN elen = my_snprintf(PL_efloatbuf, PL_efloatsize, "%g", payload);
2917 if ((IV)elen == -1) {
2925 RETVAL = c99_nan(PL_efloatbuf);
2949 RETVAL = bessel_jn(x, y);
2959 RETVAL = bessel_yn(x, y);
2971 sigaction(sig, optaction, oldaction = 0)
2974 POSIX::SigAction oldaction
2976 #if defined(WIN32) || defined(NETWARE) || (defined(__amigaos4__) && defined(__NEWLIB__))
2977 RETVAL = not_here("sigaction");
2979 # This code is really grody because we are trying to make the signal
2980 # interface look beautiful, which is hard.
2984 POSIX__SigAction action;
2985 GV *siggv = gv_fetchpvs("SIG", GV_ADD, SVt_PVHV);
2986 struct sigaction act;
2987 struct sigaction oact;
2991 POSIX__SigSet sigset;
2996 croak("Negative signals are not allowed");
2999 if (sig == 0 && SvPOK(ST(0))) {
3000 const char *s = SvPVX_const(ST(0));
3001 int i = whichsig(s);
3003 if (i < 0 && memBEGINs(s, SvCUR(ST(0)), "SIG"))
3004 i = whichsig(s + 3);
3006 if (ckWARN(WARN_SIGNAL))
3007 Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
3008 "No such signal: SIG%s", s);
3015 if (sig > NSIG) { /* NSIG - 1 is still okay. */
3016 Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
3017 "No such signal: %d", sig);
3021 sigsvp = hv_fetch(GvHVn(siggv),
3023 strlen(PL_sig_name[sig]),
3026 /* Check optaction and set action */
3027 if(SvTRUE(optaction)) {
3028 if(sv_isa(optaction, "POSIX::SigAction"))
3029 action = (HV*)SvRV(optaction);
3031 croak("action is not of type POSIX::SigAction");
3037 /* sigaction() is supposed to look atomic. In particular, any
3038 * signal handler invoked during a sigaction() call should
3039 * see either the old or the new disposition, and not something
3040 * in between. We use sigprocmask() to make it so.
3043 RETVAL=sigprocmask(SIG_BLOCK, &sset, &osset);
3047 /* Restore signal mask no matter how we exit this block. */
3048 osset_sv = newSVpvn((char *)(&osset), sizeof(sigset_t));
3049 SAVEFREESV( osset_sv );
3050 SAVEDESTRUCTOR_X(restore_sigmask, osset_sv);
3052 RETVAL=-1; /* In case both oldaction and action are 0. */
3054 /* Remember old disposition if desired. */
3058 svp = hv_fetchs(oldaction, "HANDLER", TRUE);
3060 croak("Can't supply an oldaction without a HANDLER");
3061 if(SvTRUE(*sigsvp)) { /* TBD: what if "0"? */
3062 sv_setsv(*svp, *sigsvp);
3065 sv_setpvs(*svp, "DEFAULT");
3067 RETVAL = sigaction(sig, (struct sigaction *)0, & oact);
3072 /* Get back the mask. */
3073 svp = hv_fetchs(oldaction, "MASK", TRUE);
3074 if (sv_isa(*svp, "POSIX::SigSet")) {
3075 sigset = (sigset_t *) SvPV_nolen(SvRV(*svp));
3078 sigset = (sigset_t *) allocate_struct(aTHX_ *svp,
3082 *sigset = oact.sa_mask;
3084 /* Get back the flags. */
3085 svp = hv_fetchs(oldaction, "FLAGS", TRUE);
3086 sv_setiv(*svp, oact.sa_flags);
3088 /* Get back whether the old handler used safe signals;
3089 * i.e. it used Perl_csighandler[13] rather than
3090 * Perl_sighandler[13]
3094 (oact.sa_flags & SA_SIGINFO)
3095 ? ( oact.sa_sigaction == PL_csighandler3p
3096 #ifdef PERL_USE_3ARG_SIGHANDLER
3097 || oact.sa_sigaction == PL_csighandlerp
3102 ( oact.sa_handler == PL_csighandler1p
3103 #ifndef PERL_USE_3ARG_SIGHANDLER
3104 || oact.sa_handler == PL_csighandlerp
3108 svp = hv_fetchs(oldaction, "SAFE", TRUE);
3109 sv_setiv(*svp, safe);
3115 /* Set up any desired flags. */
3116 svp = hv_fetchs(action, "FLAGS", FALSE);
3117 act.sa_flags = svp ? SvIV(*svp) : 0;
3119 /* Safe signals use "csighandler", which vectors through the
3120 PL_sighandlerp pointer when it's safe to do so.
3121 (BTW, "csighandler" is very different from "sighandler".) */
3122 svp = hv_fetchs(action, "SAFE", FALSE);
3123 safe = *svp && SvTRUE(*svp);
3125 if (act.sa_flags & SA_SIGINFO) {
3128 safe ? PL_csighandler3p : PL_sighandler3p;
3135 safe ? PL_csighandler1p : PL_sighandler1p;
3138 /* Vector new Perl handler through %SIG.
3139 (The core signal handlers read %SIG to dispatch.) */
3140 svp = hv_fetchs(action, "HANDLER", FALSE);
3142 croak("Can't supply an action without a HANDLER");
3143 sv_setsv(*sigsvp, *svp);
3145 /* This call actually calls sigaction() with almost the
3146 right settings, including appropriate interpretation
3147 of DEFAULT and IGNORE. However, why are we doing
3148 this when we're about to do it again just below? XXX */
3149 SvSETMAGIC(*sigsvp);
3151 /* And here again we duplicate -- DEFAULT/IGNORE checking. */
3153 const char *s=SvPVX_const(*svp);
3154 if(strEQ(s,"IGNORE")) {
3155 act.sa_handler = SIG_IGN;
3157 else if(strEQ(s,"DEFAULT")) {
3158 act.sa_handler = SIG_DFL;
3162 /* Set up any desired mask. */
3163 svp = hv_fetchs(action, "MASK", FALSE);
3164 if (svp && sv_isa(*svp, "POSIX::SigSet")) {
3165 sigset = (sigset_t *) SvPV_nolen(SvRV(*svp));
3166 act.sa_mask = *sigset;
3169 sigemptyset(& act.sa_mask);
3171 /* Don't worry about cleaning up *sigsvp if this fails,
3172 * because that means we tried to disposition a
3173 * nonblockable signal, in which case *sigsvp is
3174 * essentially meaningless anyway.
3176 RETVAL = sigaction(sig, & act, (struct sigaction *)0);
3191 POSIX::SigSet sigset
3196 RETVAL = not_here("sigpending");
3198 RETVAL = ix ? sigsuspend(sigset) : sigpending(sigset);
3206 sigprocmask(how, sigset, oldsigset = 0)
3208 POSIX::SigSet sigset = NO_INIT
3209 POSIX::SigSet oldsigset = NO_INIT
3211 if (! SvOK(ST(1))) {
3213 } else if (sv_isa(ST(1), "POSIX::SigSet")) {
3214 sigset = (sigset_t *) SvPV_nolen(SvRV(ST(1)));
3216 croak("sigset is not of type POSIX::SigSet");
3219 if (items < 3 || ! SvOK(ST(2))) {
3221 } else if (sv_isa(ST(2), "POSIX::SigSet")) {
3222 oldsigset = (sigset_t *) SvPV_nolen(SvRV(ST(2)));
3224 croak("oldsigset is not of type POSIX::SigSet");
3236 if (fd1 >= 0 && fd2 >= 0) {
3238 /* RT #98912 - More Microsoft muppetry - failing to
3239 actually implemented the well known documented POSIX
3240 behaviour for a POSIX API.
3241 http://msdn.microsoft.com/en-us/library/8syseb29.aspx */
3242 RETVAL = dup2(fd1, fd2) == -1 ? -1 : fd2;
3244 RETVAL = dup2(fd1, fd2);
3247 SETERRNO(EBADF,RMS_IFI);
3254 lseek(fd, offset, whence)
3260 Off_t pos = PerlLIO_lseek(fd, offset, whence);
3261 RETVAL = sizeof(Off_t) > sizeof(IV)
3262 ? newSVnv((NV)pos) : newSViv((IV)pos);
3272 if ((incr = nice(incr)) != -1 || errno == 0) {
3274 XPUSHs(newSVpvs_flags("0 but true", SVs_TEMP));
3276 XPUSHs(sv_2mortal(newSViv(incr)));
3283 if (pipe(fds) != -1) {
3285 PUSHs(sv_2mortal(newSViv(fds[0])));
3286 PUSHs(sv_2mortal(newSViv(fds[1])));
3290 read(fd, buffer, nbytes)
3292 SV *sv_buffer = SvROK(ST(1)) ? SvRV(ST(1)) : ST(1);
3296 char * buffer = sv_grow( sv_buffer, nbytes+1 );
3299 SvCUR_set(sv_buffer, RETVAL);
3300 SvPOK_only(sv_buffer);
3301 *SvEND(sv_buffer) = '\0';
3302 SvTAINTED_on(sv_buffer);
3318 tcsetpgrp(fd, pgrp_id)
3327 if (uname(&buf) >= 0) {
3329 PUSHs(newSVpvn_flags(buf.sysname, strlen(buf.sysname), SVs_TEMP));
3330 PUSHs(newSVpvn_flags(buf.nodename, strlen(buf.nodename), SVs_TEMP));
3331 PUSHs(newSVpvn_flags(buf.release, strlen(buf.release), SVs_TEMP));
3332 PUSHs(newSVpvn_flags(buf.version, strlen(buf.version), SVs_TEMP));
3333 PUSHs(newSVpvn_flags(buf.machine, strlen(buf.machine), SVs_TEMP));
3336 uname((char *) 0); /* A stub to call not_here(). */
3340 write(fd, buffer, nbytes)
3357 #if defined(USE_ITHREADS) && defined(HAS_MBRLEN)
3361 #if defined(USE_ITHREADS) && defined(HAS_MBRLEN)
3362 memset(&ps, 0, sizeof(ps)); /* Initialize state */
3363 RETVAL = mbrlen(s, n, &ps); /* Prefer reentrant version */
3365 /* This might prevent some races, but locales can be switched out
3366 * without locking, so this isn't a cure all */
3369 RETVAL = mblen(s, n);
3376 mbstowcs(s, pwcs, n)
3387 #if defined(USE_ITHREADS) && defined(HAS_MBRTOWC)
3391 #if defined(USE_ITHREADS) && defined(HAS_MBRTOWC)
3392 memset(&ps, 0, sizeof(ps));;
3393 PERL_UNUSED_RESULT(mbrtowc(pwc, NULL, 0, &ps));/* Reset any shift state */
3395 RETVAL = mbrtowc(pwc, s, n, &ps); /* Prefer reentrant version */
3397 RETVAL = mbtowc(pwc, s, n);
3403 wcstombs(s, pwcs, n)
3425 DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
3426 STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
3427 num = strtod(str, &unparsed);
3428 RESTORE_LC_NUMERIC();
3429 PUSHs(sv_2mortal(newSVnv(num)));
3430 if (GIMME_V == G_ARRAY) {
3433 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3435 PUSHs(&PL_sv_undef);
3447 DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
3448 STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
3449 num = strtold(str, &unparsed);
3450 RESTORE_LC_NUMERIC();
3451 PUSHs(sv_2mortal(newSVnv(num)));
3452 if (GIMME_V == G_ARRAY) {
3455 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3457 PUSHs(&PL_sv_undef);
3463 strtol(str, base = 0)
3470 if (base == 0 || inRANGE(base, 2, 36)) {
3471 num = strtol(str, &unparsed, base);
3472 #if IVSIZE < LONGSIZE
3473 if (num < IV_MIN || num > IV_MAX)
3474 PUSHs(sv_2mortal(newSVnv((double)num)));
3477 PUSHs(sv_2mortal(newSViv((IV)num)));
3478 if (GIMME_V == G_ARRAY) {
3481 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3483 PUSHs(&PL_sv_undef);
3486 SETERRNO(EINVAL, LIB_INVARG);
3487 PUSHs(&PL_sv_undef);
3488 if (GIMME_V == G_ARRAY) {
3490 PUSHs(&PL_sv_undef);
3495 strtoul(str, base = 0)
3500 char *unparsed = NULL;
3502 PERL_UNUSED_VAR(str);
3503 PERL_UNUSED_VAR(base);
3504 if (base == 0 || inRANGE(base, 2, 36)) {
3505 num = strtoul(str, &unparsed, base);
3506 #if IVSIZE <= LONGSIZE
3508 PUSHs(sv_2mortal(newSVnv((double)num)));
3511 PUSHs(sv_2mortal(newSViv((IV)num)));
3512 if (GIMME_V == G_ARRAY) {
3515 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3517 PUSHs(&PL_sv_undef);
3520 SETERRNO(EINVAL, LIB_INVARG);
3521 PUSHs(&PL_sv_undef);
3522 if (GIMME_V == G_ARRAY) {
3524 PUSHs(&PL_sv_undef);
3536 char *p = SvPV(src,srclen);
3538 buflen = srclen * 4 + 1;
3539 ST(0) = sv_2mortal(newSV(buflen));
3540 dstlen = strxfrm(SvPVX(ST(0)), p, (size_t)buflen);
3541 if (dstlen >= buflen) {
3543 SvGROW(ST(0), dstlen);
3544 strxfrm(SvPVX(ST(0)), p, (size_t)dstlen);
3547 SvCUR_set(ST(0), dstlen);
3552 mkfifo(filename, mode)
3559 RETVAL = access(filename, mode);
3561 TAINT_PROPER("mkfifo");
3562 RETVAL = mkfifo(filename, mode);
3575 RETVAL = ix == 1 ? close(fd)
3576 : (ix < 1 ? tcdrain(fd) : dup(fd));
3578 SETERRNO(EBADF,RMS_IFI);
3594 RETVAL = ix == 1 ? tcflush(fd, action)
3595 : (ix < 1 ? tcflow(fd, action) : tcsendbreak(fd, action));
3597 SETERRNO(EINVAL,LIB_INVARG);
3604 asctime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = -1)
3620 init_tm(&mytm); /* XXX workaround - see init_tm() in core util.c */
3623 mytm.tm_hour = hour;
3624 mytm.tm_mday = mday;
3626 mytm.tm_year = year;
3627 mytm.tm_wday = wday;
3628 mytm.tm_yday = yday;
3629 mytm.tm_isdst = isdst;
3631 const time_t result = mktime(&mytm);
3632 if (result == (time_t)-1)
3634 else if (result == 0)
3635 sv_setpvs(TARG, "0 but true");
3637 sv_setiv(TARG, (IV)result);
3639 sv_setpv(TARG, asctime(&mytm));
3657 realtime = times( &tms );
3659 PUSHs( sv_2mortal( newSViv( (IV) realtime ) ) );
3660 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_utime ) ) );
3661 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_stime ) ) );
3662 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cutime ) ) );
3663 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cstime ) ) );
3666 difftime(time1, time2)
3670 #XXX: if $xsubpp::WantOptimize is always the default
3671 # sv_setpv(TARG, ...) could be used rather than
3672 # ST(0) = sv_2mortal(newSVpv(...))
3674 strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1)
3690 /* allowing user-supplied (rather than literal) formats
3691 * is normally frowned upon as a potential security risk;
3692 * but this is part of the API so we have to allow it */
3693 GCC_DIAG_IGNORE_STMT(-Wformat-nonliteral);
3694 buf = my_strftime(SvPV_nolen(fmt), sec, min, hour, mday, mon, year, wday, yday, isdst);
3695 GCC_DIAG_RESTORE_STMT;
3696 sv = sv_newmortal();
3698 STRLEN len = strlen(buf);
3699 sv_usepvn_flags(sv, buf, len, SV_HAS_TRAILING_NUL);
3701 || ( is_utf8_non_invariant_string((U8*) buf, len)
3702 #ifdef USE_LOCALE_TIME
3703 && _is_cur_LC_category_utf8(LC_TIME)
3704 #else /* If can't check directly, at least can see if script is consistent,
3705 under UTF-8, which gives us an extra measure of confidence. */
3707 && isSCRIPT_RUN((const U8 *) buf,
3708 (const U8 *) buf + len,
3709 TRUE) /* Means assume UTF-8 */
3715 else { /* We can't distinguish between errors and just an empty
3716 * return; in all cases just return an empty string */
3717 SvUPGRADE(sv, SVt_PV);
3718 SvPV_set(sv, (char *) "");
3721 SvLEN_set(sv, 0); /* Won't attempt to free the string when sv
3736 PUSHs(newSVpvn_flags(tzname[0], strlen(tzname[0]), SVs_TEMP));
3737 PUSHs(newSVpvn_flags(tzname[1], strlen(tzname[1]), SVs_TEMP));
3743 #ifdef HAS_CTERMID_R
3744 s = (char *) safemalloc((size_t) L_ctermid);
3746 RETVAL = ctermid(s);
3750 #ifdef HAS_CTERMID_R
3759 RETVAL = cuserid(s);
3763 not_here("cuserid");
3774 pathconf(filename, name)
3785 unsigned int seconds
3787 RETVAL = PerlProc_sleep(seconds);
3813 XSprePUSH; PUSHTARG;
3817 lchown(uid, gid, path)
3823 /* yes, the order of arguments is different,
3824 * but consistent with CORE::chown() */
3825 RETVAL = lchown(path, uid, gid);
3827 PERL_UNUSED_VAR(uid);
3828 PERL_UNUSED_VAR(gid);
3829 PERL_UNUSED_VAR(path);
3830 RETVAL = not_here("lchown");