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
11 #include <sys/utsname.h>
14 #define PERL_NO_GET_CONTEXT
17 #define PERLIO_NOT_STDIO 1
21 static int not_here(const char *s);
23 #if defined(PERL_IMPLICIT_SYS)
27 # define open PerlLIO_open3
30 #ifdef I_DIRENT /* XXX maybe better to just rely on perl.h? */
35 #include <sys/errno2.h>
41 #if !(defined(__vax__) && defined(__NetBSD__))
65 #if defined(USE_QUADMATH) && defined(I_QUADMATH)
82 # define M_LOG2E M_LOG2Eq
83 # define M_LOG10E M_LOG10Eq
85 # define M_LN10 M_LN10q
87 # define M_PI_2 M_PI_2q
88 # define M_PI_4 M_PI_4q
89 # define M_1_PI M_1_PIq
90 # define M_2_PI M_2_PIq
91 # define M_2_SQRTPI M_2_SQRTPIq
92 # define M_SQRT2 M_SQRT2q
93 # define M_SQRT1_2 M_SQRT1_2q
97 # ifdef USE_LONG_DOUBLE
111 # define FLOAT_C(c) CAT2(c,L)
113 # define FLOAT_C(c) (c)
117 # define M_E FLOAT_C(2.71828182845904523536028747135266250)
120 # define M_LOG2E FLOAT_C(1.44269504088896340735992468100189214)
123 # define M_LOG10E FLOAT_C(0.434294481903251827651128918916605082)
126 # define M_LN2 FLOAT_C(0.693147180559945309417232121458176568)
129 # define M_LN10 FLOAT_C(2.30258509299404568401799145468436421)
132 # define M_PI FLOAT_C(3.14159265358979323846264338327950288)
135 # define M_PI_2 FLOAT_C(1.57079632679489661923132169163975144)
138 # define M_PI_4 FLOAT_C(0.785398163397448309615660845819875721)
141 # define M_1_PI FLOAT_C(0.318309886183790671537767526745028724)
144 # define M_2_PI FLOAT_C(0.636619772367581343075535053490057448)
147 # define M_2_SQRTPI FLOAT_C(1.12837916709551257389615890312154517)
150 # define M_SQRT2 FLOAT_C(1.41421356237309504880168872420969808)
153 # define M_SQRT1_2 FLOAT_C(0.707106781186547524400844362104849039)
158 #if !defined(INFINITY) && defined(NV_INF)
159 # define INFINITY NV_INF
162 #if !defined(NAN) && defined(NV_NAN)
166 #if !defined(Inf) && defined(NV_INF)
170 #if !defined(NaN) && defined(NV_NAN)
174 /* We will have an emulation. */
176 # define FP_INFINITE 0
179 # define FP_SUBNORMAL 3
183 /* We will have an emulation. */
185 # define FE_TOWARDZERO 0
186 # define FE_TONEAREST 1
188 # define FE_DOWNWARD 3
193 acos asin atan atan2 ceil cos cosh exp fabs floor fmod frexp ldexp
194 log log10 modf pow sin sinh sqrt tan tanh
196 * Implemented in core:
198 atan2 cos exp log pow sin sqrt
202 acosh asinh atanh cbrt copysign erf erfc exp2 expm1 fdim fma fmax
203 fmin fpclassify hypot ilogb isfinite isgreater isgreaterequal isinf
204 isless islessequal islessgreater isnan isnormal isunordered lgamma
205 log1p log2 logb lrint lround nan nearbyint nextafter nexttoward remainder
206 remquo rint round scalbn signbit tgamma trunc
209 http://pubs.opengroup.org/onlinepubs/009695399/basedefs/math.h.html
211 * Berkeley/SVID extensions:
215 * Configure already (5.21.5) scans for:
217 copysign*l* fpclassify isfinite isinf isnan isnan*l* ilogb*l* signbit scalbn*l*
219 * For floating-point round mode (which matters for e.g. lrint and rint)
221 fegetround fesetround
225 /* XXX Constant FP_FAST_FMA (if true, FMA is faster) */
227 /* XXX Add ldiv(), lldiv()? It's C99, but from stdlib.h, not math.h */
229 /* XXX Beware old gamma() -- one cannot know whether that is the
230 * gamma or the log of gamma, that's why the new tgamma and lgamma.
231 * Though also remember lgamma_r. */
233 /* Certain AIX releases have the C99 math, but not in long double.
234 * The <math.h> has them, e.g. __expl128, but no library has them!
236 * Also see the comments in hints/aix.sh about long doubles. */
238 #if defined(USE_QUADMATH) && defined(I_QUADMATH)
239 # define c99_acosh acoshq
240 # define c99_asinh asinhq
241 # define c99_atanh atanhq
242 # define c99_cbrt cbrtq
243 # define c99_copysign copysignq
244 # define c99_erf erfq
245 # define c99_erfc erfcq
247 # define c99_expm1 expm1q
248 # define c99_fdim fdimq
249 # define c99_fma fmaq
250 # define c99_fmax fmaxq
251 # define c99_fmin fminq
252 # define c99_hypot hypotq
253 # define c99_ilogb ilogbq
254 # define c99_lgamma lgammaq
255 # define c99_log1p log1pq
256 # define c99_log2 log2q
258 # if defined(USE_64_BIT_INT) && QUADKIND == QUAD_IS_LONG_LONG
259 # define c99_lrint llrintq
260 # define c99_lround llroundq
262 # define c99_lrint lrintq
263 # define c99_lround lroundq
265 # define c99_nan nanq
266 # define c99_nearbyint nearbyintq
267 # define c99_nextafter nextafterq
269 # define c99_remainder remainderq
270 # define c99_remquo remquoq
271 # define c99_rint rintq
272 # define c99_round roundq
273 # define c99_scalbn scalbnq
274 # define c99_signbit signbitq
275 # define c99_tgamma tgammaq
276 # define c99_trunc truncq
277 # define bessel_j0 j0q
278 # define bessel_j1 j1q
279 # define bessel_jn jnq
280 # define bessel_y0 y0q
281 # define bessel_y1 y1q
282 # define bessel_yn ynq
283 #elif defined(USE_LONG_DOUBLE) && \
284 (defined(HAS_FREXPL) || defined(HAS_ILOGBL)) && defined(HAS_SQRTL)
285 /* Use some of the Configure scans for long double math functions
286 * as the canary for all the C99 *l variants being defined. */
287 # define c99_acosh acoshl
288 # define c99_asinh asinhl
289 # define c99_atanh atanhl
290 # define c99_cbrt cbrtl
291 # define c99_copysign copysignl
292 # define c99_erf erfl
293 # define c99_erfc erfcl
294 # define c99_exp2 exp2l
295 # define c99_expm1 expm1l
296 # define c99_fdim fdiml
297 # define c99_fma fmal
298 # define c99_fmax fmaxl
299 # define c99_fmin fminl
300 # define c99_hypot hypotl
301 # define c99_ilogb ilogbl
302 # define c99_lgamma lgammal
303 # define c99_log1p log1pl
304 # define c99_log2 log2l
305 # define c99_logb logbl
306 # if defined(USE_64_BIT_INT) && QUADKIND == QUAD_IS_LONG_LONG && defined(HAS_LLRINTL)
307 # define c99_lrint llrintl
308 # elif defined(HAS_LRINTL)
309 # define c99_lrint lrintl
311 # if defined(USE_64_BIT_INT) && QUADKIND == QUAD_IS_LONG_LONG && defined(HAS_LLROUNDL)
312 # define c99_lround llroundl
313 # elif defined(HAS_LROUNDL)
314 # define c99_lround lroundl
316 # define c99_nan nanl
317 # define c99_nearbyint nearbyintl
318 # define c99_nextafter nextafterl
319 # define c99_nexttoward nexttowardl
320 # define c99_remainder remainderl
321 # define c99_remquo remquol
322 # define c99_rint rintl
323 # define c99_round roundl
324 # define c99_scalbn scalbnl
325 # ifdef HAS_SIGNBIT /* possibly bad assumption */
326 # define c99_signbit signbitl
328 # define c99_tgamma tgammal
329 # define c99_trunc truncl
331 # define c99_acosh acosh
332 # define c99_asinh asinh
333 # define c99_atanh atanh
334 # define c99_cbrt cbrt
335 # define c99_copysign copysign
337 # define c99_erfc erfc
338 # define c99_exp2 exp2
339 # define c99_expm1 expm1
340 # define c99_fdim fdim
342 # define c99_fmax fmax
343 # define c99_fmin fmin
344 # define c99_hypot hypot
345 # define c99_ilogb ilogb
346 # define c99_lgamma lgamma
347 # define c99_log1p log1p
348 # define c99_log2 log2
349 # define c99_logb logb
350 # if defined(USE_64_BIT_INT) && QUADKIND == QUAD_IS_LONG_LONG && defined(HAS_LLRINT)
351 # define c99_lrint llrint
353 # define c99_lrint lrint
355 # if defined(USE_64_BIT_INT) && QUADKIND == QUAD_IS_LONG_LONG && defined(HAS_LLROUND)
356 # define c99_lround llround
358 # define c99_lround lround
361 # define c99_nearbyint nearbyint
362 # define c99_nextafter nextafter
363 # define c99_nexttoward nexttoward
364 # define c99_remainder remainder
365 # define c99_remquo remquo
366 # define c99_rint rint
367 # define c99_round round
368 # define c99_scalbn scalbn
369 /* We already define Perl_signbit in perl.h. */
371 # define c99_signbit signbit
373 # define c99_tgamma tgamma
374 # define c99_trunc trunc
377 /* AIX xlc (__IBMC__) really doesn't have the following long double
378 * math interfaces (no __acoshl128 aka acoshl, etc.), see
379 * hints/aix.sh. These are in the -lc128 but fail to be found
380 * during dynamic linking/loading.
382 * XXX1 Better Configure scans
383 * XXX2 Is this xlc version dependent? */
384 #if defined(USE_LONG_DOUBLE) && defined(__IBMC__)
404 # undef c99_nearbyint
405 # undef c99_nextafter
406 # undef c99_nexttoward
407 # undef c99_remainder
418 # define isunordered(x, y) (Perl_isnan(x) || Perl_isnan(y))
419 # elif defined(HAS_UNORDERED)
420 # define isunordered(x, y) unordered(x, y)
424 /* XXX these isgreater/isnormal/isunordered macros definitions should
425 * be moved further in the file to be part of the emulations, so that
426 * platforms can e.g. #undef c99_isunordered and have it work like
427 * it does for the other interfaces. */
429 #if !defined(isgreater) && defined(isunordered)
430 # define isgreater(x, y) (!isunordered((x), (y)) && (x) > (y))
431 # define isgreaterequal(x, y) (!isunordered((x), (y)) && (x) >= (y))
432 # define isless(x, y) (!isunordered((x), (y)) && (x) < (y))
433 # define islessequal(x, y) (!isunordered((x), (y)) && (x) <= (y))
434 # define islessgreater(x, y) (!isunordered((x), (y)) && \
435 ((x) > (y) || (y) > (x)))
438 /* Check both the Configure symbol and the macro-ness (like C99 promises). */
439 #if defined(HAS_FPCLASSIFY) && defined(fpclassify)
440 # define c99_fpclassify fpclassify
442 /* Like isnormal(), the isfinite(), isinf(), and isnan() are also C99
443 and also (sizeof-arg-aware) macros, but they are already well taken
444 care of by Configure et al, and defined in perl.h as
445 Perl_isfinite(), Perl_isinf(), and Perl_isnan(). */
447 # define c99_isnormal isnormal
449 #ifdef isgreater /* canary for all the C99 is*<cmp>* macros. */
450 # define c99_isgreater isgreater
451 # define c99_isgreaterequal isgreaterequal
452 # define c99_isless isless
453 # define c99_islessequal islessequal
454 # define c99_islessgreater islessgreater
455 # define c99_isunordered isunordered
458 /* The Great Wall of Undef where according to the definedness of HAS_FOO symbols
459 * the corresponding c99_foo wrappers are undefined. This list doesn't include
460 * the isfoo() interfaces because they are either type-aware macros, or dealt
461 * separately, already in perl.h */
502 #ifndef HAS_FPCLASSIFY
503 # undef c99_fpclassify
532 #ifndef HAS_NEARBYINT
533 # undef c99_nearbyint
535 #ifndef HAS_NEXTAFTER
536 # undef c99_nextafter
538 #ifndef HAS_NEXTTOWARD
539 # undef c99_nexttoward
541 #ifndef HAS_REMAINDER
542 # undef c99_remainder
568 /* Some APIs exist under Win32 with "underbar" names. */
571 # undef c99_nextafter
572 # define c99_hypot _hypot
573 # define c99_logb _logb
574 # define c99_nextafter _nextafter
576 # define bessel_j0 _j0
577 # define bessel_j1 _j1
578 # define bessel_jn _jn
579 # define bessel_y0 _y0
580 # define bessel_y1 _y1
581 # define bessel_yn _yn
585 /* The Bessel functions: BSD, SVID, XPG4, and POSIX. But not C99. */
586 #if defined(HAS_J0) && !defined(bessel_j0)
587 # if defined(USE_LONG_DOUBLE) && defined(HAS_J0L)
588 # define bessel_j0 j0l
589 # define bessel_j1 j1l
590 # define bessel_jn jnl
591 # define bessel_y0 y0l
592 # define bessel_y1 y1l
593 # define bessel_yn ynl
595 # define bessel_j0 j0
596 # define bessel_j1 j1
597 # define bessel_jn jn
598 # define bessel_y0 y0
599 # define bessel_y1 y1
600 # define bessel_yn yn
604 /* Emulations for missing math APIs.
606 * Keep in mind that the point of many of these functions is that
607 * they, if available, are supposed to give more precise/more
608 * numerically stable results.
610 * See e.g. http://www.johndcook.com/math_h.html
614 static NV my_acosh(NV x)
616 return Perl_log(x + Perl_sqrt(x * x - 1));
618 # define c99_acosh my_acosh
622 static NV my_asinh(NV x)
624 return Perl_log(x + Perl_sqrt(x * x + 1));
626 # define c99_asinh my_asinh
630 static NV my_atanh(NV x)
632 return (Perl_log(1 + x) - Perl_log(1 - x)) / 2;
634 # define c99_atanh my_atanh
638 static NV my_cbrt(NV x)
640 static const NV one_third = (NV)1.0/3;
641 return x >= 0.0 ? Perl_pow(x, one_third) : -Perl_pow(-x, one_third);
643 # define c99_cbrt my_cbrt
647 static NV my_copysign(NV x, NV y)
649 return y >= 0 ? (x < 0 ? -x : x) : (x < 0 ? x : -x);
651 # define c99_copysign my_copysign
654 /* XXX cosh (though c89) */
657 static NV my_erf(NV x)
659 /* http://www.johndcook.com/cpp_erf.html -- public domain */
661 NV a2 = -0.284496736;
663 NV a4 = -1.453152027;
667 int sign = x < 0 ? -1 : 1; /* Save the sign. */
670 /* Abramowitz and Stegun formula 7.1.26 */
671 t = 1.0 / (1.0 + p * x);
672 y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1) * t * Perl_exp(-x*x);
676 # define c99_erf my_erf
680 static NV my_erfc(NV x) {
681 /* This is not necessarily numerically stable, but better than nothing. */
682 return 1.0 - c99_erf(x);
684 # define c99_erfc my_erfc
688 static NV my_exp2(NV x)
690 return Perl_pow((NV)2.0, x);
692 # define c99_exp2 my_exp2
696 static NV my_expm1(NV x)
698 if (PERL_ABS(x) < 1e-5)
699 /* http://www.johndcook.com/cpp_expm1.html -- public domain.
700 * Taylor series, the first four terms (the last term quartic). */
701 /* Probably not enough for long doubles. */
702 return x * (1.0 + x * (1/2.0 + x * (1/6.0 + x/24.0)));
704 return Perl_exp(x) - 1;
706 # define c99_expm1 my_expm1
710 static NV my_fdim(NV x, NV y)
713 return (Perl_isnan(x) || Perl_isnan(y)) ? NV_NAN : (x > y ? x - y : 0);
715 return (x > y ? x - y : 0);
718 # define c99_fdim my_fdim
722 static NV my_fma(NV x, NV y, NV z)
726 # define c99_fma my_fma
730 static NV my_fmax(NV x, NV y)
734 return Perl_isnan(y) ? NV_NAN : y;
735 } else if (Perl_isnan(y)) {
739 return x > y ? x : y;
741 # define c99_fmax my_fmax
745 static NV my_fmin(NV x, NV y)
749 return Perl_isnan(y) ? NV_NAN : y;
750 } else if (Perl_isnan(y)) {
754 return x < y ? x : y;
756 # define c99_fmin my_fmin
759 #ifndef c99_fpclassify
761 static IV my_fpclassify(NV x)
763 #ifdef Perl_fp_class_inf
764 if (Perl_fp_class_inf(x)) return FP_INFINITE;
765 if (Perl_fp_class_nan(x)) return FP_NAN;
766 if (Perl_fp_class_norm(x)) return FP_NORMAL;
767 if (Perl_fp_class_denorm(x)) return FP_SUBNORMAL;
768 if (Perl_fp_class_zero(x)) return FP_ZERO;
769 # define c99_fpclassify my_fpclassify
777 static NV my_hypot(NV x, NV y)
779 /* http://en.wikipedia.org/wiki/Hypot */
781 x = PERL_ABS(x); /* Take absolute values. */
789 if (x < y) { /* Swap so that y is less. */
795 return x * Perl_sqrt(1.0 + t * t);
797 # define c99_hypot my_hypot
801 static IV my_ilogb(NV x)
803 return (IV)(Perl_log(x) * M_LOG2E);
805 # define c99_ilogb my_ilogb
808 /* tgamma and lgamma emulations based on
809 * http://www.johndcook.com/cpp_gamma.html,
810 * code placed in public domain.
812 * Note that these implementations (neither the johndcook originals
813 * nor these) do NOT set the global signgam variable. This is not
814 * necessarily a bad thing. */
816 /* Note that the tgamma() and lgamma() implementations
817 * here depend on each other. */
819 #if !defined(HAS_TGAMMA) || !defined(c99_tgamma)
820 static NV my_tgamma(NV x);
821 # define c99_tgamma my_tgamma
822 # define USE_MY_TGAMMA
824 #if !defined(HAS_LGAMMA) || !defined(c99_lgamma)
825 static NV my_lgamma(NV x);
826 # define c99_lgamma my_lgamma
827 # define USE_MY_LGAMMA
831 static NV my_tgamma(NV x)
833 const NV gamma = 0.577215664901532860606512090; /* Euler's gamma constant. */
835 if (Perl_isnan(x) || x < 0.0)
839 if (x == 0.0 || x == NV_INF)
840 #ifdef DOUBLE_IS_IEEE_FORMAT
841 return x == -0.0 ? -NV_INF : NV_INF;
847 /* The function domain is split into three intervals:
848 * (0, 0.001), [0.001, 12), and (12, infinity) */
850 /* First interval: (0, 0.001)
851 * For small values, 1/tgamma(x) has power series x + gamma x^2,
852 * so in this range, 1/tgamma(x) = x + gamma x^2 with error on the order of x^3.
853 * The relative error over this interval is less than 6e-7. */
855 return 1.0 / (x * (1.0 + gamma * x));
857 /* Second interval: [0.001, 12) */
859 double y = x; /* Working copy. */
861 /* Numerator coefficients for approximation over the interval (1,2) */
862 static const NV p[] = {
863 -1.71618513886549492533811E+0,
864 2.47656508055759199108314E+1,
865 -3.79804256470945635097577E+2,
866 6.29331155312818442661052E+2,
867 8.66966202790413211295064E+2,
868 -3.14512729688483675254357E+4,
869 -3.61444134186911729807069E+4,
870 6.64561438202405440627855E+4
872 /* Denominator coefficients for approximation over the interval (1, 2) */
873 static const NV q[] = {
874 -3.08402300119738975254353E+1,
875 3.15350626979604161529144E+2,
876 -1.01515636749021914166146E+3,
877 -3.10777167157231109440444E+3,
878 2.25381184209801510330112E+4,
879 4.75584627752788110767815E+3,
880 -1.34659959864969306392456E+5,
881 -1.15132259675553483497211E+5
892 n = (int)Perl_floor(y) - 1;
896 for (i = 0; i < 8; i++) {
897 num = (num + p[i]) * z;
898 den = den * z + q[i];
900 result = num / den + 1.0;
903 /* Use the identity tgamma(z) = tgamma(z+1)/z
904 * The variable "result" now holds tgamma of the original y + 1
905 * Thus we use y - 1 to get back the original y. */
909 /* Use the identity tgamma(z+n) = z*(z+1)* ... *(z+n-1)*tgamma(z) */
910 for (i = 0; i < n; i++)
918 /* Third interval: [12, +Inf) */
919 #if LDBL_MANT_DIG == 113 /* IEEE quad prec */
930 return Perl_exp(c99_lgamma(x));
935 static NV my_lgamma(NV x)
942 if (x <= 0 || x == NV_INF)
945 if (x == 1.0 || x == 2.0)
948 return Perl_log(PERL_ABS(c99_tgamma(x)));
949 /* Abramowitz and Stegun 6.1.41
950 * Asymptotic series should be good to at least 11 or 12 figures
951 * For error analysis, see Whittiker and Watson
952 * A Course in Modern Analysis (1927), page 252 */
954 static const NV c[8] = {
964 NV z = 1.0 / (x * x);
966 static const NV half_log_of_two_pi =
967 0.91893853320467274178032973640562;
970 for (i = 6; i >= 0; i--) {
975 return (x - 0.5) * Perl_log(x) - x + half_log_of_two_pi + series;
981 static NV my_log1p(NV x)
983 /* http://www.johndcook.com/cpp_log_one_plus_x.html -- public domain.
984 * Taylor series, the first four terms (the last term quartic). */
993 if (PERL_ABS(x) > 1e-4)
994 return Perl_log(1.0 + x);
996 /* Probably not enough for long doubles. */
997 return x * (1.0 + x * (-1/2.0 + x * (1/3.0 - x/4.0)));
999 # define c99_log1p my_log1p
1003 static NV my_log2(NV x)
1005 return Perl_log(x) * M_LOG2E;
1007 # define c99_log2 my_log2
1012 /* XXX nexttoward */
1014 static int my_fegetround()
1016 #ifdef HAS_FEGETROUND
1017 return fegetround();
1018 #elif defined(HAS_FPGETROUND)
1019 switch (fpgetround()) {
1020 case FP_RN: return FE_TONEAREST;
1021 case FP_RZ: return FE_TOWARDZERO;
1022 case FP_RM: return FE_DOWNWARD;
1023 case FP_RP: return FE_UPWARD;
1026 #elif defined(FLT_ROUNDS)
1027 switch (FLT_ROUNDS) {
1028 case 0: return FE_TOWARDZERO;
1029 case 1: return FE_TONEAREST;
1030 case 2: return FE_UPWARD;
1031 case 3: return FE_DOWNWARD;
1034 #elif defined(__osf__) /* Tru64 */
1035 switch (read_rnd()) {
1036 case FP_RND_RN: return FE_TONEAREST;
1037 case FP_RND_RZ: return FE_TOWARDZERO;
1038 case FP_RND_RM: return FE_DOWNWARD;
1039 case FP_RND_RP: return FE_UPWARD;
1047 /* Toward closest integer. */
1048 #define MY_ROUND_NEAREST(x) ((NV)((IV)((x) >= 0.0 ? (x) + 0.5 : (x) - 0.5)))
1051 #define MY_ROUND_TRUNC(x) ((NV)((IV)(x)))
1053 /* Toward minus infinity. */
1054 #define MY_ROUND_DOWN(x) ((NV)((IV)((x) >= 0.0 ? (x) : (x) - 0.5)))
1056 /* Toward plus infinity. */
1057 #define MY_ROUND_UP(x) ((NV)((IV)((x) >= 0.0 ? (x) + 0.5 : (x))))
1059 #if (!defined(c99_nearbyint) || !defined(c99_lrint)) && defined(FE_TONEAREST)
1060 static NV my_rint(NV x)
1063 switch (my_fegetround()) {
1064 case FE_TONEAREST: return MY_ROUND_NEAREST(x);
1065 case FE_TOWARDZERO: return MY_ROUND_TRUNC(x);
1066 case FE_DOWNWARD: return MY_ROUND_DOWN(x);
1067 case FE_UPWARD: return MY_ROUND_UP(x);
1070 #elif defined(HAS_FPGETROUND)
1071 switch (fpgetround()) {
1072 case FP_RN: return MY_ROUND_NEAREST(x);
1073 case FP_RZ: return MY_ROUND_TRUNC(x);
1074 case FP_RM: return MY_ROUND_DOWN(x);
1075 case FE_RP: return MY_ROUND_UP(x);
1083 /* XXX nearbyint() and rint() are not really identical -- but the difference
1084 * is messy: nearbyint is defined NOT to raise FE_INEXACT floating point
1085 * exceptions, while rint() is defined to MAYBE raise them. At the moment
1086 * Perl is blissfully unaware of such fine detail of floating point. */
1087 #ifndef c99_nearbyint
1088 # ifdef FE_TONEAREST
1089 # define c99_nearbyrint my_rint
1094 # ifdef FE_TONEAREST
1095 static IV my_lrint(NV x)
1097 return (IV)my_rint(x);
1099 # define c99_lrint my_lrint
1104 static IV my_lround(NV x)
1106 return (IV)MY_ROUND_NEAREST(x);
1108 # define c99_lround my_lround
1116 # ifdef FE_TONEAREST
1117 # define c99_rint my_rint
1122 static NV my_round(NV x)
1124 return MY_ROUND_NEAREST(x);
1126 # define c99_round my_round
1130 # if defined(Perl_ldexp) && FLT_RADIX == 2
1131 static NV my_scalbn(NV x, int y)
1133 return Perl_ldexp(x, y);
1135 # define c99_scalbn my_scalbn
1139 /* XXX sinh (though c89) */
1141 /* tgamma -- see lgamma */
1143 /* XXX tanh (though c89) */
1146 static NV my_trunc(NV x)
1148 return MY_ROUND_TRUNC(x);
1150 # define c99_trunc my_trunc
1155 #undef NV_PAYLOAD_DEBUG
1157 /* NOTE: the NaN payload API implementation is hand-rolled, since the
1158 * APIs are only proposed ones as of June 2015, so very few, if any,
1159 * platforms have implementations yet, so HAS_SETPAYLOAD and such are
1160 * unlikely to be helpful.
1162 * XXX - if the core numification wants to actually generate
1163 * the nan payload in "nan(123)", and maybe "nans(456)", for
1164 * signaling payload", this needs to be moved to e.g. numeric.c
1165 * (look for grok_infnan)
1167 * Conversely, if the core stringification wants the nan payload
1168 * and/or the nan quiet/signaling distinction, S_getpayload()
1169 * from this file needs to be moved, to e.g. sv.c (look for S_infnan_2pv),
1170 * and the (trivial) functionality of issignaling() copied
1171 * (for generating "NaNS", or maybe even "NaNQ") -- or maybe there
1172 * are too many formatting parameters for simple stringification?
1175 /* While it might make sense for the payload to be UV or IV,
1176 * to avoid conversion loss, the proposed ISO interfaces use
1177 * a floating point input, which is then truncated to integer,
1178 * and only the integer part being used. This is workable,
1179 * except for: (1) the conversion loss (2) suboptimal for
1180 * 32-bit integer platforms. A workaround API for (2) and
1181 * in general for bit-honesty would be an array of integers
1182 * as the payload... but the proposed C API does nothing of
1184 #if NVSIZE == UVSIZE
1185 # define NV_PAYLOAD_TYPE UV
1187 # define NV_PAYLOAD_TYPE NV
1190 #if defined(USE_LONG_DOUBLE) && defined(LONGDOUBLE_DOUBLEDOUBLE)
1191 # define NV_PAYLOAD_SIZEOF_ASSERT(a) \
1192 STATIC_ASSERT_STMT(sizeof(a) == NVSIZE / 2)
1194 # define NV_PAYLOAD_SIZEOF_ASSERT(a) \
1195 STATIC_ASSERT_STMT(sizeof(a) == NVSIZE)
1198 static void S_setpayload(NV* nvp, NV_PAYLOAD_TYPE payload, bool signaling)
1201 static const U8 m[] = { NV_NAN_PAYLOAD_MASK };
1202 static const U8 p[] = { NV_NAN_PAYLOAD_PERM };
1203 UV a[(NVSIZE + UVSIZE - 1) / UVSIZE] = { 0 };
1205 NV_PAYLOAD_SIZEOF_ASSERT(m);
1206 NV_PAYLOAD_SIZEOF_ASSERT(p);
1208 /* Divide the input into the array in "base unsigned integer" in
1209 * little-endian order. Note that the integer might be smaller than
1210 * an NV (if UV is U32, for example). */
1211 #if NVSIZE == UVSIZE
1212 a[0] = payload; /* The trivial case. */
1215 NV t1 = c99_trunc(payload); /* towards zero (drop fractional) */
1216 #ifdef NV_PAYLOAD_DEBUG
1217 Perl_warn(aTHX_ "t1 = %"NVgf" (payload %"NVgf")\n", t1, payload);
1220 a[0] = (UV)t1; /* Fast path, also avoids rounding errors (right?) */
1222 /* UVSIZE < NVSIZE or payload > UV_MAX.
1224 * This may happen for example if:
1225 * (1) UVSIZE == 32 and common 64-bit double NV
1226 * (32-bit system not using -Duse64bitint)
1227 * (2) UVSIZE == 64 and the x86-style 80-bit long double NV
1228 * (note that here the room for payload is actually the 64 bits)
1229 * (3) UVSIZE == 64 and the 128-bit IEEE 764 quadruple NV
1230 * (112 bits in mantissa, 111 bits room for payload)
1232 * NOTE: this is very sensitive to correctly functioning
1233 * fmod()/fmodl(), and correct casting of big-unsigned-integer to NV.
1234 * If these don't work right, especially the low order bits
1235 * are in danger. For example Solaris and AIX seem to have issues
1236 * here, especially if using 32-bit UVs. */
1238 for (i = 0, t2 = t1; i < (int)C_ARRAY_LENGTH(a); i++) {
1239 a[i] = (UV)Perl_fmod(t2, (NV)UV_MAX);
1240 t2 = Perl_floor(t2 / (NV)UV_MAX);
1245 #ifdef NV_PAYLOAD_DEBUG
1246 for (i = 0; i < (int)C_ARRAY_LENGTH(a); i++) {
1247 Perl_warn(aTHX_ "a[%d] = 0x%"UVxf"\n", i, a[i]);
1250 for (i = 0; i < (int)sizeof(p); i++) {
1251 if (m[i] && p[i] < sizeof(p)) {
1252 U8 s = (p[i] % UVSIZE) << 3;
1253 UV u = a[p[i] / UVSIZE] & ((UV)0xFF << s);
1254 U8 b = (U8)((u >> s) & m[i]);
1255 ((U8 *)(nvp))[i] &= ~m[i]; /* For NaNs with non-zero payload bits. */
1256 ((U8 *)(nvp))[i] |= b;
1257 #ifdef NV_PAYLOAD_DEBUG
1258 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);
1260 a[p[i] / UVSIZE] &= ~u;
1264 NV_NAN_SET_SIGNALING(nvp);
1266 #ifdef USE_LONG_DOUBLE
1267 # if LONG_DOUBLEKIND == 3 || LONG_DOUBLEKIND == 4
1268 # if LONG_DOUBLESIZE > 10
1269 memset((char *)nvp + 10, '\0', LONG_DOUBLESIZE - 10); /* x86 long double */
1273 for (i = 0; i < (int)C_ARRAY_LENGTH(a); i++) {
1275 Perl_warn(aTHX_ "payload lost bits (%"UVxf")", a[i]);
1279 #ifdef NV_PAYLOAD_DEBUG
1280 for (i = 0; i < NVSIZE; i++) {
1281 PerlIO_printf(Perl_debug_log, "%02x ", ((U8 *)(nvp))[i]);
1283 PerlIO_printf(Perl_debug_log, "\n");
1287 static NV_PAYLOAD_TYPE S_getpayload(NV nv)
1290 static const U8 m[] = { NV_NAN_PAYLOAD_MASK };
1291 static const U8 p[] = { NV_NAN_PAYLOAD_PERM };
1292 UV a[(NVSIZE + UVSIZE - 1) / UVSIZE] = { 0 };
1295 NV_PAYLOAD_SIZEOF_ASSERT(m);
1296 NV_PAYLOAD_SIZEOF_ASSERT(p);
1298 for (i = 0; i < (int)sizeof(p); i++) {
1299 if (m[i] && p[i] < NVSIZE) {
1300 U8 s = (p[i] % UVSIZE) << 3;
1301 a[p[i] / UVSIZE] |= (UV)(((U8 *)(&nv))[i] & m[i]) << s;
1304 for (i = (int)C_ARRAY_LENGTH(a) - 1; i >= 0; i--) {
1305 #ifdef NV_PAYLOAD_DEBUG
1306 Perl_warn(aTHX_ "a[%d] = %"UVxf"\n", i, a[i]);
1311 #ifdef NV_PAYLOAD_DEBUG
1312 for (i = 0; i < NVSIZE; i++) {
1313 PerlIO_printf(Perl_debug_log, "%02x ", ((U8 *)(&nv))[i]);
1315 PerlIO_printf(Perl_debug_log, "\n");
1320 #endif /* #ifdef NV_NAN */
1322 /* XXX This comment is just to make I_TERMIO and I_SGTTY visible to
1323 metaconfig for future extension writers. We don't use them in POSIX.
1324 (This is really sneaky :-) --AD
1326 #if defined(I_TERMIOS)
1327 #include <termios.h>
1335 #include <sys/stat.h>
1336 #include <sys/types.h>
1344 # if !defined(WIN32) && !defined(__CYGWIN__) && !defined(NETWARE) && !defined(__UWIN__)
1345 extern char *tzname[];
1348 #if !defined(WIN32) && !defined(__UWIN__) || (defined(__MINGW32__) && !defined(tzname))
1349 char *tzname[] = { "" , "" };
1353 #if defined(__VMS) && !defined(__POSIX_SOURCE)
1355 # include <utsname.h>
1358 # define mkfifo(a,b) (not_here("mkfifo"),-1)
1360 /* The POSIX notion of ttyname() is better served by getname() under VMS */
1361 static char ttnambuf[64];
1362 # define ttyname(fd) (isatty(fd) > 0 ? getname(fd,ttnambuf,0) : NULL)
1365 #if defined (__CYGWIN__)
1366 # define tzname _tzname
1368 #if defined (WIN32) || defined (NETWARE)
1370 # define mkfifo(a,b) not_here("mkfifo")
1371 # define ttyname(a) (char*)not_here("ttyname")
1372 # define sigset_t long
1375 # define mode_t short
1378 # define mode_t short
1380 # define tzset() not_here("tzset")
1382 # ifndef _POSIX_OPEN_MAX
1383 # define _POSIX_OPEN_MAX FOPEN_MAX /* XXX bogus ? */
1386 # define sigaction(a,b,c) not_here("sigaction")
1387 # define sigpending(a) not_here("sigpending")
1388 # define sigprocmask(a,b,c) not_here("sigprocmask")
1389 # define sigsuspend(a) not_here("sigsuspend")
1390 # define sigemptyset(a) not_here("sigemptyset")
1391 # define sigaddset(a,b) not_here("sigaddset")
1392 # define sigdelset(a,b) not_here("sigdelset")
1393 # define sigfillset(a) not_here("sigfillset")
1394 # define sigismember(a,b) not_here("sigismember")
1398 # define setuid(a) not_here("setuid")
1399 # define setgid(a) not_here("setgid")
1400 #endif /* NETWARE */
1401 #ifndef USE_LONG_DOUBLE
1402 # define strtold(s1,s2) not_here("strtold")
1403 #endif /* USE_LONG_DOUBLE */
1407 # if defined(OS2) || defined(__amigaos4__)
1408 # define mkfifo(a,b) not_here("mkfifo")
1409 # else /* !( defined OS2 ) */
1411 # define mkfifo(path, mode) (mknod((path), (mode) | S_IFIFO, 0))
1414 # endif /* !HAS_MKFIFO */
1419 # include <sys/times.h>
1421 # include <sys/utsname.h>
1423 # ifndef __amigaos4__
1424 # include <sys/wait.h>
1429 #endif /* WIN32 || NETWARE */
1433 typedef long SysRetLong;
1434 typedef sigset_t* POSIX__SigSet;
1435 typedef HV* POSIX__SigAction;
1436 typedef int POSIX__SigNo;
1437 typedef int POSIX__Fd;
1439 typedef struct termios* POSIX__Termios;
1440 #else /* Define termios types to int, and call not_here for the functions.*/
1441 #define POSIX__Termios int
1443 #define tcflag_t int
1445 #define cfgetispeed(x) not_here("cfgetispeed")
1446 #define cfgetospeed(x) not_here("cfgetospeed")
1447 #define tcdrain(x) not_here("tcdrain")
1448 #define tcflush(x,y) not_here("tcflush")
1449 #define tcsendbreak(x,y) not_here("tcsendbreak")
1450 #define cfsetispeed(x,y) not_here("cfsetispeed")
1451 #define cfsetospeed(x,y) not_here("cfsetospeed")
1452 #define ctermid(x) (char *) not_here("ctermid")
1453 #define tcflow(x,y) not_here("tcflow")
1454 #define tcgetattr(x,y) not_here("tcgetattr")
1455 #define tcsetattr(x,y,z) not_here("tcsetattr")
1458 /* Possibly needed prototypes */
1461 double strtod (const char *, char **);
1462 long strtol (const char *, char **, int);
1463 unsigned long strtoul (const char *, char **, int);
1465 long double strtold (const char *, char **);
1470 #ifndef HAS_DIFFTIME
1472 #define difftime(a,b) not_here("difftime")
1475 #ifndef HAS_FPATHCONF
1476 #define fpathconf(f,n) (SysRetLong) not_here("fpathconf")
1479 #define mktime(a) not_here("mktime")
1482 #define nice(a) not_here("nice")
1484 #ifndef HAS_PATHCONF
1485 #define pathconf(f,n) (SysRetLong) not_here("pathconf")
1488 #define sysconf(n) (SysRetLong) not_here("sysconf")
1490 #ifndef HAS_READLINK
1491 #define readlink(a,b,c) not_here("readlink")
1494 #define setpgid(a,b) not_here("setpgid")
1497 #define setsid() not_here("setsid")
1500 #define strcoll(s1,s2) not_here("strcoll")
1503 #define strtod(s1,s2) not_here("strtod")
1506 #define strtold(s1,s2) not_here("strtold")
1509 #define strtol(s1,s2,b) not_here("strtol")
1512 #define strtoul(s1,s2,b) not_here("strtoul")
1515 #define strxfrm(s1,s2,n) not_here("strxfrm")
1517 #ifndef HAS_TCGETPGRP
1518 #define tcgetpgrp(a) not_here("tcgetpgrp")
1520 #ifndef HAS_TCSETPGRP
1521 #define tcsetpgrp(a,b) not_here("tcsetpgrp")
1525 #define times(a) not_here("times")
1526 #endif /* NETWARE */
1529 #define uname(a) not_here("uname")
1532 #define waitpid(a,b,c) not_here("waitpid")
1537 #define mblen(a,b) not_here("mblen")
1540 #ifndef HAS_MBSTOWCS
1541 #define mbstowcs(s, pwcs, n) not_here("mbstowcs")
1544 #define mbtowc(pwc, s, n) not_here("mbtowc")
1546 #ifndef HAS_WCSTOMBS
1547 #define wcstombs(s, pwcs, n) not_here("wcstombs")
1550 #define wctomb(s, wchar) not_here("wcstombs")
1552 #if !defined(HAS_MBLEN) && !defined(HAS_MBSTOWCS) && !defined(HAS_MBTOWC) && !defined(HAS_WCSTOMBS) && !defined(HAS_WCTOMB)
1553 /* If we don't have these functions, then we wouldn't have gotten a typedef
1554 for wchar_t, the wide character type. Defining wchar_t allows the
1555 functions referencing it to compile. Its actual type is then meaningless,
1556 since without the above functions, all sections using it end up calling
1557 not_here() and croak. --Kaveh Ghazi (ghazi@noc.rutgers.edu) 9/18/94. */
1559 #define wchar_t char
1563 #ifndef HAS_LOCALECONV
1564 # define localeconv() not_here("localeconv")
1566 struct lconv_offset {
1571 static const struct lconv_offset lconv_strings[] = {
1572 #ifdef USE_LOCALE_NUMERIC
1573 {"decimal_point", STRUCT_OFFSET(struct lconv, decimal_point)},
1574 {"thousands_sep", STRUCT_OFFSET(struct lconv, thousands_sep)},
1575 # ifndef NO_LOCALECONV_GROUPING
1576 {"grouping", STRUCT_OFFSET(struct lconv, grouping)},
1579 #ifdef USE_LOCALE_MONETARY
1580 {"int_curr_symbol", STRUCT_OFFSET(struct lconv, int_curr_symbol)},
1581 {"currency_symbol", STRUCT_OFFSET(struct lconv, currency_symbol)},
1582 {"mon_decimal_point", STRUCT_OFFSET(struct lconv, mon_decimal_point)},
1583 # ifndef NO_LOCALECONV_MON_THOUSANDS_SEP
1584 {"mon_thousands_sep", STRUCT_OFFSET(struct lconv, mon_thousands_sep)},
1586 # ifndef NO_LOCALECONV_MON_GROUPING
1587 {"mon_grouping", STRUCT_OFFSET(struct lconv, mon_grouping)},
1589 {"positive_sign", STRUCT_OFFSET(struct lconv, positive_sign)},
1590 {"negative_sign", STRUCT_OFFSET(struct lconv, negative_sign)},
1595 #ifdef USE_LOCALE_NUMERIC
1597 /* The Linux man pages say these are the field names for the structure
1598 * components that are LC_NUMERIC; the rest being LC_MONETARY */
1599 # define isLC_NUMERIC_STRING(name) (strEQ(name, "decimal_point") \
1600 || strEQ(name, "thousands_sep") \
1602 /* There should be no harm done \
1603 * checking for this, even if \
1604 * NO_LOCALECONV_GROUPING */ \
1605 || strEQ(name, "grouping"))
1607 # define isLC_NUMERIC_STRING(name) (0)
1610 static const struct lconv_offset lconv_integers[] = {
1611 #ifdef USE_LOCALE_MONETARY
1612 {"int_frac_digits", STRUCT_OFFSET(struct lconv, int_frac_digits)},
1613 {"frac_digits", STRUCT_OFFSET(struct lconv, frac_digits)},
1614 {"p_cs_precedes", STRUCT_OFFSET(struct lconv, p_cs_precedes)},
1615 {"p_sep_by_space", STRUCT_OFFSET(struct lconv, p_sep_by_space)},
1616 {"n_cs_precedes", STRUCT_OFFSET(struct lconv, n_cs_precedes)},
1617 {"n_sep_by_space", STRUCT_OFFSET(struct lconv, n_sep_by_space)},
1618 {"p_sign_posn", STRUCT_OFFSET(struct lconv, p_sign_posn)},
1619 {"n_sign_posn", STRUCT_OFFSET(struct lconv, n_sign_posn)},
1620 #ifdef HAS_LC_MONETARY_2008
1621 {"int_p_cs_precedes", STRUCT_OFFSET(struct lconv, int_p_cs_precedes)},
1622 {"int_p_sep_by_space", STRUCT_OFFSET(struct lconv, int_p_sep_by_space)},
1623 {"int_n_cs_precedes", STRUCT_OFFSET(struct lconv, int_n_cs_precedes)},
1624 {"int_n_sep_by_space", STRUCT_OFFSET(struct lconv, int_n_sep_by_space)},
1625 {"int_p_sign_posn", STRUCT_OFFSET(struct lconv, int_p_sign_posn)},
1626 {"int_n_sign_posn", STRUCT_OFFSET(struct lconv, int_n_sign_posn)},
1632 #endif /* HAS_LOCALECONV */
1634 #ifdef HAS_LONG_DOUBLE
1635 # if LONG_DOUBLESIZE > NVSIZE
1636 # undef HAS_LONG_DOUBLE /* XXX until we figure out how to use them */
1640 #ifndef HAS_LONG_DOUBLE
1652 /* Background: in most systems the low byte of the wait status
1653 * is the signal (the lowest 7 bits) and the coredump flag is
1654 * the eight bit, and the second lowest byte is the exit status.
1655 * BeOS bucks the trend and has the bytes in different order.
1656 * See beos/beos.c for how the reality is bent even in BeOS
1657 * to follow the traditional. However, to make the POSIX
1658 * wait W*() macros to work in BeOS, we need to unbend the
1659 * reality back in place. --jhi */
1660 /* In actual fact the code below is to blame here. Perl has an internal
1661 * representation of the exit status ($?), which it re-composes from the
1662 * OS's representation using the W*() POSIX macros. The code below
1663 * incorrectly uses the W*() macros on the internal representation,
1664 * which fails for OSs that have a different representation (namely BeOS
1665 * and Haiku). WMUNGE() is a hack that converts the internal
1666 * representation into the OS specific one, so that the W*() macros work
1667 * as expected. The better solution would be not to use the W*() macros
1668 * in the first place, though. -- Ingo Weinhold
1670 #if defined(__HAIKU__)
1671 # define WMUNGE(x) (((x) & 0xFF00) >> 8 | ((x) & 0x00FF) << 8)
1673 # define WMUNGE(x) (x)
1677 not_here(const char *s)
1679 croak("POSIX::%s not implemented on this architecture", s);
1683 #include "const-c.inc"
1686 restore_sigmask(pTHX_ SV *osset_sv)
1688 /* Fortunately, restoring the signal mask can't fail, because
1689 * there's nothing we can do about it if it does -- we're not
1690 * supposed to return -1 from sigaction unless the disposition
1693 #if !(defined(__amigaos4__) && defined(__NEWLIB__))
1694 sigset_t *ossetp = (sigset_t *) SvPV_nolen( osset_sv );
1695 (void)sigprocmask(SIG_SETMASK, ossetp, (sigset_t *)0);
1700 allocate_struct(pTHX_ SV *rv, const STRLEN size, const char *packname) {
1701 SV *const t = newSVrv(rv, packname);
1702 void *const p = sv_grow(t, size + 1);
1704 /* Ensure at least one use of not_here() to avoid "defined but not
1705 * used" warning. This is not at all related to allocate_struct(); I
1706 * just needed somewhere to dump it - DAPM */
1707 if (0) { not_here(""); }
1717 * (1) The CRT maintains its own copy of the environment, separate from
1718 * the Win32API copy.
1720 * (2) CRT getenv() retrieves from this copy. CRT putenv() updates this
1721 * copy, and then calls SetEnvironmentVariableA() to update the Win32API
1724 * (3) win32_getenv() and win32_putenv() call GetEnvironmentVariableA() and
1725 * SetEnvironmentVariableA() directly, bypassing the CRT copy of the
1728 * (4) The CRT strftime() "%Z" implementation calls __tzset(). That
1729 * calls CRT tzset(), but only the first time it is called, and in turn
1730 * that uses CRT getenv("TZ") to retrieve the timezone info from the CRT
1731 * local copy of the environment and hence gets the original setting as
1732 * perl never updates the CRT copy when assigning to $ENV{TZ}.
1734 * Therefore, we need to retrieve the value of $ENV{TZ} and call CRT
1735 * putenv() to update the CRT copy of the environment (if it is different)
1736 * whenever we're about to call tzset().
1738 * In addition to all that, when perl is built with PERL_IMPLICIT_SYS
1741 * (a) Each interpreter has its own copy of the environment inside the
1742 * perlhost structure. That allows applications that host multiple
1743 * independent Perl interpreters to isolate environment changes from
1744 * each other. (This is similar to how the perlhost mechanism keeps a
1745 * separate working directory for each Perl interpreter, so that calling
1746 * chdir() will not affect other interpreters.)
1748 * (b) Only the first Perl interpreter instantiated within a process will
1749 * "write through" environment changes to the process environment.
1751 * (c) Even the primary Perl interpreter won't update the CRT copy of the
1752 * the environment, only the Win32API copy (it calls win32_putenv()).
1754 * As with CPerlHost::Getenv() and CPerlHost::Putenv() themselves, it makes
1755 * sense to only update the process environment when inside the main
1756 * interpreter, but we don't have access to CPerlHost's m_bTopLevel member
1757 * from here so we'll just have to check PL_curinterp instead.
1759 * Therefore, we can simply #undef getenv() and putenv() so that those names
1760 * always refer to the CRT functions, and explicitly call win32_getenv() to
1761 * access perl's %ENV.
1763 * We also #undef malloc() and free() to be sure we are using the CRT
1764 * functions otherwise under PERL_IMPLICIT_SYS they are redefined to calls
1765 * into VMem::Malloc() and VMem::Free() and all allocations will be freed
1766 * when the Perl interpreter is being destroyed so we'd end up with a pointer
1767 * into deallocated memory in environ[] if a program embedding a Perl
1768 * interpreter continues to operate even after the main Perl interpreter has
1771 * Note that we don't free() the malloc()ed memory unless and until we call
1772 * malloc() again ourselves because the CRT putenv() function simply puts its
1773 * pointer argument into the environ[] array (it doesn't make a copy of it)
1774 * so this memory must otherwise be leaked.
1783 fix_win32_tzenv(void)
1785 static char* oldenv = NULL;
1787 const char* perl_tz_env = win32_getenv("TZ");
1788 const char* crt_tz_env = getenv("TZ");
1789 if (perl_tz_env == NULL)
1791 if (crt_tz_env == NULL)
1793 if (strcmp(perl_tz_env, crt_tz_env) != 0) {
1794 newenv = (char*)malloc((strlen(perl_tz_env) + 4) * sizeof(char));
1795 if (newenv != NULL) {
1796 sprintf(newenv, "TZ=%s", perl_tz_env);
1808 * my_tzset - wrapper to tzset() with a fix to make it work (better) on Win32.
1809 * This code is duplicated in the Time-Piece module, so any changes made here
1810 * should be made there too.
1816 #if defined(USE_ITHREADS) && defined(PERL_IMPLICIT_SYS)
1817 if (PL_curinterp == aTHX)
1824 MODULE = SigSet PACKAGE = POSIX::SigSet PREFIX = sig
1827 new(packname = "POSIX::SigSet", ...)
1828 const char * packname
1833 = (sigset_t *) allocate_struct(aTHX_ (ST(0) = sv_newmortal()),
1837 for (i = 1; i < items; i++)
1838 sigaddset(s, SvIV(ST(i)));
1844 POSIX::SigSet sigset
1849 RETVAL = ix ? sigdelset(sigset, sig) : sigaddset(sigset, sig);
1855 POSIX::SigSet sigset
1859 RETVAL = ix ? sigfillset(sigset) : sigemptyset(sigset);
1864 sigismember(sigset, sig)
1865 POSIX::SigSet sigset
1868 MODULE = Termios PACKAGE = POSIX::Termios PREFIX = cf
1871 new(packname = "POSIX::Termios", ...)
1872 const char * packname
1876 void *const p = allocate_struct(aTHX_ (ST(0) = sv_newmortal()),
1877 sizeof(struct termios), packname);
1878 /* The previous implementation stored a pointer to an uninitialised
1879 struct termios. Seems safer to initialise it, particularly as
1880 this implementation exposes the struct to prying from perl-space.
1882 memset(p, 0, 1 + sizeof(struct termios));
1885 not_here("termios");
1890 getattr(termios_ref, fd = 0)
1891 POSIX::Termios termios_ref
1894 RETVAL = tcgetattr(fd, termios_ref);
1898 # If we define TCSANOW here then both a found and not found constant sub
1899 # are created causing a Constant subroutine TCSANOW redefined warning
1901 # define DEF_SETATTR_ACTION 0
1903 # define DEF_SETATTR_ACTION TCSANOW
1906 setattr(termios_ref, fd = 0, optional_actions = DEF_SETATTR_ACTION)
1907 POSIX::Termios termios_ref
1909 int optional_actions
1911 /* The second argument to the call is mandatory, but we'd like to give
1912 it a useful default. 0 isn't valid on all operating systems - on
1913 Solaris (at least) TCSANOW, TCSADRAIN and TCSAFLUSH have the same
1914 values as the equivalent ioctls, TCSETS, TCSETSW and TCSETSF. */
1915 if (optional_actions < 0) {
1916 SETERRNO(EINVAL, LIB_INVARG);
1919 RETVAL = tcsetattr(fd, optional_actions, termios_ref);
1925 getispeed(termios_ref)
1926 POSIX::Termios termios_ref
1930 RETVAL = ix ? cfgetospeed(termios_ref) : cfgetispeed(termios_ref);
1935 getiflag(termios_ref)
1936 POSIX::Termios termios_ref
1942 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
1945 RETVAL = termios_ref->c_iflag;
1948 RETVAL = termios_ref->c_oflag;
1951 RETVAL = termios_ref->c_cflag;
1954 RETVAL = termios_ref->c_lflag;
1957 RETVAL = 0; /* silence compiler warning */
1960 not_here(GvNAME(CvGV(cv)));
1967 getcc(termios_ref, ccix)
1968 POSIX::Termios termios_ref
1971 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
1973 croak("Bad getcc subscript");
1974 RETVAL = termios_ref->c_cc[ccix];
1983 setispeed(termios_ref, speed)
1984 POSIX::Termios termios_ref
1990 ? cfsetospeed(termios_ref, speed) : cfsetispeed(termios_ref, speed);
1995 setiflag(termios_ref, flag)
1996 POSIX::Termios termios_ref
2003 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
2006 termios_ref->c_iflag = flag;
2009 termios_ref->c_oflag = flag;
2012 termios_ref->c_cflag = flag;
2015 termios_ref->c_lflag = flag;
2019 not_here(GvNAME(CvGV(cv)));
2023 setcc(termios_ref, ccix, cc)
2024 POSIX::Termios termios_ref
2028 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
2030 croak("Bad setcc subscript");
2031 termios_ref->c_cc[ccix] = cc;
2037 MODULE = POSIX PACKAGE = POSIX
2039 INCLUDE: const-xs.inc
2045 POSIX::WIFEXITED = 1
2046 POSIX::WIFSIGNALED = 2
2047 POSIX::WIFSTOPPED = 3
2051 #if !defined(WEXITSTATUS) || !defined(WIFEXITED) || !defined(WIFSIGNALED) \
2052 || !defined(WIFSTOPPED) || !defined(WSTOPSIG) || !defined(WTERMSIG)
2053 RETVAL = 0; /* Silence compilers that notice this, but don't realise
2054 that not_here() can't return. */
2059 RETVAL = WEXITSTATUS(WMUNGE(status));
2061 not_here("WEXITSTATUS");
2066 RETVAL = WIFEXITED(WMUNGE(status));
2068 not_here("WIFEXITED");
2073 RETVAL = WIFSIGNALED(WMUNGE(status));
2075 not_here("WIFSIGNALED");
2080 RETVAL = WIFSTOPPED(WMUNGE(status));
2082 not_here("WIFSTOPPED");
2087 RETVAL = WSTOPSIG(WMUNGE(status));
2089 not_here("WSTOPSIG");
2094 RETVAL = WTERMSIG(WMUNGE(status));
2096 not_here("WTERMSIG");
2100 croak("Illegal alias %d for POSIX::W*", (int)ix);
2106 open(filename, flags = O_RDONLY, mode = 0666)
2111 if (flags & (O_APPEND|O_CREAT|O_TRUNC|O_RDWR|O_WRONLY|O_EXCL))
2112 TAINT_PROPER("open");
2113 RETVAL = open(filename, flags, mode);
2121 #ifndef HAS_LOCALECONV
2122 localeconv(); /* A stub to call not_here(). */
2124 struct lconv *lcbuf;
2126 /* localeconv() deals with both LC_NUMERIC and LC_MONETARY, but
2127 * LC_MONETARY is already in the correct locale */
2128 DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
2129 STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
2132 sv_2mortal((SV*)RETVAL);
2133 if ((lcbuf = localeconv())) {
2134 const struct lconv_offset *strings = lconv_strings;
2135 const struct lconv_offset *integers = lconv_integers;
2136 const char *ptr = (const char *) lcbuf;
2138 while (strings->name) {
2139 /* This string may be controlled by either LC_NUMERIC, or
2142 #if defined(USE_LOCALE_NUMERIC) && defined(USE_LOCALE_MONETARY)
2143 = _is_cur_LC_category_utf8((isLC_NUMERIC_STRING(strings->name))
2146 #elif defined(USE_LOCALE_NUMERIC)
2147 = _is_cur_LC_category_utf8(LC_NUMERIC);
2148 #elif defined(USE_LOCALE_MONETARY)
2149 = _is_cur_LC_category_utf8(LC_MONETARY);
2154 const char *value = *((const char **)(ptr + strings->offset));
2156 if (value && *value) {
2157 (void) hv_store(RETVAL,
2159 strlen(strings->name),
2164 /* We mark it as UTF-8 if a utf8 locale and is
2165 * valid and variant under UTF-8 */
2167 && ! is_utf8_invariant_string((U8 *) value, 0)
2168 && is_utf8_string((U8 *) value, 0)),
2174 while (integers->name) {
2175 const char value = *((const char *)(ptr + integers->offset));
2177 if (value != CHAR_MAX)
2178 (void) hv_store(RETVAL, integers->name,
2179 strlen(integers->name), newSViv(value), 0);
2183 RESTORE_LC_NUMERIC_STANDARD();
2184 #endif /* HAS_LOCALECONV */
2189 setlocale(category, locale = 0)
2195 #ifdef USE_LOCALE_NUMERIC
2196 /* A 0 (or NULL) locale means only query what the current one is. We
2197 * have the LC_NUMERIC name saved, because we are normally switched
2198 * into the C locale for it. Switch back so an LC_ALL query will yield
2199 * the correct results; all other categories don't require special
2202 if (category == LC_NUMERIC) {
2203 XSRETURN_PV(PL_numeric_name);
2206 else if (category == LC_ALL) {
2207 SET_NUMERIC_UNDERLYING();
2212 #ifdef WIN32 /* Use wrapper on Windows */
2213 retval = Perl_my_setlocale(aTHX_ category, locale);
2215 retval = setlocale(category, locale);
2217 DEBUG_L(PerlIO_printf(Perl_debug_log,
2218 "%s:%d: %s\n", __FILE__, __LINE__,
2219 _setlocale_debug_string(category, locale, retval)));
2221 /* Should never happen that a query would return an error, but be
2222 * sure and reset to C locale */
2224 SET_NUMERIC_STANDARD();
2229 /* Save retval since subsequent setlocale() calls may overwrite it. */
2230 retval = savepv(retval);
2233 /* For locale == 0, we may have switched to NUMERIC_UNDERLYING. Switch
2236 SET_NUMERIC_STANDARD();
2237 XSRETURN_PV(retval);
2241 #ifdef USE_LOCALE_CTYPE
2242 if (category == LC_CTYPE
2244 || category == LC_ALL
2250 if (category == LC_ALL) {
2251 newctype = setlocale(LC_CTYPE, NULL);
2252 DEBUG_Lv(PerlIO_printf(Perl_debug_log,
2253 "%s:%d: %s\n", __FILE__, __LINE__,
2254 _setlocale_debug_string(LC_CTYPE, NULL, newctype)));
2259 new_ctype(newctype);
2261 #endif /* USE_LOCALE_CTYPE */
2262 #ifdef USE_LOCALE_COLLATE
2263 if (category == LC_COLLATE
2265 || category == LC_ALL
2271 if (category == LC_ALL) {
2272 newcoll = setlocale(LC_COLLATE, NULL);
2273 DEBUG_Lv(PerlIO_printf(Perl_debug_log,
2274 "%s:%d: %s\n", __FILE__, __LINE__,
2275 _setlocale_debug_string(LC_COLLATE, NULL, newcoll)));
2280 new_collate(newcoll);
2282 #endif /* USE_LOCALE_COLLATE */
2283 #ifdef USE_LOCALE_NUMERIC
2284 if (category == LC_NUMERIC
2286 || category == LC_ALL
2292 if (category == LC_ALL) {
2293 newnum = setlocale(LC_NUMERIC, NULL);
2294 DEBUG_Lv(PerlIO_printf(Perl_debug_log,
2295 "%s:%d: %s\n", __FILE__, __LINE__,
2296 _setlocale_debug_string(LC_NUMERIC, NULL, newnum)));
2301 new_numeric(newnum);
2303 #endif /* USE_LOCALE_NUMERIC */
2351 RETVAL = Perl_acos(x); /* C89 math */
2355 RETVAL = c99_acosh(x);
2361 RETVAL = Perl_asin(x); /* C89 math */
2365 RETVAL = c99_asinh(x);
2371 RETVAL = Perl_atan(x); /* C89 math */
2375 RETVAL = c99_atanh(x);
2382 RETVAL = c99_cbrt(x);
2388 RETVAL = Perl_ceil(x); /* C89 math */
2391 RETVAL = Perl_cosh(x); /* C89 math */
2395 RETVAL = c99_erf(x);
2402 RETVAL = c99_erfc(x);
2409 RETVAL = c99_exp2(x);
2416 RETVAL = c99_expm1(x);
2422 RETVAL = Perl_floor(x); /* C89 math */
2426 RETVAL = bessel_j0(x);
2433 RETVAL = bessel_j1(x);
2439 /* XXX Note: the lgamma modifies a global variable (signgam),
2440 * which is evil. Some platforms have lgamma_r, which has
2441 * extra output parameter instead of the global variable. */
2443 RETVAL = c99_lgamma(x);
2449 RETVAL = log10(x); /* C89 math */
2453 RETVAL = c99_log1p(x);
2460 RETVAL = c99_log2(x);
2467 RETVAL = c99_logb(x);
2468 #elif defined(c99_log2) && FLT_RADIX == 2
2469 RETVAL = Perl_floor(c99_log2(PERL_ABS(x)));
2475 #ifdef c99_nearbyint
2476 RETVAL = c99_nearbyint(x);
2478 not_here("nearbyint");
2483 RETVAL = c99_rint(x);
2490 RETVAL = c99_round(x);
2496 RETVAL = Perl_sinh(x); /* C89 math */
2499 RETVAL = Perl_tan(x); /* C89 math */
2502 RETVAL = Perl_tanh(x); /* C89 math */
2506 RETVAL = c99_tgamma(x);
2513 RETVAL = c99_trunc(x);
2520 RETVAL = bessel_y0(x);
2528 RETVAL = bessel_y1(x);
2539 #ifdef HAS_FEGETROUND
2540 RETVAL = my_fegetround();
2543 not_here("fegetround");
2552 #ifdef HAS_FEGETROUND /* canary for fesetround */
2553 RETVAL = fesetround(x);
2554 #elif defined(HAS_FPGETROUND) /* canary for fpsetround */
2556 case FE_TONEAREST: RETVAL = fpsetround(FP_RN); break;
2557 case FE_TOWARDZERO: RETVAL = fpsetround(FP_RZ); break;
2558 case FE_DOWNWARD: RETVAL = fpsetround(FP_RM); break;
2559 case FE_UPWARD: RETVAL = fpsetround(FP_RP); break;
2560 default: RETVAL = -1; break;
2562 #elif defined(__osf__) /* Tru64 */
2564 case FE_TONEAREST: RETVAL = write_rnd(FP_RND_RN); break;
2565 case FE_TOWARDZERO: RETVAL = write_rnd(FP_RND_RZ); break;
2566 case FE_DOWNWARD: RETVAL = write_rnd(FP_RND_RM); break;
2567 case FE_UPWARD: RETVAL = write_rnd(FP_RND_RP); break;
2568 default: RETVAL = -1; break;
2573 not_here("fesetround");
2595 #ifdef c99_fpclassify
2596 RETVAL = c99_fpclassify(x);
2598 not_here("fpclassify");
2603 RETVAL = c99_ilogb(x);
2609 RETVAL = Perl_isfinite(x);
2612 RETVAL = Perl_isinf(x);
2615 RETVAL = Perl_isnan(x);
2619 RETVAL = c99_isnormal(x);
2621 not_here("isnormal");
2626 RETVAL = c99_lrint(x);
2633 RETVAL = c99_lround(x);
2641 RETVAL = Perl_signbit(x);
2644 #ifdef DOUBLE_IS_IEEE_FORMAT
2659 #ifdef DOUBLE_HAS_NAN
2660 RETVAL = S_getpayload(nv);
2662 PERL_UNUSED_VAR(nv);
2663 not_here("getpayload");
2669 setpayload(nv, payload)
2673 #ifdef DOUBLE_HAS_NAN
2674 S_setpayload(&nv, payload, FALSE);
2676 PERL_UNUSED_VAR(nv);
2677 PERL_UNUSED_VAR(payload);
2678 not_here("setpayload");
2684 setpayloadsig(nv, payload)
2688 #ifdef DOUBLE_HAS_NAN
2690 S_setpayload(&nv, payload, TRUE);
2692 PERL_UNUSED_VAR(nv);
2693 PERL_UNUSED_VAR(payload);
2694 not_here("setpayloadsig");
2703 #ifdef DOUBLE_HAS_NAN
2704 RETVAL = Perl_isnan(nv) && NV_NAN_IS_SIGNALING(&nv);
2706 PERL_UNUSED_VAR(nv);
2707 not_here("issignaling");
2742 RETVAL = c99_copysign(x, y);
2744 not_here("copysign");
2749 RETVAL = c99_fdim(x, y);
2756 RETVAL = c99_fmax(x, y);
2763 RETVAL = c99_fmin(x, y);
2769 RETVAL = Perl_fmod(x, y); /* C89 math */
2773 RETVAL = c99_hypot(x, y);
2779 #ifdef c99_isgreater
2780 RETVAL = c99_isgreater(x, y);
2782 not_here("isgreater");
2786 #ifdef c99_isgreaterequal
2787 RETVAL = c99_isgreaterequal(x, y);
2789 not_here("isgreaterequal");
2794 RETVAL = c99_isless(x, y);
2800 #ifdef c99_islessequal
2801 RETVAL = c99_islessequal(x, y);
2803 not_here("islessequal");
2807 #ifdef c99_islessgreater
2808 RETVAL = c99_islessgreater(x, y);
2810 not_here("islessgreater");
2814 #ifdef c99_isunordered
2815 RETVAL = c99_isunordered(x, y);
2817 not_here("isunordered");
2821 #ifdef c99_nextafter
2822 RETVAL = c99_nextafter(x, y);
2824 not_here("nextafter");
2828 #ifdef c99_nexttoward
2829 RETVAL = c99_nexttoward(x, y);
2831 not_here("nexttoward");
2836 #ifdef c99_remainder
2837 RETVAL = c99_remainder(x, y);
2839 not_here("remainder");
2851 /* (We already know stack is long enough.) */
2852 PUSHs(sv_2mortal(newSVnv(Perl_frexp(x,&expvar)))); /* C89 math */
2853 PUSHs(sv_2mortal(newSViv(expvar)));
2865 /* (We already know stack is long enough.) */
2866 PUSHs(sv_2mortal(newSVnv(Perl_modf(x,&intvar)))); /* C89 math */
2867 PUSHs(sv_2mortal(newSVnv(intvar)));
2876 PUSHs(sv_2mortal(newSVnv(c99_remquo(x,y,&intvar))));
2877 PUSHs(sv_2mortal(newSVnv(intvar)));
2890 RETVAL = c99_scalbn(x, y);
2907 RETVAL = c99_fma(x, y, z);
2922 /* If no payload given, just return the default NaN.
2923 * This makes a difference in platforms where the default
2924 * NaN is not all zeros. */
2928 S_setpayload(&RETVAL, payload, FALSE);
2930 #elif defined(c99_nan)
2932 STRLEN elen = my_snprintf(PL_efloatbuf, PL_efloatsize, "%g", payload);
2933 if ((IV)elen == -1) {
2940 RETVAL = c99_nan(PL_efloatbuf);
2964 RETVAL = bessel_jn(x, y);
2974 RETVAL = bessel_yn(x, y);
2986 sigaction(sig, optaction, oldaction = 0)
2989 POSIX::SigAction oldaction
2991 #if defined(WIN32) || defined(NETWARE) || (defined(__amigaos4__) && defined(__NEWLIB__))
2992 RETVAL = not_here("sigaction");
2994 # This code is really grody because we are trying to make the signal
2995 # interface look beautiful, which is hard.
2999 POSIX__SigAction action;
3000 GV *siggv = gv_fetchpvs("SIG", GV_ADD, SVt_PVHV);
3001 struct sigaction act;
3002 struct sigaction oact;
3006 POSIX__SigSet sigset;
3011 croak("Negative signals are not allowed");
3014 if (sig == 0 && SvPOK(ST(0))) {
3015 const char *s = SvPVX_const(ST(0));
3016 int i = whichsig(s);
3018 if (i < 0 && _memEQs(s, "SIG"))
3019 i = whichsig(s + 3);
3021 if (ckWARN(WARN_SIGNAL))
3022 Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
3023 "No such signal: SIG%s", s);
3030 if (sig > NSIG) { /* NSIG - 1 is still okay. */
3031 Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
3032 "No such signal: %d", sig);
3036 sigsvp = hv_fetch(GvHVn(siggv),
3038 strlen(PL_sig_name[sig]),
3041 /* Check optaction and set action */
3042 if(SvTRUE(optaction)) {
3043 if(sv_isa(optaction, "POSIX::SigAction"))
3044 action = (HV*)SvRV(optaction);
3046 croak("action is not of type POSIX::SigAction");
3052 /* sigaction() is supposed to look atomic. In particular, any
3053 * signal handler invoked during a sigaction() call should
3054 * see either the old or the new disposition, and not something
3055 * in between. We use sigprocmask() to make it so.
3058 RETVAL=sigprocmask(SIG_BLOCK, &sset, &osset);
3062 /* Restore signal mask no matter how we exit this block. */
3063 osset_sv = newSVpvn((char *)(&osset), sizeof(sigset_t));
3064 SAVEFREESV( osset_sv );
3065 SAVEDESTRUCTOR_X(restore_sigmask, osset_sv);
3067 RETVAL=-1; /* In case both oldaction and action are 0. */
3069 /* Remember old disposition if desired. */
3071 svp = hv_fetchs(oldaction, "HANDLER", TRUE);
3073 croak("Can't supply an oldaction without a HANDLER");
3074 if(SvTRUE(*sigsvp)) { /* TBD: what if "0"? */
3075 sv_setsv(*svp, *sigsvp);
3078 sv_setpvs(*svp, "DEFAULT");
3080 RETVAL = sigaction(sig, (struct sigaction *)0, & oact);
3085 /* Get back the mask. */
3086 svp = hv_fetchs(oldaction, "MASK", TRUE);
3087 if (sv_isa(*svp, "POSIX::SigSet")) {
3088 sigset = (sigset_t *) SvPV_nolen(SvRV(*svp));
3091 sigset = (sigset_t *) allocate_struct(aTHX_ *svp,
3095 *sigset = oact.sa_mask;
3097 /* Get back the flags. */
3098 svp = hv_fetchs(oldaction, "FLAGS", TRUE);
3099 sv_setiv(*svp, oact.sa_flags);
3101 /* Get back whether the old handler used safe signals. */
3102 svp = hv_fetchs(oldaction, "SAFE", TRUE);
3104 /* compare incompatible pointers by casting to integer */
3105 PTR2nat(oact.sa_handler) == PTR2nat(PL_csighandlerp));
3109 /* Safe signals use "csighandler", which vectors through the
3110 PL_sighandlerp pointer when it's safe to do so.
3111 (BTW, "csighandler" is very different from "sighandler".) */
3112 svp = hv_fetchs(action, "SAFE", FALSE);
3116 (*svp && SvTRUE(*svp))
3117 ? PL_csighandlerp : PL_sighandlerp
3120 /* Vector new Perl handler through %SIG.
3121 (The core signal handlers read %SIG to dispatch.) */
3122 svp = hv_fetchs(action, "HANDLER", FALSE);
3124 croak("Can't supply an action without a HANDLER");
3125 sv_setsv(*sigsvp, *svp);
3127 /* This call actually calls sigaction() with almost the
3128 right settings, including appropriate interpretation
3129 of DEFAULT and IGNORE. However, why are we doing
3130 this when we're about to do it again just below? XXX */
3131 SvSETMAGIC(*sigsvp);
3133 /* And here again we duplicate -- DEFAULT/IGNORE checking. */
3135 const char *s=SvPVX_const(*svp);
3136 if(strEQ(s,"IGNORE")) {
3137 act.sa_handler = SIG_IGN;
3139 else if(strEQ(s,"DEFAULT")) {
3140 act.sa_handler = SIG_DFL;
3144 /* Set up any desired mask. */
3145 svp = hv_fetchs(action, "MASK", FALSE);
3146 if (svp && sv_isa(*svp, "POSIX::SigSet")) {
3147 sigset = (sigset_t *) SvPV_nolen(SvRV(*svp));
3148 act.sa_mask = *sigset;
3151 sigemptyset(& act.sa_mask);
3153 /* Set up any desired flags. */
3154 svp = hv_fetchs(action, "FLAGS", FALSE);
3155 act.sa_flags = svp ? SvIV(*svp) : 0;
3157 /* Don't worry about cleaning up *sigsvp if this fails,
3158 * because that means we tried to disposition a
3159 * nonblockable signal, in which case *sigsvp is
3160 * essentially meaningless anyway.
3162 RETVAL = sigaction(sig, & act, (struct sigaction *)0);
3177 POSIX::SigSet sigset
3182 RETVAL = not_here("sigpending");
3184 RETVAL = ix ? sigsuspend(sigset) : sigpending(sigset);
3192 sigprocmask(how, sigset, oldsigset = 0)
3194 POSIX::SigSet sigset = NO_INIT
3195 POSIX::SigSet oldsigset = NO_INIT
3197 if (! SvOK(ST(1))) {
3199 } else if (sv_isa(ST(1), "POSIX::SigSet")) {
3200 sigset = (sigset_t *) SvPV_nolen(SvRV(ST(1)));
3202 croak("sigset is not of type POSIX::SigSet");
3205 if (items < 3 || ! SvOK(ST(2))) {
3207 } else if (sv_isa(ST(2), "POSIX::SigSet")) {
3208 oldsigset = (sigset_t *) SvPV_nolen(SvRV(ST(2)));
3210 croak("oldsigset is not of type POSIX::SigSet");
3222 if (fd1 >= 0 && fd2 >= 0) {
3224 /* RT #98912 - More Microsoft muppetry - failing to
3225 actually implemented the well known documented POSIX
3226 behaviour for a POSIX API.
3227 http://msdn.microsoft.com/en-us/library/8syseb29.aspx */
3228 RETVAL = dup2(fd1, fd2) == -1 ? -1 : fd2;
3230 RETVAL = dup2(fd1, fd2);
3233 SETERRNO(EBADF,RMS_IFI);
3240 lseek(fd, offset, whence)
3246 Off_t pos = PerlLIO_lseek(fd, offset, whence);
3247 RETVAL = sizeof(Off_t) > sizeof(IV)
3248 ? newSVnv((NV)pos) : newSViv((IV)pos);
3258 if ((incr = nice(incr)) != -1 || errno == 0) {
3260 XPUSHs(newSVpvs_flags("0 but true", SVs_TEMP));
3262 XPUSHs(sv_2mortal(newSViv(incr)));
3269 if (pipe(fds) != -1) {
3271 PUSHs(sv_2mortal(newSViv(fds[0])));
3272 PUSHs(sv_2mortal(newSViv(fds[1])));
3276 read(fd, buffer, nbytes)
3278 SV *sv_buffer = SvROK(ST(1)) ? SvRV(ST(1)) : ST(1);
3282 char * buffer = sv_grow( sv_buffer, nbytes+1 );
3285 SvCUR_set(sv_buffer, RETVAL);
3286 SvPOK_only(sv_buffer);
3287 *SvEND(sv_buffer) = '\0';
3288 SvTAINTED_on(sv_buffer);
3304 tcsetpgrp(fd, pgrp_id)
3313 if (uname(&buf) >= 0) {
3315 PUSHs(newSVpvn_flags(buf.sysname, strlen(buf.sysname), SVs_TEMP));
3316 PUSHs(newSVpvn_flags(buf.nodename, strlen(buf.nodename), SVs_TEMP));
3317 PUSHs(newSVpvn_flags(buf.release, strlen(buf.release), SVs_TEMP));
3318 PUSHs(newSVpvn_flags(buf.version, strlen(buf.version), SVs_TEMP));
3319 PUSHs(newSVpvn_flags(buf.machine, strlen(buf.machine), SVs_TEMP));
3322 uname((char *) 0); /* A stub to call not_here(). */
3326 write(fd, buffer, nbytes)
3340 mbstowcs(s, pwcs, n)
3352 wcstombs(s, pwcs, n)
3374 DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
3375 STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
3376 num = strtod(str, &unparsed);
3377 PUSHs(sv_2mortal(newSVnv(num)));
3378 if (GIMME_V == G_ARRAY) {
3381 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3383 PUSHs(&PL_sv_undef);
3385 RESTORE_LC_NUMERIC_STANDARD();
3396 DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
3397 STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
3398 num = strtold(str, &unparsed);
3399 PUSHs(sv_2mortal(newSVnv(num)));
3400 if (GIMME_V == G_ARRAY) {
3403 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3405 PUSHs(&PL_sv_undef);
3407 RESTORE_LC_NUMERIC_STANDARD();
3412 strtol(str, base = 0)
3419 if (base == 0 || (base >= 2 && base <= 36)) {
3420 num = strtol(str, &unparsed, base);
3421 #if IVSIZE < LONGSIZE
3422 if (num < IV_MIN || num > IV_MAX)
3423 PUSHs(sv_2mortal(newSVnv((double)num)));
3426 PUSHs(sv_2mortal(newSViv((IV)num)));
3427 if (GIMME_V == G_ARRAY) {
3430 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3432 PUSHs(&PL_sv_undef);
3435 SETERRNO(EINVAL, LIB_INVARG);
3436 PUSHs(&PL_sv_undef);
3437 if (GIMME_V == G_ARRAY) {
3439 PUSHs(&PL_sv_undef);
3444 strtoul(str, base = 0)
3451 PERL_UNUSED_VAR(str);
3452 PERL_UNUSED_VAR(base);
3453 if (base == 0 || (base >= 2 && base <= 36)) {
3454 num = strtoul(str, &unparsed, base);
3455 #if IVSIZE <= LONGSIZE
3457 PUSHs(sv_2mortal(newSVnv((double)num)));
3460 PUSHs(sv_2mortal(newSViv((IV)num)));
3461 if (GIMME_V == G_ARRAY) {
3464 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3466 PUSHs(&PL_sv_undef);
3469 SETERRNO(EINVAL, LIB_INVARG);
3470 PUSHs(&PL_sv_undef);
3471 if (GIMME_V == G_ARRAY) {
3473 PUSHs(&PL_sv_undef);
3485 char *p = SvPV(src,srclen);
3487 buflen = srclen * 4 + 1;
3488 ST(0) = sv_2mortal(newSV(buflen));
3489 dstlen = strxfrm(SvPVX(ST(0)), p, (size_t)buflen);
3490 if (dstlen >= buflen) {
3492 SvGROW(ST(0), dstlen);
3493 strxfrm(SvPVX(ST(0)), p, (size_t)dstlen);
3496 SvCUR_set(ST(0), dstlen);
3501 mkfifo(filename, mode)
3508 RETVAL = access(filename, mode);
3510 TAINT_PROPER("mkfifo");
3511 RETVAL = mkfifo(filename, mode);
3524 RETVAL = ix == 1 ? close(fd)
3525 : (ix < 1 ? tcdrain(fd) : dup(fd));
3527 SETERRNO(EBADF,RMS_IFI);
3543 RETVAL = ix == 1 ? tcflush(fd, action)
3544 : (ix < 1 ? tcflow(fd, action) : tcsendbreak(fd, action));
3546 SETERRNO(EINVAL,LIB_INVARG);
3553 asctime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = -1)
3569 init_tm(&mytm); /* XXX workaround - see init_tm() in core util.c */
3572 mytm.tm_hour = hour;
3573 mytm.tm_mday = mday;
3575 mytm.tm_year = year;
3576 mytm.tm_wday = wday;
3577 mytm.tm_yday = yday;
3578 mytm.tm_isdst = isdst;
3580 const time_t result = mktime(&mytm);
3581 if (result == (time_t)-1)
3583 else if (result == 0)
3584 sv_setpvs(TARG, "0 but true");
3586 sv_setiv(TARG, (IV)result);
3588 sv_setpv(TARG, asctime(&mytm));
3606 realtime = times( &tms );
3608 PUSHs( sv_2mortal( newSViv( (IV) realtime ) ) );
3609 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_utime ) ) );
3610 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_stime ) ) );
3611 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cutime ) ) );
3612 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cstime ) ) );
3615 difftime(time1, time2)
3619 #XXX: if $xsubpp::WantOptimize is always the default
3620 # sv_setpv(TARG, ...) could be used rather than
3621 # ST(0) = sv_2mortal(newSVpv(...))
3623 strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1)
3639 /* allowing user-supplied (rather than literal) formats
3640 * is normally frowned upon as a potential security risk;
3641 * but this is part of the API so we have to allow it */
3642 GCC_DIAG_IGNORE(-Wformat-nonliteral);
3643 buf = my_strftime(SvPV_nolen(fmt), sec, min, hour, mday, mon, year, wday, yday, isdst);
3645 sv = sv_newmortal();
3647 STRLEN len = strlen(buf);
3648 sv_usepvn_flags(sv, buf, len, SV_HAS_TRAILING_NUL);
3650 || (! is_utf8_invariant_string((U8*) buf, len)
3651 && is_utf8_string((U8*) buf, len)
3652 #ifdef USE_LOCALE_TIME
3653 && _is_cur_LC_category_utf8(LC_TIME)
3659 else { /* We can't distinguish between errors and just an empty
3660 * return; in all cases just return an empty string */
3661 SvUPGRADE(sv, SVt_PV);
3662 SvPV_set(sv, (char *) "");
3665 SvLEN_set(sv, 0); /* Won't attempt to free the string when sv
3680 PUSHs(newSVpvn_flags(tzname[0], strlen(tzname[0]), SVs_TEMP));
3681 PUSHs(newSVpvn_flags(tzname[1], strlen(tzname[1]), SVs_TEMP));
3687 #ifdef HAS_CTERMID_R
3688 s = (char *) safemalloc((size_t) L_ctermid);
3690 RETVAL = ctermid(s);
3694 #ifdef HAS_CTERMID_R
3703 RETVAL = cuserid(s);
3707 not_here("cuserid");
3718 pathconf(filename, name)
3729 unsigned int seconds
3731 RETVAL = PerlProc_sleep(seconds);
3757 XSprePUSH; PUSHTARG;
3761 lchown(uid, gid, path)
3767 /* yes, the order of arguments is different,
3768 * but consistent with CORE::chown() */
3769 RETVAL = lchown(path, uid, gid);
3771 PERL_UNUSED_VAR(uid);
3772 PERL_UNUSED_VAR(gid);
3773 PERL_UNUSED_VAR(path);
3774 RETVAL = not_here("lchown");