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 #if defined(USE_QUADMATH) && defined(I_QUADMATH)
84 # define M_LOG2E M_LOG2Eq
85 # define M_LOG10E M_LOG10Eq
87 # define M_LN10 M_LN10q
89 # define M_PI_2 M_PI_2q
90 # define M_PI_4 M_PI_4q
91 # define M_1_PI M_1_PIq
92 # define M_2_PI M_2_PIq
93 # define M_2_SQRTPI M_2_SQRTPIq
94 # define M_SQRT2 M_SQRT2q
95 # define M_SQRT1_2 M_SQRT1_2q
99 # ifdef USE_LONG_DOUBLE
113 # define FLOAT_C(c) CAT2(c,L)
115 # define FLOAT_C(c) (c)
119 # define M_E FLOAT_C(2.71828182845904523536028747135266250)
122 # define M_LOG2E FLOAT_C(1.44269504088896340735992468100189214)
125 # define M_LOG10E FLOAT_C(0.434294481903251827651128918916605082)
128 # define M_LN2 FLOAT_C(0.693147180559945309417232121458176568)
131 # define M_LN10 FLOAT_C(2.30258509299404568401799145468436421)
134 # define M_PI FLOAT_C(3.14159265358979323846264338327950288)
137 # define M_PI_2 FLOAT_C(1.57079632679489661923132169163975144)
140 # define M_PI_4 FLOAT_C(0.785398163397448309615660845819875721)
143 # define M_1_PI FLOAT_C(0.318309886183790671537767526745028724)
146 # define M_2_PI FLOAT_C(0.636619772367581343075535053490057448)
149 # define M_2_SQRTPI FLOAT_C(1.12837916709551257389615890312154517)
152 # define M_SQRT2 FLOAT_C(1.41421356237309504880168872420969808)
155 # define M_SQRT1_2 FLOAT_C(0.707106781186547524400844362104849039)
160 #if !defined(INFINITY) && defined(NV_INF)
161 # define INFINITY NV_INF
164 #if !defined(NAN) && defined(NV_NAN)
168 #if !defined(Inf) && defined(NV_INF)
172 #if !defined(NaN) && defined(NV_NAN)
176 /* We will have an emulation. */
178 # define FP_INFINITE 0
181 # define FP_SUBNORMAL 3
185 /* We will have an emulation. */
187 # define FE_TOWARDZERO 0
188 # define FE_TONEAREST 1
190 # define FE_DOWNWARD 3
195 acos asin atan atan2 ceil cos cosh exp fabs floor fmod frexp ldexp
196 log log10 modf pow sin sinh sqrt tan tanh
198 * Implemented in core:
200 atan2 cos exp log pow sin sqrt
204 acosh asinh atanh cbrt copysign erf erfc exp2 expm1 fdim fma fmax
205 fmin fpclassify hypot ilogb isfinite isgreater isgreaterequal isinf
206 isless islessequal islessgreater isnan isnormal isunordered lgamma
207 log1p log2 logb lrint lround nan nearbyint nextafter nexttoward remainder
208 remquo rint round scalbn signbit tgamma trunc
211 http://pubs.opengroup.org/onlinepubs/009695399/basedefs/math.h.html
213 * Berkeley/SVID extensions:
217 * Configure already (5.21.5) scans for:
219 copysign*l* fpclassify isfinite isinf isnan isnan*l* ilogb*l* signbit scalbn*l*
221 * For floating-point round mode (which matters for e.g. lrint and rint)
223 fegetround fesetround
227 /* XXX Constant FP_FAST_FMA (if true, FMA is faster) */
229 /* XXX Add ldiv(), lldiv()? It's C99, but from stdlib.h, not math.h */
231 /* XXX Beware old gamma() -- one cannot know whether that is the
232 * gamma or the log of gamma, that's why the new tgamma and lgamma.
233 * Though also remember lgamma_r. */
235 /* Certain AIX releases have the C99 math, but not in long double.
236 * The <math.h> has them, e.g. __expl128, but no library has them!
238 * Also see the comments in hints/aix.sh about long doubles. */
240 #if defined(USE_QUADMATH) && defined(I_QUADMATH)
241 # define c99_acosh acoshq
242 # define c99_asinh asinhq
243 # define c99_atanh atanhq
244 # define c99_cbrt cbrtq
245 # define c99_copysign copysignq
246 # define c99_erf erfq
247 # define c99_erfc erfcq
249 # define c99_expm1 expm1q
250 # define c99_fdim fdimq
251 # define c99_fma fmaq
252 # define c99_fmax fmaxq
253 # define c99_fmin fminq
254 # define c99_hypot hypotq
255 # define c99_ilogb ilogbq
256 # define c99_lgamma lgammaq
257 # define c99_log1p log1pq
258 # define c99_log2 log2q
260 # if defined(USE_64_BIT_INT) && QUADKIND == QUAD_IS_LONG_LONG
261 # define c99_lrint llrintq
262 # define c99_lround llroundq
264 # define c99_lrint lrintq
265 # define c99_lround lroundq
267 # define c99_nan nanq
268 # define c99_nearbyint nearbyintq
269 # define c99_nextafter nextafterq
271 # define c99_remainder remainderq
272 # define c99_remquo remquoq
273 # define c99_rint rintq
274 # define c99_round roundq
275 # define c99_scalbn scalbnq
276 # define c99_signbit signbitq
277 # define c99_tgamma tgammaq
278 # define c99_trunc truncq
279 # define bessel_j0 j0q
280 # define bessel_j1 j1q
281 # define bessel_jn jnq
282 # define bessel_y0 y0q
283 # define bessel_y1 y1q
284 # define bessel_yn ynq
285 #elif defined(USE_LONG_DOUBLE) && \
286 (defined(HAS_FREXPL) || defined(HAS_ILOGBL)) && defined(HAS_SQRTL)
287 /* Use some of the Configure scans for long double math functions
288 * as the canary for all the C99 *l variants being defined. */
289 # define c99_acosh acoshl
290 # define c99_asinh asinhl
291 # define c99_atanh atanhl
292 # define c99_cbrt cbrtl
293 # define c99_copysign copysignl
294 # define c99_erf erfl
295 # define c99_erfc erfcl
296 # define c99_exp2 exp2l
297 # define c99_expm1 expm1l
298 # define c99_fdim fdiml
299 # define c99_fma fmal
300 # define c99_fmax fmaxl
301 # define c99_fmin fminl
302 # define c99_hypot hypotl
303 # define c99_ilogb ilogbl
304 # define c99_lgamma lgammal
305 # define c99_log1p log1pl
306 # define c99_log2 log2l
307 # define c99_logb logbl
308 # if defined(USE_64_BIT_INT) && QUADKIND == QUAD_IS_LONG_LONG && defined(HAS_LLRINTL)
309 # define c99_lrint llrintl
310 # elif defined(HAS_LRINTL)
311 # define c99_lrint lrintl
313 # if defined(USE_64_BIT_INT) && QUADKIND == QUAD_IS_LONG_LONG && defined(HAS_LLROUNDL)
314 # define c99_lround llroundl
315 # elif defined(HAS_LROUNDL)
316 # define c99_lround lroundl
318 # define c99_nan nanl
319 # define c99_nearbyint nearbyintl
320 # define c99_nextafter nextafterl
321 # define c99_nexttoward nexttowardl
322 # define c99_remainder remainderl
323 # define c99_remquo remquol
324 # define c99_rint rintl
325 # define c99_round roundl
326 # define c99_scalbn scalbnl
327 # ifdef HAS_SIGNBIT /* possibly bad assumption */
328 # define c99_signbit signbitl
330 # define c99_tgamma tgammal
331 # define c99_trunc truncl
333 # define c99_acosh acosh
334 # define c99_asinh asinh
335 # define c99_atanh atanh
336 # define c99_cbrt cbrt
337 # define c99_copysign copysign
339 # define c99_erfc erfc
340 # define c99_exp2 exp2
341 # define c99_expm1 expm1
342 # define c99_fdim fdim
344 # define c99_fmax fmax
345 # define c99_fmin fmin
346 # define c99_hypot hypot
347 # define c99_ilogb ilogb
348 # define c99_lgamma lgamma
349 # define c99_log1p log1p
350 # define c99_log2 log2
351 # define c99_logb logb
352 # if defined(USE_64_BIT_INT) && QUADKIND == QUAD_IS_LONG_LONG && defined(HAS_LLRINT)
353 # define c99_lrint llrint
355 # define c99_lrint lrint
357 # if defined(USE_64_BIT_INT) && QUADKIND == QUAD_IS_LONG_LONG && defined(HAS_LLROUND)
358 # define c99_lround llround
360 # define c99_lround lround
363 # define c99_nearbyint nearbyint
364 # define c99_nextafter nextafter
365 # define c99_nexttoward nexttoward
366 # define c99_remainder remainder
367 # define c99_remquo remquo
368 # define c99_rint rint
369 # define c99_round round
370 # define c99_scalbn scalbn
371 /* We already define Perl_signbit in perl.h. */
373 # define c99_signbit signbit
375 # define c99_tgamma tgamma
376 # define c99_trunc trunc
379 /* AIX xlc (__IBMC__) really doesn't have the following long double
380 * math interfaces (no __acoshl128 aka acoshl, etc.), see
381 * hints/aix.sh. These are in the -lc128 but fail to be found
382 * during dynamic linking/loading.
384 * XXX1 Better Configure scans
385 * XXX2 Is this xlc version dependent? */
386 #if defined(USE_LONG_DOUBLE) && defined(__IBMC__)
406 # undef c99_nearbyint
407 # undef c99_nextafter
408 # undef c99_nexttoward
409 # undef c99_remainder
420 # define isunordered(x, y) (Perl_isnan(x) || Perl_isnan(y))
421 # elif defined(HAS_UNORDERED)
422 # define isunordered(x, y) unordered(x, y)
426 /* XXX these isgreater/isnormal/isunordered macros definitions should
427 * be moved further in the file to be part of the emulations, so that
428 * platforms can e.g. #undef c99_isunordered and have it work like
429 * it does for the other interfaces. */
431 #if !defined(isgreater) && defined(isunordered)
432 # define isgreater(x, y) (!isunordered((x), (y)) && (x) > (y))
433 # define isgreaterequal(x, y) (!isunordered((x), (y)) && (x) >= (y))
434 # define isless(x, y) (!isunordered((x), (y)) && (x) < (y))
435 # define islessequal(x, y) (!isunordered((x), (y)) && (x) <= (y))
436 # define islessgreater(x, y) (!isunordered((x), (y)) && \
437 ((x) > (y) || (y) > (x)))
440 /* Check both the Configure symbol and the macro-ness (like C99 promises). */
441 #if defined(HAS_FPCLASSIFY) && defined(fpclassify)
442 # define c99_fpclassify fpclassify
444 /* Like isnormal(), the isfinite(), isinf(), and isnan() are also C99
445 and also (sizeof-arg-aware) macros, but they are already well taken
446 care of by Configure et al, and defined in perl.h as
447 Perl_isfinite(), Perl_isinf(), and Perl_isnan(). */
449 # define c99_isnormal isnormal
451 #ifdef isgreater /* canary for all the C99 is*<cmp>* macros. */
452 # define c99_isgreater isgreater
453 # define c99_isgreaterequal isgreaterequal
454 # define c99_isless isless
455 # define c99_islessequal islessequal
456 # define c99_islessgreater islessgreater
457 # define c99_isunordered isunordered
460 /* The Great Wall of Undef where according to the definedness of HAS_FOO symbols
461 * the corresponding c99_foo wrappers are undefined. This list doesn't include
462 * the isfoo() interfaces because they are either type-aware macros, or dealt
463 * separately, already in perl.h */
504 #ifndef HAS_FPCLASSIFY
505 # undef c99_fpclassify
534 #ifndef HAS_NEARBYINT
535 # undef c99_nearbyint
537 #ifndef HAS_NEXTAFTER
538 # undef c99_nextafter
540 #ifndef HAS_NEXTTOWARD
541 # undef c99_nexttoward
543 #ifndef HAS_REMAINDER
544 # undef c99_remainder
570 /* Some APIs exist under Win32 with "underbar" names. */
573 # undef c99_nextafter
574 # define c99_hypot _hypot
575 # define c99_logb _logb
576 # define c99_nextafter _nextafter
578 # define bessel_j0 _j0
579 # define bessel_j1 _j1
580 # define bessel_jn _jn
581 # define bessel_y0 _y0
582 # define bessel_y1 _y1
583 # define bessel_yn _yn
587 /* The Bessel functions: BSD, SVID, XPG4, and POSIX. But not C99. */
588 #if defined(HAS_J0) && !defined(bessel_j0)
589 # if defined(USE_LONG_DOUBLE) && defined(HAS_J0L)
590 # define bessel_j0 j0l
591 # define bessel_j1 j1l
592 # define bessel_jn jnl
593 # define bessel_y0 y0l
594 # define bessel_y1 y1l
595 # define bessel_yn ynl
597 # define bessel_j0 j0
598 # define bessel_j1 j1
599 # define bessel_jn jn
600 # define bessel_y0 y0
601 # define bessel_y1 y1
602 # define bessel_yn yn
606 /* Emulations for missing math APIs.
608 * Keep in mind that the point of many of these functions is that
609 * they, if available, are supposed to give more precise/more
610 * numerically stable results.
612 * See e.g. http://www.johndcook.com/math_h.html
616 static NV my_acosh(NV x)
618 return Perl_log(x + Perl_sqrt(x * x - 1));
620 # define c99_acosh my_acosh
624 static NV my_asinh(NV x)
626 return Perl_log(x + Perl_sqrt(x * x + 1));
628 # define c99_asinh my_asinh
632 static NV my_atanh(NV x)
634 return (Perl_log(1 + x) - Perl_log(1 - x)) / 2;
636 # define c99_atanh my_atanh
640 static NV my_cbrt(NV x)
642 static const NV one_third = (NV)1.0/3;
643 return x >= 0.0 ? Perl_pow(x, one_third) : -Perl_pow(-x, one_third);
645 # define c99_cbrt my_cbrt
649 static NV my_copysign(NV x, NV y)
651 return y >= 0 ? (x < 0 ? -x : x) : (x < 0 ? x : -x);
653 # define c99_copysign my_copysign
656 /* XXX cosh (though c89) */
659 static NV my_erf(NV x)
661 /* http://www.johndcook.com/cpp_erf.html -- public domain */
663 NV a2 = -0.284496736;
665 NV a4 = -1.453152027;
669 int sign = x < 0 ? -1 : 1; /* Save the sign. */
672 /* Abramowitz and Stegun formula 7.1.26 */
673 t = 1.0 / (1.0 + p * x);
674 y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1) * t * Perl_exp(-x*x);
678 # define c99_erf my_erf
682 static NV my_erfc(NV x) {
683 /* This is not necessarily numerically stable, but better than nothing. */
684 return 1.0 - c99_erf(x);
686 # define c99_erfc my_erfc
690 static NV my_exp2(NV x)
692 return Perl_pow((NV)2.0, x);
694 # define c99_exp2 my_exp2
698 static NV my_expm1(NV x)
700 if (PERL_ABS(x) < 1e-5)
701 /* http://www.johndcook.com/cpp_expm1.html -- public domain.
702 * Taylor series, the first four terms (the last term quartic). */
703 /* Probably not enough for long doubles. */
704 return x * (1.0 + x * (1/2.0 + x * (1/6.0 + x/24.0)));
706 return Perl_exp(x) - 1;
708 # define c99_expm1 my_expm1
712 static NV my_fdim(NV x, NV y)
715 return (Perl_isnan(x) || Perl_isnan(y)) ? NV_NAN : (x > y ? x - y : 0);
717 return (x > y ? x - y : 0);
720 # define c99_fdim my_fdim
724 static NV my_fma(NV x, NV y, NV z)
728 # define c99_fma my_fma
732 static NV my_fmax(NV x, NV y)
736 return Perl_isnan(y) ? NV_NAN : y;
737 } else if (Perl_isnan(y)) {
741 return x > y ? x : y;
743 # define c99_fmax my_fmax
747 static NV my_fmin(NV x, NV y)
751 return Perl_isnan(y) ? NV_NAN : y;
752 } else if (Perl_isnan(y)) {
756 return x < y ? x : y;
758 # define c99_fmin my_fmin
761 #ifndef c99_fpclassify
763 static IV my_fpclassify(NV x)
765 #ifdef Perl_fp_class_inf
766 if (Perl_fp_class_inf(x)) return FP_INFINITE;
767 if (Perl_fp_class_nan(x)) return FP_NAN;
768 if (Perl_fp_class_norm(x)) return FP_NORMAL;
769 if (Perl_fp_class_denorm(x)) return FP_SUBNORMAL;
770 if (Perl_fp_class_zero(x)) return FP_ZERO;
771 # define c99_fpclassify my_fpclassify
779 static NV my_hypot(NV x, NV y)
781 /* http://en.wikipedia.org/wiki/Hypot */
783 x = PERL_ABS(x); /* Take absolute values. */
791 if (x < y) { /* Swap so that y is less. */
797 return x * Perl_sqrt(1.0 + t * t);
799 # define c99_hypot my_hypot
803 static IV my_ilogb(NV x)
805 return (IV)(Perl_log(x) * M_LOG2E);
807 # define c99_ilogb my_ilogb
810 /* tgamma and lgamma emulations based on
811 * http://www.johndcook.com/cpp_gamma.html,
812 * code placed in public domain.
814 * Note that these implementations (neither the johndcook originals
815 * nor these) do NOT set the global signgam variable. This is not
816 * necessarily a bad thing. */
818 /* Note that the tgamma() and lgamma() implementations
819 * here depend on each other. */
821 #if !defined(HAS_TGAMMA) || !defined(c99_tgamma)
822 static NV my_tgamma(NV x);
823 # define c99_tgamma my_tgamma
824 # define USE_MY_TGAMMA
826 #if !defined(HAS_LGAMMA) || !defined(c99_lgamma)
827 static NV my_lgamma(NV x);
828 # define c99_lgamma my_lgamma
829 # define USE_MY_LGAMMA
833 static NV my_tgamma(NV x)
835 const NV gamma = 0.577215664901532860606512090; /* Euler's gamma constant. */
837 if (Perl_isnan(x) || x < 0.0)
841 if (x == 0.0 || x == NV_INF)
842 #ifdef DOUBLE_IS_IEEE_FORMAT
843 return x == -0.0 ? -NV_INF : NV_INF;
849 /* The function domain is split into three intervals:
850 * (0, 0.001), [0.001, 12), and (12, infinity) */
852 /* First interval: (0, 0.001)
853 * For small values, 1/tgamma(x) has power series x + gamma x^2,
854 * so in this range, 1/tgamma(x) = x + gamma x^2 with error on the order of x^3.
855 * The relative error over this interval is less than 6e-7. */
857 return 1.0 / (x * (1.0 + gamma * x));
859 /* Second interval: [0.001, 12) */
861 double y = x; /* Working copy. */
863 /* Numerator coefficients for approximation over the interval (1,2) */
864 static const NV p[] = {
865 -1.71618513886549492533811E+0,
866 2.47656508055759199108314E+1,
867 -3.79804256470945635097577E+2,
868 6.29331155312818442661052E+2,
869 8.66966202790413211295064E+2,
870 -3.14512729688483675254357E+4,
871 -3.61444134186911729807069E+4,
872 6.64561438202405440627855E+4
874 /* Denominator coefficients for approximation over the interval (1, 2) */
875 static const NV q[] = {
876 -3.08402300119738975254353E+1,
877 3.15350626979604161529144E+2,
878 -1.01515636749021914166146E+3,
879 -3.10777167157231109440444E+3,
880 2.25381184209801510330112E+4,
881 4.75584627752788110767815E+3,
882 -1.34659959864969306392456E+5,
883 -1.15132259675553483497211E+5
894 n = (int)Perl_floor(y) - 1;
898 for (i = 0; i < 8; i++) {
899 num = (num + p[i]) * z;
900 den = den * z + q[i];
902 result = num / den + 1.0;
905 /* Use the identity tgamma(z) = tgamma(z+1)/z
906 * The variable "result" now holds tgamma of the original y + 1
907 * Thus we use y - 1 to get back the original y. */
911 /* Use the identity tgamma(z+n) = z*(z+1)* ... *(z+n-1)*tgamma(z) */
912 for (i = 0; i < n; i++)
920 /* Third interval: [12, +Inf) */
921 #if LDBL_MANT_DIG == 113 /* IEEE quad prec */
932 return Perl_exp(c99_lgamma(x));
937 static NV my_lgamma(NV x)
944 if (x <= 0 || x == NV_INF)
947 if (x == 1.0 || x == 2.0)
950 return Perl_log(PERL_ABS(c99_tgamma(x)));
951 /* Abramowitz and Stegun 6.1.41
952 * Asymptotic series should be good to at least 11 or 12 figures
953 * For error analysis, see Whittiker and Watson
954 * A Course in Modern Analysis (1927), page 252 */
956 static const NV c[8] = {
966 NV z = 1.0 / (x * x);
968 static const NV half_log_of_two_pi =
969 0.91893853320467274178032973640562;
972 for (i = 6; i >= 0; i--) {
977 return (x - 0.5) * Perl_log(x) - x + half_log_of_two_pi + series;
983 static NV my_log1p(NV x)
985 /* http://www.johndcook.com/cpp_log_one_plus_x.html -- public domain.
986 * Taylor series, the first four terms (the last term quartic). */
995 if (PERL_ABS(x) > 1e-4)
996 return Perl_log(1.0 + x);
998 /* Probably not enough for long doubles. */
999 return x * (1.0 + x * (-1/2.0 + x * (1/3.0 - x/4.0)));
1001 # define c99_log1p my_log1p
1005 static NV my_log2(NV x)
1007 return Perl_log(x) * M_LOG2E;
1009 # define c99_log2 my_log2
1014 /* XXX nexttoward */
1016 static int my_fegetround()
1018 #ifdef HAS_FEGETROUND
1019 return fegetround();
1020 #elif defined(HAS_FPGETROUND)
1021 switch (fpgetround()) {
1022 case FP_RN: return FE_TONEAREST;
1023 case FP_RZ: return FE_TOWARDZERO;
1024 case FP_RM: return FE_DOWNWARD;
1025 case FP_RP: return FE_UPWARD;
1028 #elif defined(FLT_ROUNDS)
1029 switch (FLT_ROUNDS) {
1030 case 0: return FE_TOWARDZERO;
1031 case 1: return FE_TONEAREST;
1032 case 2: return FE_UPWARD;
1033 case 3: return FE_DOWNWARD;
1036 #elif defined(__osf__) /* Tru64 */
1037 switch (read_rnd()) {
1038 case FP_RND_RN: return FE_TONEAREST;
1039 case FP_RND_RZ: return FE_TOWARDZERO;
1040 case FP_RND_RM: return FE_DOWNWARD;
1041 case FP_RND_RP: return FE_UPWARD;
1049 /* Toward closest integer. */
1050 #define MY_ROUND_NEAREST(x) ((NV)((IV)((x) >= 0.0 ? (x) + 0.5 : (x) - 0.5)))
1053 #define MY_ROUND_TRUNC(x) ((NV)((IV)(x)))
1055 /* Toward minus infinity. */
1056 #define MY_ROUND_DOWN(x) ((NV)((IV)((x) >= 0.0 ? (x) : (x) - 0.5)))
1058 /* Toward plus infinity. */
1059 #define MY_ROUND_UP(x) ((NV)((IV)((x) >= 0.0 ? (x) + 0.5 : (x))))
1061 #if (!defined(c99_nearbyint) || !defined(c99_lrint)) && defined(FE_TONEAREST)
1062 static NV my_rint(NV x)
1065 switch (my_fegetround()) {
1066 case FE_TONEAREST: return MY_ROUND_NEAREST(x);
1067 case FE_TOWARDZERO: return MY_ROUND_TRUNC(x);
1068 case FE_DOWNWARD: return MY_ROUND_DOWN(x);
1069 case FE_UPWARD: return MY_ROUND_UP(x);
1072 #elif defined(HAS_FPGETROUND)
1073 switch (fpgetround()) {
1074 case FP_RN: return MY_ROUND_NEAREST(x);
1075 case FP_RZ: return MY_ROUND_TRUNC(x);
1076 case FP_RM: return MY_ROUND_DOWN(x);
1077 case FE_RP: return MY_ROUND_UP(x);
1085 /* XXX nearbyint() and rint() are not really identical -- but the difference
1086 * is messy: nearbyint is defined NOT to raise FE_INEXACT floating point
1087 * exceptions, while rint() is defined to MAYBE raise them. At the moment
1088 * Perl is blissfully unaware of such fine detail of floating point. */
1089 #ifndef c99_nearbyint
1090 # ifdef FE_TONEAREST
1091 # define c99_nearbyrint my_rint
1096 # ifdef FE_TONEAREST
1097 static IV my_lrint(NV x)
1099 return (IV)my_rint(x);
1101 # define c99_lrint my_lrint
1106 static IV my_lround(NV x)
1108 return (IV)MY_ROUND_NEAREST(x);
1110 # define c99_lround my_lround
1118 # ifdef FE_TONEAREST
1119 # define c99_rint my_rint
1124 static NV my_round(NV x)
1126 return MY_ROUND_NEAREST(x);
1128 # define c99_round my_round
1132 # if defined(Perl_ldexp) && FLT_RADIX == 2
1133 static NV my_scalbn(NV x, int y)
1135 return Perl_ldexp(x, y);
1137 # define c99_scalbn my_scalbn
1141 /* XXX sinh (though c89) */
1143 /* tgamma -- see lgamma */
1145 /* XXX tanh (though c89) */
1148 static NV my_trunc(NV x)
1150 return MY_ROUND_TRUNC(x);
1152 # define c99_trunc my_trunc
1157 #undef NV_PAYLOAD_DEBUG
1159 /* NOTE: the NaN payload API implementation is hand-rolled, since the
1160 * APIs are only proposed ones as of June 2015, so very few, if any,
1161 * platforms have implementations yet, so HAS_SETPAYLOAD and such are
1162 * unlikely to be helpful.
1164 * XXX - if the core numification wants to actually generate
1165 * the nan payload in "nan(123)", and maybe "nans(456)", for
1166 * signaling payload", this needs to be moved to e.g. numeric.c
1167 * (look for grok_infnan)
1169 * Conversely, if the core stringification wants the nan payload
1170 * and/or the nan quiet/signaling distinction, S_getpayload()
1171 * from this file needs to be moved, to e.g. sv.c (look for S_infnan_2pv),
1172 * and the (trivial) functionality of issignaling() copied
1173 * (for generating "NaNS", or maybe even "NaNQ") -- or maybe there
1174 * are too many formatting parameters for simple stringification?
1177 /* While it might make sense for the payload to be UV or IV,
1178 * to avoid conversion loss, the proposed ISO interfaces use
1179 * a floating point input, which is then truncated to integer,
1180 * and only the integer part being used. This is workable,
1181 * except for: (1) the conversion loss (2) suboptimal for
1182 * 32-bit integer platforms. A workaround API for (2) and
1183 * in general for bit-honesty would be an array of integers
1184 * as the payload... but the proposed C API does nothing of
1186 #if NVSIZE == UVSIZE
1187 # define NV_PAYLOAD_TYPE UV
1189 # define NV_PAYLOAD_TYPE NV
1192 #if defined(USE_LONG_DOUBLE) && defined(LONGDOUBLE_DOUBLEDOUBLE)
1193 # define NV_PAYLOAD_SIZEOF_ASSERT(a) \
1194 STATIC_ASSERT_STMT(sizeof(a) == NVSIZE / 2)
1196 # define NV_PAYLOAD_SIZEOF_ASSERT(a) \
1197 STATIC_ASSERT_STMT(sizeof(a) == NVSIZE)
1200 static void S_setpayload(NV* nvp, NV_PAYLOAD_TYPE payload, bool signaling)
1203 static const U8 m[] = { NV_NAN_PAYLOAD_MASK };
1204 static const U8 p[] = { NV_NAN_PAYLOAD_PERM };
1205 UV a[(NVSIZE + UVSIZE - 1) / UVSIZE] = { 0 };
1207 NV_PAYLOAD_SIZEOF_ASSERT(m);
1208 NV_PAYLOAD_SIZEOF_ASSERT(p);
1210 /* Divide the input into the array in "base unsigned integer" in
1211 * little-endian order. Note that the integer might be smaller than
1212 * an NV (if UV is U32, for example). */
1213 #if NVSIZE == UVSIZE
1214 a[0] = payload; /* The trivial case. */
1217 NV t1 = c99_trunc(payload); /* towards zero (drop fractional) */
1218 #ifdef NV_PAYLOAD_DEBUG
1219 Perl_warn(aTHX_ "t1 = %" NVgf " (payload %" NVgf ")\n", t1, payload);
1222 a[0] = (UV)t1; /* Fast path, also avoids rounding errors (right?) */
1224 /* UVSIZE < NVSIZE or payload > UV_MAX.
1226 * This may happen for example if:
1227 * (1) UVSIZE == 32 and common 64-bit double NV
1228 * (32-bit system not using -Duse64bitint)
1229 * (2) UVSIZE == 64 and the x86-style 80-bit long double NV
1230 * (note that here the room for payload is actually the 64 bits)
1231 * (3) UVSIZE == 64 and the 128-bit IEEE 764 quadruple NV
1232 * (112 bits in mantissa, 111 bits room for payload)
1234 * NOTE: this is very sensitive to correctly functioning
1235 * fmod()/fmodl(), and correct casting of big-unsigned-integer to NV.
1236 * If these don't work right, especially the low order bits
1237 * are in danger. For example Solaris and AIX seem to have issues
1238 * here, especially if using 32-bit UVs. */
1240 for (i = 0, t2 = t1; i < (int)C_ARRAY_LENGTH(a); i++) {
1241 a[i] = (UV)Perl_fmod(t2, (NV)UV_MAX);
1242 t2 = Perl_floor(t2 / (NV)UV_MAX);
1247 #ifdef NV_PAYLOAD_DEBUG
1248 for (i = 0; i < (int)C_ARRAY_LENGTH(a); i++) {
1249 Perl_warn(aTHX_ "a[%d] = 0x%" UVxf "\n", i, a[i]);
1252 for (i = 0; i < (int)sizeof(p); i++) {
1253 if (m[i] && p[i] < sizeof(p)) {
1254 U8 s = (p[i] % UVSIZE) << 3;
1255 UV u = a[p[i] / UVSIZE] & ((UV)0xFF << s);
1256 U8 b = (U8)((u >> s) & m[i]);
1257 ((U8 *)(nvp))[i] &= ~m[i]; /* For NaNs with non-zero payload bits. */
1258 ((U8 *)(nvp))[i] |= b;
1259 #ifdef NV_PAYLOAD_DEBUG
1261 "set p[%2d] = %02x (i = %d, m = %02x, s = %2d, b = %02x, u = %08"
1262 UVxf ")\n", i, ((U8 *)(nvp))[i], i, m[i], s, b, u);
1264 a[p[i] / UVSIZE] &= ~u;
1268 NV_NAN_SET_SIGNALING(nvp);
1270 #ifdef USE_LONG_DOUBLE
1271 # if LONG_DOUBLEKIND == 3 || LONG_DOUBLEKIND == 4
1272 # if LONG_DOUBLESIZE > 10
1273 memset((char *)nvp + 10, '\0', LONG_DOUBLESIZE - 10); /* x86 long double */
1277 for (i = 0; i < (int)C_ARRAY_LENGTH(a); i++) {
1279 Perl_warn(aTHX_ "payload lost bits (%" UVxf ")", a[i]);
1283 #ifdef NV_PAYLOAD_DEBUG
1284 for (i = 0; i < NVSIZE; i++) {
1285 PerlIO_printf(Perl_debug_log, "%02x ", ((U8 *)(nvp))[i]);
1287 PerlIO_printf(Perl_debug_log, "\n");
1291 static NV_PAYLOAD_TYPE S_getpayload(NV nv)
1294 static const U8 m[] = { NV_NAN_PAYLOAD_MASK };
1295 static const U8 p[] = { NV_NAN_PAYLOAD_PERM };
1296 UV a[(NVSIZE + UVSIZE - 1) / UVSIZE] = { 0 };
1299 NV_PAYLOAD_SIZEOF_ASSERT(m);
1300 NV_PAYLOAD_SIZEOF_ASSERT(p);
1302 for (i = 0; i < (int)sizeof(p); i++) {
1303 if (m[i] && p[i] < NVSIZE) {
1304 U8 s = (p[i] % UVSIZE) << 3;
1305 a[p[i] / UVSIZE] |= (UV)(((U8 *)(&nv))[i] & m[i]) << s;
1308 for (i = (int)C_ARRAY_LENGTH(a) - 1; i >= 0; i--) {
1309 #ifdef NV_PAYLOAD_DEBUG
1310 Perl_warn(aTHX_ "a[%d] = %" UVxf "\n", i, a[i]);
1315 #ifdef NV_PAYLOAD_DEBUG
1316 for (i = 0; i < NVSIZE; i++) {
1317 PerlIO_printf(Perl_debug_log, "%02x ", ((U8 *)(&nv))[i]);
1319 PerlIO_printf(Perl_debug_log, "\n");
1324 #endif /* #ifdef NV_NAN */
1326 /* XXX This comment is just to make I_TERMIO and I_SGTTY visible to
1327 metaconfig for future extension writers. We don't use them in POSIX.
1328 (This is really sneaky :-) --AD
1330 #if defined(I_TERMIOS)
1331 #include <termios.h>
1337 #include <sys/stat.h>
1338 #include <sys/types.h>
1346 # if !defined(WIN32) && !defined(__CYGWIN__) && !defined(NETWARE) && !defined(__UWIN__)
1347 extern char *tzname[];
1350 #if !defined(WIN32) && !defined(__UWIN__) || (defined(__MINGW32__) && !defined(tzname))
1351 char *tzname[] = { "" , "" };
1355 #if defined(__VMS) && !defined(__POSIX_SOURCE)
1357 # include <utsname.h>
1360 # define mkfifo(a,b) (not_here("mkfifo"),-1)
1362 /* The POSIX notion of ttyname() is better served by getname() under VMS */
1363 static char ttnambuf[64];
1364 # define ttyname(fd) (isatty(fd) > 0 ? getname(fd,ttnambuf,0) : NULL)
1367 #if defined (__CYGWIN__)
1368 # define tzname _tzname
1370 #if defined (WIN32) || defined (NETWARE)
1372 # define mkfifo(a,b) not_here("mkfifo")
1373 # define ttyname(a) (char*)not_here("ttyname")
1374 # define sigset_t long
1377 # define mode_t short
1380 # define mode_t short
1382 # define tzset() not_here("tzset")
1384 # ifndef _POSIX_OPEN_MAX
1385 # define _POSIX_OPEN_MAX FOPEN_MAX /* XXX bogus ? */
1388 # define sigaction(a,b,c) not_here("sigaction")
1389 # define sigpending(a) not_here("sigpending")
1390 # define sigprocmask(a,b,c) not_here("sigprocmask")
1391 # define sigsuspend(a) not_here("sigsuspend")
1392 # define sigemptyset(a) not_here("sigemptyset")
1393 # define sigaddset(a,b) not_here("sigaddset")
1394 # define sigdelset(a,b) not_here("sigdelset")
1395 # define sigfillset(a) not_here("sigfillset")
1396 # define sigismember(a,b) not_here("sigismember")
1400 # define setuid(a) not_here("setuid")
1401 # define setgid(a) not_here("setgid")
1402 #endif /* NETWARE */
1403 #ifndef USE_LONG_DOUBLE
1404 # define strtold(s1,s2) not_here("strtold")
1405 #endif /* USE_LONG_DOUBLE */
1409 # if defined(OS2) || defined(__amigaos4__)
1410 # define mkfifo(a,b) not_here("mkfifo")
1411 # else /* !( defined OS2 ) */
1413 # define mkfifo(path, mode) (mknod((path), (mode) | S_IFIFO, 0))
1416 # endif /* !HAS_MKFIFO */
1421 # include <sys/times.h>
1423 # include <sys/utsname.h>
1425 # ifndef __amigaos4__
1426 # include <sys/wait.h>
1431 #endif /* WIN32 || NETWARE */
1435 typedef long SysRetLong;
1436 typedef sigset_t* POSIX__SigSet;
1437 typedef HV* POSIX__SigAction;
1438 typedef int POSIX__SigNo;
1439 typedef int POSIX__Fd;
1441 typedef struct termios* POSIX__Termios;
1442 #else /* Define termios types to int, and call not_here for the functions.*/
1443 #define POSIX__Termios int
1445 #define tcflag_t int
1447 #define cfgetispeed(x) not_here("cfgetispeed")
1448 #define cfgetospeed(x) not_here("cfgetospeed")
1449 #define tcdrain(x) not_here("tcdrain")
1450 #define tcflush(x,y) not_here("tcflush")
1451 #define tcsendbreak(x,y) not_here("tcsendbreak")
1452 #define cfsetispeed(x,y) not_here("cfsetispeed")
1453 #define cfsetospeed(x,y) not_here("cfsetospeed")
1454 #define ctermid(x) (char *) not_here("ctermid")
1455 #define tcflow(x,y) not_here("tcflow")
1456 #define tcgetattr(x,y) not_here("tcgetattr")
1457 #define tcsetattr(x,y,z) not_here("tcsetattr")
1460 /* Possibly needed prototypes */
1463 double strtod (const char *, char **);
1464 long strtol (const char *, char **, int);
1465 unsigned long strtoul (const char *, char **, int);
1467 long double strtold (const char *, char **);
1472 #ifndef HAS_DIFFTIME
1474 #define difftime(a,b) not_here("difftime")
1477 #ifndef HAS_FPATHCONF
1478 #define fpathconf(f,n) (SysRetLong) not_here("fpathconf")
1481 #define mktime(a) not_here("mktime")
1484 #define nice(a) not_here("nice")
1486 #ifndef HAS_PATHCONF
1487 #define pathconf(f,n) (SysRetLong) not_here("pathconf")
1490 #define sysconf(n) (SysRetLong) not_here("sysconf")
1492 #ifndef HAS_READLINK
1493 #define readlink(a,b,c) not_here("readlink")
1496 #define setpgid(a,b) not_here("setpgid")
1499 #define setsid() not_here("setsid")
1502 #define strcoll(s1,s2) not_here("strcoll")
1505 #define strtod(s1,s2) not_here("strtod")
1508 #define strtold(s1,s2) not_here("strtold")
1511 #define strtol(s1,s2,b) not_here("strtol")
1514 #define strtoul(s1,s2,b) not_here("strtoul")
1517 #define strxfrm(s1,s2,n) not_here("strxfrm")
1519 #ifndef HAS_TCGETPGRP
1520 #define tcgetpgrp(a) not_here("tcgetpgrp")
1522 #ifndef HAS_TCSETPGRP
1523 #define tcsetpgrp(a,b) not_here("tcsetpgrp")
1527 #define times(a) not_here("times")
1528 #endif /* NETWARE */
1531 #define uname(a) not_here("uname")
1534 #define waitpid(a,b,c) not_here("waitpid")
1539 #define mblen(a,b) not_here("mblen")
1542 #ifndef HAS_MBSTOWCS
1543 #define mbstowcs(s, pwcs, n) not_here("mbstowcs")
1546 #define mbtowc(pwc, s, n) not_here("mbtowc")
1548 #ifndef HAS_WCSTOMBS
1549 #define wcstombs(s, pwcs, n) not_here("wcstombs")
1552 #define wctomb(s, wchar) not_here("wcstombs")
1554 #if !defined(HAS_MBLEN) && !defined(HAS_MBSTOWCS) && !defined(HAS_MBTOWC) && !defined(HAS_WCSTOMBS) && !defined(HAS_WCTOMB)
1555 /* If we don't have these functions, then we wouldn't have gotten a typedef
1556 for wchar_t, the wide character type. Defining wchar_t allows the
1557 functions referencing it to compile. Its actual type is then meaningless,
1558 since without the above functions, all sections using it end up calling
1559 not_here() and croak. --Kaveh Ghazi (ghazi@noc.rutgers.edu) 9/18/94. */
1561 #define wchar_t char
1565 #ifndef HAS_LOCALECONV
1566 # define localeconv() not_here("localeconv")
1568 struct lconv_offset {
1573 static const struct lconv_offset lconv_strings[] = {
1574 #ifdef USE_LOCALE_NUMERIC
1575 {"decimal_point", STRUCT_OFFSET(struct lconv, decimal_point)},
1576 {"thousands_sep", STRUCT_OFFSET(struct lconv, thousands_sep)},
1577 # ifndef NO_LOCALECONV_GROUPING
1578 {"grouping", STRUCT_OFFSET(struct lconv, grouping)},
1581 #ifdef USE_LOCALE_MONETARY
1582 {"int_curr_symbol", STRUCT_OFFSET(struct lconv, int_curr_symbol)},
1583 {"currency_symbol", STRUCT_OFFSET(struct lconv, currency_symbol)},
1584 {"mon_decimal_point", STRUCT_OFFSET(struct lconv, mon_decimal_point)},
1585 # ifndef NO_LOCALECONV_MON_THOUSANDS_SEP
1586 {"mon_thousands_sep", STRUCT_OFFSET(struct lconv, mon_thousands_sep)},
1588 # ifndef NO_LOCALECONV_MON_GROUPING
1589 {"mon_grouping", STRUCT_OFFSET(struct lconv, mon_grouping)},
1591 {"positive_sign", STRUCT_OFFSET(struct lconv, positive_sign)},
1592 {"negative_sign", STRUCT_OFFSET(struct lconv, negative_sign)},
1597 #ifdef USE_LOCALE_NUMERIC
1599 /* The Linux man pages say these are the field names for the structure
1600 * components that are LC_NUMERIC; the rest being LC_MONETARY */
1601 # define isLC_NUMERIC_STRING(name) ( strEQ(name, "decimal_point") \
1602 || strEQ(name, "thousands_sep") \
1604 /* There should be no harm done \
1605 * checking for this, even if \
1606 * NO_LOCALECONV_GROUPING */ \
1607 || strEQ(name, "grouping"))
1609 # define isLC_NUMERIC_STRING(name) (0)
1612 static const struct lconv_offset lconv_integers[] = {
1613 #ifdef USE_LOCALE_MONETARY
1614 {"int_frac_digits", STRUCT_OFFSET(struct lconv, int_frac_digits)},
1615 {"frac_digits", STRUCT_OFFSET(struct lconv, frac_digits)},
1616 {"p_cs_precedes", STRUCT_OFFSET(struct lconv, p_cs_precedes)},
1617 {"p_sep_by_space", STRUCT_OFFSET(struct lconv, p_sep_by_space)},
1618 {"n_cs_precedes", STRUCT_OFFSET(struct lconv, n_cs_precedes)},
1619 {"n_sep_by_space", STRUCT_OFFSET(struct lconv, n_sep_by_space)},
1620 {"p_sign_posn", STRUCT_OFFSET(struct lconv, p_sign_posn)},
1621 {"n_sign_posn", STRUCT_OFFSET(struct lconv, n_sign_posn)},
1622 #ifdef HAS_LC_MONETARY_2008
1623 {"int_p_cs_precedes", STRUCT_OFFSET(struct lconv, int_p_cs_precedes)},
1624 {"int_p_sep_by_space", STRUCT_OFFSET(struct lconv, int_p_sep_by_space)},
1625 {"int_n_cs_precedes", STRUCT_OFFSET(struct lconv, int_n_cs_precedes)},
1626 {"int_n_sep_by_space", STRUCT_OFFSET(struct lconv, int_n_sep_by_space)},
1627 {"int_p_sign_posn", STRUCT_OFFSET(struct lconv, int_p_sign_posn)},
1628 {"int_n_sign_posn", STRUCT_OFFSET(struct lconv, int_n_sign_posn)},
1634 #endif /* HAS_LOCALECONV */
1636 #ifdef HAS_LONG_DOUBLE
1637 # if LONG_DOUBLESIZE > NVSIZE
1638 # undef HAS_LONG_DOUBLE /* XXX until we figure out how to use them */
1642 #ifndef HAS_LONG_DOUBLE
1654 /* Background: in most systems the low byte of the wait status
1655 * is the signal (the lowest 7 bits) and the coredump flag is
1656 * the eight bit, and the second lowest byte is the exit status.
1657 * BeOS bucks the trend and has the bytes in different order.
1658 * See beos/beos.c for how the reality is bent even in BeOS
1659 * to follow the traditional. However, to make the POSIX
1660 * wait W*() macros to work in BeOS, we need to unbend the
1661 * reality back in place. --jhi */
1662 /* In actual fact the code below is to blame here. Perl has an internal
1663 * representation of the exit status ($?), which it re-composes from the
1664 * OS's representation using the W*() POSIX macros. The code below
1665 * incorrectly uses the W*() macros on the internal representation,
1666 * which fails for OSs that have a different representation (namely BeOS
1667 * and Haiku). WMUNGE() is a hack that converts the internal
1668 * representation into the OS specific one, so that the W*() macros work
1669 * as expected. The better solution would be not to use the W*() macros
1670 * in the first place, though. -- Ingo Weinhold
1672 #if defined(__HAIKU__)
1673 # define WMUNGE(x) (((x) & 0xFF00) >> 8 | ((x) & 0x00FF) << 8)
1675 # define WMUNGE(x) (x)
1679 not_here(const char *s)
1681 croak("POSIX::%s not implemented on this architecture", s);
1685 #include "const-c.inc"
1688 restore_sigmask(pTHX_ SV *osset_sv)
1690 /* Fortunately, restoring the signal mask can't fail, because
1691 * there's nothing we can do about it if it does -- we're not
1692 * supposed to return -1 from sigaction unless the disposition
1695 #if !(defined(__amigaos4__) && defined(__NEWLIB__))
1696 sigset_t *ossetp = (sigset_t *) SvPV_nolen( osset_sv );
1697 (void)sigprocmask(SIG_SETMASK, ossetp, (sigset_t *)0);
1702 allocate_struct(pTHX_ SV *rv, const STRLEN size, const char *packname) {
1703 SV *const t = newSVrv(rv, packname);
1704 void *const p = sv_grow(t, size + 1);
1706 /* Ensure at least one use of not_here() to avoid "defined but not
1707 * used" warning. This is not at all related to allocate_struct(); I
1708 * just needed somewhere to dump it - DAPM */
1709 if (0) { not_here(""); }
1719 * (1) The CRT maintains its own copy of the environment, separate from
1720 * the Win32API copy.
1722 * (2) CRT getenv() retrieves from this copy. CRT putenv() updates this
1723 * copy, and then calls SetEnvironmentVariableA() to update the Win32API
1726 * (3) win32_getenv() and win32_putenv() call GetEnvironmentVariableA() and
1727 * SetEnvironmentVariableA() directly, bypassing the CRT copy of the
1730 * (4) The CRT strftime() "%Z" implementation calls __tzset(). That
1731 * calls CRT tzset(), but only the first time it is called, and in turn
1732 * that uses CRT getenv("TZ") to retrieve the timezone info from the CRT
1733 * local copy of the environment and hence gets the original setting as
1734 * perl never updates the CRT copy when assigning to $ENV{TZ}.
1736 * Therefore, we need to retrieve the value of $ENV{TZ} and call CRT
1737 * putenv() to update the CRT copy of the environment (if it is different)
1738 * whenever we're about to call tzset().
1740 * In addition to all that, when perl is built with PERL_IMPLICIT_SYS
1743 * (a) Each interpreter has its own copy of the environment inside the
1744 * perlhost structure. That allows applications that host multiple
1745 * independent Perl interpreters to isolate environment changes from
1746 * each other. (This is similar to how the perlhost mechanism keeps a
1747 * separate working directory for each Perl interpreter, so that calling
1748 * chdir() will not affect other interpreters.)
1750 * (b) Only the first Perl interpreter instantiated within a process will
1751 * "write through" environment changes to the process environment.
1753 * (c) Even the primary Perl interpreter won't update the CRT copy of the
1754 * the environment, only the Win32API copy (it calls win32_putenv()).
1756 * As with CPerlHost::Getenv() and CPerlHost::Putenv() themselves, it makes
1757 * sense to only update the process environment when inside the main
1758 * interpreter, but we don't have access to CPerlHost's m_bTopLevel member
1759 * from here so we'll just have to check PL_curinterp instead.
1761 * Therefore, we can simply #undef getenv() and putenv() so that those names
1762 * always refer to the CRT functions, and explicitly call win32_getenv() to
1763 * access perl's %ENV.
1765 * We also #undef malloc() and free() to be sure we are using the CRT
1766 * functions otherwise under PERL_IMPLICIT_SYS they are redefined to calls
1767 * into VMem::Malloc() and VMem::Free() and all allocations will be freed
1768 * when the Perl interpreter is being destroyed so we'd end up with a pointer
1769 * into deallocated memory in environ[] if a program embedding a Perl
1770 * interpreter continues to operate even after the main Perl interpreter has
1773 * Note that we don't free() the malloc()ed memory unless and until we call
1774 * malloc() again ourselves because the CRT putenv() function simply puts its
1775 * pointer argument into the environ[] array (it doesn't make a copy of it)
1776 * so this memory must otherwise be leaked.
1785 fix_win32_tzenv(void)
1787 static char* oldenv = NULL;
1789 const char* perl_tz_env = win32_getenv("TZ");
1790 const char* crt_tz_env = getenv("TZ");
1791 if (perl_tz_env == NULL)
1793 if (crt_tz_env == NULL)
1795 if (strNE(perl_tz_env, crt_tz_env)) {
1796 newenv = (char*)malloc((strlen(perl_tz_env) + 4) * sizeof(char));
1797 if (newenv != NULL) {
1798 sprintf(newenv, "TZ=%s", perl_tz_env);
1810 * my_tzset - wrapper to tzset() with a fix to make it work (better) on Win32.
1811 * This code is duplicated in the Time-Piece module, so any changes made here
1812 * should be made there too.
1818 #if defined(USE_ITHREADS) && defined(PERL_IMPLICIT_SYS)
1819 if (PL_curinterp == aTHX)
1826 MODULE = SigSet PACKAGE = POSIX::SigSet PREFIX = sig
1829 new(packname = "POSIX::SigSet", ...)
1830 const char * packname
1835 = (sigset_t *) allocate_struct(aTHX_ (ST(0) = sv_newmortal()),
1839 for (i = 1; i < items; i++)
1840 sigaddset(s, SvIV(ST(i)));
1846 POSIX::SigSet sigset
1851 RETVAL = ix ? sigdelset(sigset, sig) : sigaddset(sigset, sig);
1857 POSIX::SigSet sigset
1861 RETVAL = ix ? sigfillset(sigset) : sigemptyset(sigset);
1866 sigismember(sigset, sig)
1867 POSIX::SigSet sigset
1870 MODULE = Termios PACKAGE = POSIX::Termios PREFIX = cf
1873 new(packname = "POSIX::Termios", ...)
1874 const char * packname
1878 void *const p = allocate_struct(aTHX_ (ST(0) = sv_newmortal()),
1879 sizeof(struct termios), packname);
1880 /* The previous implementation stored a pointer to an uninitialised
1881 struct termios. Seems safer to initialise it, particularly as
1882 this implementation exposes the struct to prying from perl-space.
1884 memset(p, 0, 1 + sizeof(struct termios));
1887 not_here("termios");
1892 getattr(termios_ref, fd = 0)
1893 POSIX::Termios termios_ref
1896 RETVAL = tcgetattr(fd, termios_ref);
1900 # If we define TCSANOW here then both a found and not found constant sub
1901 # are created causing a Constant subroutine TCSANOW redefined warning
1903 # define DEF_SETATTR_ACTION 0
1905 # define DEF_SETATTR_ACTION TCSANOW
1908 setattr(termios_ref, fd = 0, optional_actions = DEF_SETATTR_ACTION)
1909 POSIX::Termios termios_ref
1911 int optional_actions
1913 /* The second argument to the call is mandatory, but we'd like to give
1914 it a useful default. 0 isn't valid on all operating systems - on
1915 Solaris (at least) TCSANOW, TCSADRAIN and TCSAFLUSH have the same
1916 values as the equivalent ioctls, TCSETS, TCSETSW and TCSETSF. */
1917 if (optional_actions < 0) {
1918 SETERRNO(EINVAL, LIB_INVARG);
1921 RETVAL = tcsetattr(fd, optional_actions, termios_ref);
1927 getispeed(termios_ref)
1928 POSIX::Termios termios_ref
1932 RETVAL = ix ? cfgetospeed(termios_ref) : cfgetispeed(termios_ref);
1937 getiflag(termios_ref)
1938 POSIX::Termios termios_ref
1944 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
1947 RETVAL = termios_ref->c_iflag;
1950 RETVAL = termios_ref->c_oflag;
1953 RETVAL = termios_ref->c_cflag;
1956 RETVAL = termios_ref->c_lflag;
1959 RETVAL = 0; /* silence compiler warning */
1962 not_here(GvNAME(CvGV(cv)));
1969 getcc(termios_ref, ccix)
1970 POSIX::Termios termios_ref
1973 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
1975 croak("Bad getcc subscript");
1976 RETVAL = termios_ref->c_cc[ccix];
1985 setispeed(termios_ref, speed)
1986 POSIX::Termios termios_ref
1992 ? cfsetospeed(termios_ref, speed) : cfsetispeed(termios_ref, speed);
1997 setiflag(termios_ref, flag)
1998 POSIX::Termios termios_ref
2005 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
2008 termios_ref->c_iflag = flag;
2011 termios_ref->c_oflag = flag;
2014 termios_ref->c_cflag = flag;
2017 termios_ref->c_lflag = flag;
2021 not_here(GvNAME(CvGV(cv)));
2025 setcc(termios_ref, ccix, cc)
2026 POSIX::Termios termios_ref
2030 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
2032 croak("Bad setcc subscript");
2033 termios_ref->c_cc[ccix] = cc;
2039 MODULE = POSIX PACKAGE = POSIX
2041 INCLUDE: const-xs.inc
2047 POSIX::WIFEXITED = 1
2048 POSIX::WIFSIGNALED = 2
2049 POSIX::WIFSTOPPED = 3
2053 #if !defined(WEXITSTATUS) || !defined(WIFEXITED) || !defined(WIFSIGNALED) \
2054 || !defined(WIFSTOPPED) || !defined(WSTOPSIG) || !defined(WTERMSIG)
2055 RETVAL = 0; /* Silence compilers that notice this, but don't realise
2056 that not_here() can't return. */
2061 RETVAL = WEXITSTATUS(WMUNGE(status));
2063 not_here("WEXITSTATUS");
2068 RETVAL = WIFEXITED(WMUNGE(status));
2070 not_here("WIFEXITED");
2075 RETVAL = WIFSIGNALED(WMUNGE(status));
2077 not_here("WIFSIGNALED");
2082 RETVAL = WIFSTOPPED(WMUNGE(status));
2084 not_here("WIFSTOPPED");
2089 RETVAL = WSTOPSIG(WMUNGE(status));
2091 not_here("WSTOPSIG");
2096 RETVAL = WTERMSIG(WMUNGE(status));
2098 not_here("WTERMSIG");
2102 croak("Illegal alias %d for POSIX::W*", (int)ix);
2108 open(filename, flags = O_RDONLY, mode = 0666)
2113 if (flags & (O_APPEND|O_CREAT|O_TRUNC|O_RDWR|O_WRONLY|O_EXCL))
2114 TAINT_PROPER("open");
2115 RETVAL = open(filename, flags, mode);
2123 #ifndef HAS_LOCALECONV
2124 localeconv(); /* A stub to call not_here(). */
2126 struct lconv *lcbuf;
2127 # if defined(USE_ITHREADS) \
2128 && defined(HAS_POSIX_2008_LOCALE) \
2129 && defined(HAS_LOCALECONV_L) /* Prefer this thread-safe version */
2130 bool do_free = FALSE;
2133 DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
2135 /* localeconv() deals with both LC_NUMERIC and LC_MONETARY, but
2136 * LC_MONETARY is already in the correct locale */
2137 # ifdef USE_LOCALE_MONETARY
2139 const bool is_monetary_utf8 = _is_cur_LC_category_utf8(LC_MONETARY);
2141 # ifdef USE_LOCALE_NUMERIC
2143 bool is_numeric_utf8;
2145 STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
2147 is_numeric_utf8 = _is_cur_LC_category_utf8(LC_NUMERIC);
2151 sv_2mortal((SV*)RETVAL);
2152 # if defined(USE_ITHREADS) \
2153 && defined(HAS_POSIX_2008_LOCALE) \
2154 && defined(HAS_LOCALECONV_L)
2156 cur = uselocale((locale_t) 0);
2157 if (cur == LC_GLOBAL_LOCALE) {
2158 cur = duplocale(LC_GLOBAL_LOCALE);
2162 lcbuf = localeconv_l(cur);
2164 LOCALE_LOCK; /* Prevent interference with other threads using
2167 lcbuf = localeconv();
2170 const struct lconv_offset *strings = lconv_strings;
2171 const struct lconv_offset *integers = lconv_integers;
2172 const char *ptr = (const char *) lcbuf;
2174 while (strings->name) {
2175 /* This string may be controlled by either LC_NUMERIC, or
2177 const bool is_utf8_locale =
2178 # if defined(USE_LOCALE_NUMERIC) && defined(USE_LOCALE_MONETARY)
2179 (isLC_NUMERIC_STRING(strings->name))
2182 # elif defined(USE_LOCALE_NUMERIC)
2184 # elif defined(USE_LOCALE_MONETARY)
2190 const char *value = *((const char **)(ptr + strings->offset));
2192 if (value && *value) {
2193 const STRLEN value_len = strlen(value);
2195 /* We mark it as UTF-8 if a utf8 locale and is valid and
2196 * variant under UTF-8 */
2197 const bool is_utf8 = is_utf8_locale
2198 && is_utf8_non_invariant_string(
2201 (void) hv_store(RETVAL,
2203 strlen(strings->name),
2204 newSVpvn_utf8(value, value_len, is_utf8),
2210 while (integers->name) {
2211 const char value = *((const char *)(ptr + integers->offset));
2213 if (value != CHAR_MAX)
2214 (void) hv_store(RETVAL, integers->name,
2215 strlen(integers->name), newSViv(value), 0);
2219 # if defined(USE_ITHREADS) \
2220 && defined(HAS_POSIX_2008_LOCALE) \
2221 && defined(HAS_LOCALECONV_L)
2228 RESTORE_LC_NUMERIC();
2229 #endif /* HAS_LOCALECONV */
2234 setlocale(category, locale = 0)
2240 retval = Perl_setlocale(category, locale);
2241 if (! retval) { /* Should never happen that a query would return an
2242 * error, but be sure */
2246 /* Make sure the returned copy gets cleaned up */
2296 RETVAL = Perl_acos(x); /* C89 math */
2300 RETVAL = c99_acosh(x);
2306 RETVAL = Perl_asin(x); /* C89 math */
2310 RETVAL = c99_asinh(x);
2316 RETVAL = Perl_atan(x); /* C89 math */
2320 RETVAL = c99_atanh(x);
2327 RETVAL = c99_cbrt(x);
2333 RETVAL = Perl_ceil(x); /* C89 math */
2336 RETVAL = Perl_cosh(x); /* C89 math */
2340 RETVAL = c99_erf(x);
2347 RETVAL = c99_erfc(x);
2354 RETVAL = c99_exp2(x);
2361 RETVAL = c99_expm1(x);
2367 RETVAL = Perl_floor(x); /* C89 math */
2371 RETVAL = bessel_j0(x);
2378 RETVAL = bessel_j1(x);
2384 /* XXX Note: the lgamma modifies a global variable (signgam),
2385 * which is evil. Some platforms have lgamma_r, which has
2386 * extra output parameter instead of the global variable. */
2388 RETVAL = c99_lgamma(x);
2394 RETVAL = log10(x); /* C89 math */
2398 RETVAL = c99_log1p(x);
2405 RETVAL = c99_log2(x);
2412 RETVAL = c99_logb(x);
2413 #elif defined(c99_log2) && FLT_RADIX == 2
2414 RETVAL = Perl_floor(c99_log2(PERL_ABS(x)));
2420 #ifdef c99_nearbyint
2421 RETVAL = c99_nearbyint(x);
2423 not_here("nearbyint");
2428 RETVAL = c99_rint(x);
2435 RETVAL = c99_round(x);
2441 RETVAL = Perl_sinh(x); /* C89 math */
2444 RETVAL = Perl_tan(x); /* C89 math */
2447 RETVAL = Perl_tanh(x); /* C89 math */
2451 RETVAL = c99_tgamma(x);
2458 RETVAL = c99_trunc(x);
2465 RETVAL = bessel_y0(x);
2473 RETVAL = bessel_y1(x);
2484 #ifdef HAS_FEGETROUND
2485 RETVAL = my_fegetround();
2488 not_here("fegetround");
2497 #ifdef HAS_FEGETROUND /* canary for fesetround */
2498 RETVAL = fesetround(x);
2499 #elif defined(HAS_FPGETROUND) /* canary for fpsetround */
2501 case FE_TONEAREST: RETVAL = fpsetround(FP_RN); break;
2502 case FE_TOWARDZERO: RETVAL = fpsetround(FP_RZ); break;
2503 case FE_DOWNWARD: RETVAL = fpsetround(FP_RM); break;
2504 case FE_UPWARD: RETVAL = fpsetround(FP_RP); break;
2505 default: RETVAL = -1; break;
2507 #elif defined(__osf__) /* Tru64 */
2509 case FE_TONEAREST: RETVAL = write_rnd(FP_RND_RN); break;
2510 case FE_TOWARDZERO: RETVAL = write_rnd(FP_RND_RZ); break;
2511 case FE_DOWNWARD: RETVAL = write_rnd(FP_RND_RM); break;
2512 case FE_UPWARD: RETVAL = write_rnd(FP_RND_RP); break;
2513 default: RETVAL = -1; break;
2518 not_here("fesetround");
2540 #ifdef c99_fpclassify
2541 RETVAL = c99_fpclassify(x);
2543 not_here("fpclassify");
2548 RETVAL = c99_ilogb(x);
2554 RETVAL = Perl_isfinite(x);
2557 RETVAL = Perl_isinf(x);
2560 RETVAL = Perl_isnan(x);
2564 RETVAL = c99_isnormal(x);
2566 not_here("isnormal");
2571 RETVAL = c99_lrint(x);
2578 RETVAL = c99_lround(x);
2586 RETVAL = Perl_signbit(x);
2589 #ifdef DOUBLE_IS_IEEE_FORMAT
2604 #ifdef DOUBLE_HAS_NAN
2605 RETVAL = S_getpayload(nv);
2607 PERL_UNUSED_VAR(nv);
2609 not_here("getpayload");
2615 setpayload(nv, payload)
2619 #ifdef DOUBLE_HAS_NAN
2620 S_setpayload(&nv, payload, FALSE);
2622 PERL_UNUSED_VAR(nv);
2623 PERL_UNUSED_VAR(payload);
2624 not_here("setpayload");
2630 setpayloadsig(nv, payload)
2634 #ifdef DOUBLE_HAS_NAN
2636 S_setpayload(&nv, payload, TRUE);
2638 PERL_UNUSED_VAR(nv);
2639 PERL_UNUSED_VAR(payload);
2640 not_here("setpayloadsig");
2649 #ifdef DOUBLE_HAS_NAN
2650 RETVAL = Perl_isnan(nv) && NV_NAN_IS_SIGNALING(&nv);
2652 PERL_UNUSED_VAR(nv);
2654 not_here("issignaling");
2689 RETVAL = c99_copysign(x, y);
2691 not_here("copysign");
2696 RETVAL = c99_fdim(x, y);
2703 RETVAL = c99_fmax(x, y);
2710 RETVAL = c99_fmin(x, y);
2716 RETVAL = Perl_fmod(x, y); /* C89 math */
2720 RETVAL = c99_hypot(x, y);
2726 #ifdef c99_isgreater
2727 RETVAL = c99_isgreater(x, y);
2729 not_here("isgreater");
2733 #ifdef c99_isgreaterequal
2734 RETVAL = c99_isgreaterequal(x, y);
2736 not_here("isgreaterequal");
2741 RETVAL = c99_isless(x, y);
2747 #ifdef c99_islessequal
2748 RETVAL = c99_islessequal(x, y);
2750 not_here("islessequal");
2754 #ifdef c99_islessgreater
2755 RETVAL = c99_islessgreater(x, y);
2757 not_here("islessgreater");
2761 #ifdef c99_isunordered
2762 RETVAL = c99_isunordered(x, y);
2764 not_here("isunordered");
2768 #ifdef c99_nextafter
2769 RETVAL = c99_nextafter(x, y);
2771 not_here("nextafter");
2775 #ifdef c99_nexttoward
2776 RETVAL = c99_nexttoward(x, y);
2778 not_here("nexttoward");
2783 #ifdef c99_remainder
2784 RETVAL = c99_remainder(x, y);
2786 not_here("remainder");
2798 /* (We already know stack is long enough.) */
2799 PUSHs(sv_2mortal(newSVnv(Perl_frexp(x,&expvar)))); /* C89 math */
2800 PUSHs(sv_2mortal(newSViv(expvar)));
2812 /* (We already know stack is long enough.) */
2813 PUSHs(sv_2mortal(newSVnv(Perl_modf(x,&intvar)))); /* C89 math */
2814 PUSHs(sv_2mortal(newSVnv(intvar)));
2823 PUSHs(sv_2mortal(newSVnv(c99_remquo(x,y,&intvar))));
2824 PUSHs(sv_2mortal(newSVnv(intvar)));
2837 RETVAL = c99_scalbn(x, y);
2854 RETVAL = c99_fma(x, y, z);
2869 /* If no payload given, just return the default NaN.
2870 * This makes a difference in platforms where the default
2871 * NaN is not all zeros. */
2875 S_setpayload(&RETVAL, payload, FALSE);
2877 #elif defined(c99_nan)
2879 STRLEN elen = my_snprintf(PL_efloatbuf, PL_efloatsize, "%g", payload);
2880 if ((IV)elen == -1) {
2888 RETVAL = c99_nan(PL_efloatbuf);
2912 RETVAL = bessel_jn(x, y);
2922 RETVAL = bessel_yn(x, y);
2934 sigaction(sig, optaction, oldaction = 0)
2937 POSIX::SigAction oldaction
2939 #if defined(WIN32) || defined(NETWARE) || (defined(__amigaos4__) && defined(__NEWLIB__))
2940 RETVAL = not_here("sigaction");
2942 # This code is really grody because we are trying to make the signal
2943 # interface look beautiful, which is hard.
2947 POSIX__SigAction action;
2948 GV *siggv = gv_fetchpvs("SIG", GV_ADD, SVt_PVHV);
2949 struct sigaction act;
2950 struct sigaction oact;
2954 POSIX__SigSet sigset;
2959 croak("Negative signals are not allowed");
2962 if (sig == 0 && SvPOK(ST(0))) {
2963 const char *s = SvPVX_const(ST(0));
2964 int i = whichsig(s);
2966 if (i < 0 && memBEGINs(s, SvCUR(ST(0)), "SIG"))
2967 i = whichsig(s + 3);
2969 if (ckWARN(WARN_SIGNAL))
2970 Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
2971 "No such signal: SIG%s", s);
2978 if (sig > NSIG) { /* NSIG - 1 is still okay. */
2979 Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
2980 "No such signal: %d", sig);
2984 sigsvp = hv_fetch(GvHVn(siggv),
2986 strlen(PL_sig_name[sig]),
2989 /* Check optaction and set action */
2990 if(SvTRUE(optaction)) {
2991 if(sv_isa(optaction, "POSIX::SigAction"))
2992 action = (HV*)SvRV(optaction);
2994 croak("action is not of type POSIX::SigAction");
3000 /* sigaction() is supposed to look atomic. In particular, any
3001 * signal handler invoked during a sigaction() call should
3002 * see either the old or the new disposition, and not something
3003 * in between. We use sigprocmask() to make it so.
3006 RETVAL=sigprocmask(SIG_BLOCK, &sset, &osset);
3010 /* Restore signal mask no matter how we exit this block. */
3011 osset_sv = newSVpvn((char *)(&osset), sizeof(sigset_t));
3012 SAVEFREESV( osset_sv );
3013 SAVEDESTRUCTOR_X(restore_sigmask, osset_sv);
3015 RETVAL=-1; /* In case both oldaction and action are 0. */
3017 /* Remember old disposition if desired. */
3019 svp = hv_fetchs(oldaction, "HANDLER", TRUE);
3021 croak("Can't supply an oldaction without a HANDLER");
3022 if(SvTRUE(*sigsvp)) { /* TBD: what if "0"? */
3023 sv_setsv(*svp, *sigsvp);
3026 sv_setpvs(*svp, "DEFAULT");
3028 RETVAL = sigaction(sig, (struct sigaction *)0, & oact);
3033 /* Get back the mask. */
3034 svp = hv_fetchs(oldaction, "MASK", TRUE);
3035 if (sv_isa(*svp, "POSIX::SigSet")) {
3036 sigset = (sigset_t *) SvPV_nolen(SvRV(*svp));
3039 sigset = (sigset_t *) allocate_struct(aTHX_ *svp,
3043 *sigset = oact.sa_mask;
3045 /* Get back the flags. */
3046 svp = hv_fetchs(oldaction, "FLAGS", TRUE);
3047 sv_setiv(*svp, oact.sa_flags);
3049 /* Get back whether the old handler used safe signals. */
3050 svp = hv_fetchs(oldaction, "SAFE", TRUE);
3052 /* compare incompatible pointers by casting to integer */
3053 PTR2nat(oact.sa_handler) == PTR2nat(PL_csighandlerp));
3057 /* Safe signals use "csighandler", which vectors through the
3058 PL_sighandlerp pointer when it's safe to do so.
3059 (BTW, "csighandler" is very different from "sighandler".) */
3060 svp = hv_fetchs(action, "SAFE", FALSE);
3064 (*svp && SvTRUE(*svp))
3065 ? PL_csighandlerp : PL_sighandlerp
3068 /* Vector new Perl handler through %SIG.
3069 (The core signal handlers read %SIG to dispatch.) */
3070 svp = hv_fetchs(action, "HANDLER", FALSE);
3072 croak("Can't supply an action without a HANDLER");
3073 sv_setsv(*sigsvp, *svp);
3075 /* This call actually calls sigaction() with almost the
3076 right settings, including appropriate interpretation
3077 of DEFAULT and IGNORE. However, why are we doing
3078 this when we're about to do it again just below? XXX */
3079 SvSETMAGIC(*sigsvp);
3081 /* And here again we duplicate -- DEFAULT/IGNORE checking. */
3083 const char *s=SvPVX_const(*svp);
3084 if(strEQ(s,"IGNORE")) {
3085 act.sa_handler = SIG_IGN;
3087 else if(strEQ(s,"DEFAULT")) {
3088 act.sa_handler = SIG_DFL;
3092 /* Set up any desired mask. */
3093 svp = hv_fetchs(action, "MASK", FALSE);
3094 if (svp && sv_isa(*svp, "POSIX::SigSet")) {
3095 sigset = (sigset_t *) SvPV_nolen(SvRV(*svp));
3096 act.sa_mask = *sigset;
3099 sigemptyset(& act.sa_mask);
3101 /* Set up any desired flags. */
3102 svp = hv_fetchs(action, "FLAGS", FALSE);
3103 act.sa_flags = svp ? SvIV(*svp) : 0;
3105 /* Don't worry about cleaning up *sigsvp if this fails,
3106 * because that means we tried to disposition a
3107 * nonblockable signal, in which case *sigsvp is
3108 * essentially meaningless anyway.
3110 RETVAL = sigaction(sig, & act, (struct sigaction *)0);
3125 POSIX::SigSet sigset
3130 RETVAL = not_here("sigpending");
3132 RETVAL = ix ? sigsuspend(sigset) : sigpending(sigset);
3140 sigprocmask(how, sigset, oldsigset = 0)
3142 POSIX::SigSet sigset = NO_INIT
3143 POSIX::SigSet oldsigset = NO_INIT
3145 if (! SvOK(ST(1))) {
3147 } else if (sv_isa(ST(1), "POSIX::SigSet")) {
3148 sigset = (sigset_t *) SvPV_nolen(SvRV(ST(1)));
3150 croak("sigset is not of type POSIX::SigSet");
3153 if (items < 3 || ! SvOK(ST(2))) {
3155 } else if (sv_isa(ST(2), "POSIX::SigSet")) {
3156 oldsigset = (sigset_t *) SvPV_nolen(SvRV(ST(2)));
3158 croak("oldsigset is not of type POSIX::SigSet");
3170 if (fd1 >= 0 && fd2 >= 0) {
3172 /* RT #98912 - More Microsoft muppetry - failing to
3173 actually implemented the well known documented POSIX
3174 behaviour for a POSIX API.
3175 http://msdn.microsoft.com/en-us/library/8syseb29.aspx */
3176 RETVAL = dup2(fd1, fd2) == -1 ? -1 : fd2;
3178 RETVAL = dup2(fd1, fd2);
3181 SETERRNO(EBADF,RMS_IFI);
3188 lseek(fd, offset, whence)
3194 Off_t pos = PerlLIO_lseek(fd, offset, whence);
3195 RETVAL = sizeof(Off_t) > sizeof(IV)
3196 ? newSVnv((NV)pos) : newSViv((IV)pos);
3206 if ((incr = nice(incr)) != -1 || errno == 0) {
3208 XPUSHs(newSVpvs_flags("0 but true", SVs_TEMP));
3210 XPUSHs(sv_2mortal(newSViv(incr)));
3217 if (pipe(fds) != -1) {
3219 PUSHs(sv_2mortal(newSViv(fds[0])));
3220 PUSHs(sv_2mortal(newSViv(fds[1])));
3224 read(fd, buffer, nbytes)
3226 SV *sv_buffer = SvROK(ST(1)) ? SvRV(ST(1)) : ST(1);
3230 char * buffer = sv_grow( sv_buffer, nbytes+1 );
3233 SvCUR_set(sv_buffer, RETVAL);
3234 SvPOK_only(sv_buffer);
3235 *SvEND(sv_buffer) = '\0';
3236 SvTAINTED_on(sv_buffer);
3252 tcsetpgrp(fd, pgrp_id)
3261 if (uname(&buf) >= 0) {
3263 PUSHs(newSVpvn_flags(buf.sysname, strlen(buf.sysname), SVs_TEMP));
3264 PUSHs(newSVpvn_flags(buf.nodename, strlen(buf.nodename), SVs_TEMP));
3265 PUSHs(newSVpvn_flags(buf.release, strlen(buf.release), SVs_TEMP));
3266 PUSHs(newSVpvn_flags(buf.version, strlen(buf.version), SVs_TEMP));
3267 PUSHs(newSVpvn_flags(buf.machine, strlen(buf.machine), SVs_TEMP));
3270 uname((char *) 0); /* A stub to call not_here(). */
3274 write(fd, buffer, nbytes)
3291 #if defined(USE_ITHREADS) && defined(HAS_MBRLEN)
3295 #if defined(USE_ITHREADS) && defined(HAS_MBRLEN)
3296 PERL_UNUSED_RESULT(mbrlen(NULL, 0, &ps)); /* Initialize state */
3297 RETVAL = mbrlen(s, n, &ps); /* Prefer reentrant version */
3299 RETVAL = mblen(s, n);
3305 mbstowcs(s, pwcs, n)
3316 #if defined(USE_ITHREADS) && defined(HAS_MBRTOWC)
3320 #if defined(USE_ITHREADS) && defined(HAS_MBRTOWC)
3321 memset(&ps, 0, sizeof(ps));;
3322 PERL_UNUSED_RESULT(mbrtowc(pwc, NULL, 0, &ps));/* Reset any shift state */
3324 RETVAL = mbrtowc(pwc, s, n, &ps); /* Prefer reentrant version */
3326 RETVAL = mbtowc(pwc, s, n);
3332 wcstombs(s, pwcs, n)
3354 DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
3355 STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
3356 num = strtod(str, &unparsed);
3357 RESTORE_LC_NUMERIC();
3358 PUSHs(sv_2mortal(newSVnv(num)));
3359 if (GIMME_V == G_ARRAY) {
3362 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3364 PUSHs(&PL_sv_undef);
3376 DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
3377 STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
3378 num = strtold(str, &unparsed);
3379 RESTORE_LC_NUMERIC();
3380 PUSHs(sv_2mortal(newSVnv(num)));
3381 if (GIMME_V == G_ARRAY) {
3384 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3386 PUSHs(&PL_sv_undef);
3392 strtol(str, base = 0)
3399 if (base == 0 || (base >= 2 && base <= 36)) {
3400 num = strtol(str, &unparsed, base);
3401 #if IVSIZE < LONGSIZE
3402 if (num < IV_MIN || num > IV_MAX)
3403 PUSHs(sv_2mortal(newSVnv((double)num)));
3406 PUSHs(sv_2mortal(newSViv((IV)num)));
3407 if (GIMME_V == G_ARRAY) {
3410 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3412 PUSHs(&PL_sv_undef);
3415 SETERRNO(EINVAL, LIB_INVARG);
3416 PUSHs(&PL_sv_undef);
3417 if (GIMME_V == G_ARRAY) {
3419 PUSHs(&PL_sv_undef);
3424 strtoul(str, base = 0)
3429 char *unparsed = NULL;
3431 PERL_UNUSED_VAR(str);
3432 PERL_UNUSED_VAR(base);
3433 if (base == 0 || (base >= 2 && base <= 36)) {
3434 num = strtoul(str, &unparsed, base);
3435 #if IVSIZE <= LONGSIZE
3437 PUSHs(sv_2mortal(newSVnv((double)num)));
3440 PUSHs(sv_2mortal(newSViv((IV)num)));
3441 if (GIMME_V == G_ARRAY) {
3444 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3446 PUSHs(&PL_sv_undef);
3449 SETERRNO(EINVAL, LIB_INVARG);
3450 PUSHs(&PL_sv_undef);
3451 if (GIMME_V == G_ARRAY) {
3453 PUSHs(&PL_sv_undef);
3465 char *p = SvPV(src,srclen);
3467 buflen = srclen * 4 + 1;
3468 ST(0) = sv_2mortal(newSV(buflen));
3469 dstlen = strxfrm(SvPVX(ST(0)), p, (size_t)buflen);
3470 if (dstlen >= buflen) {
3472 SvGROW(ST(0), dstlen);
3473 strxfrm(SvPVX(ST(0)), p, (size_t)dstlen);
3476 SvCUR_set(ST(0), dstlen);
3481 mkfifo(filename, mode)
3488 RETVAL = access(filename, mode);
3490 TAINT_PROPER("mkfifo");
3491 RETVAL = mkfifo(filename, mode);
3504 RETVAL = ix == 1 ? close(fd)
3505 : (ix < 1 ? tcdrain(fd) : dup(fd));
3507 SETERRNO(EBADF,RMS_IFI);
3523 RETVAL = ix == 1 ? tcflush(fd, action)
3524 : (ix < 1 ? tcflow(fd, action) : tcsendbreak(fd, action));
3526 SETERRNO(EINVAL,LIB_INVARG);
3533 asctime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = -1)
3549 init_tm(&mytm); /* XXX workaround - see init_tm() in core util.c */
3552 mytm.tm_hour = hour;
3553 mytm.tm_mday = mday;
3555 mytm.tm_year = year;
3556 mytm.tm_wday = wday;
3557 mytm.tm_yday = yday;
3558 mytm.tm_isdst = isdst;
3560 const time_t result = mktime(&mytm);
3561 if (result == (time_t)-1)
3563 else if (result == 0)
3564 sv_setpvs(TARG, "0 but true");
3566 sv_setiv(TARG, (IV)result);
3568 sv_setpv(TARG, asctime(&mytm));
3586 realtime = times( &tms );
3588 PUSHs( sv_2mortal( newSViv( (IV) realtime ) ) );
3589 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_utime ) ) );
3590 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_stime ) ) );
3591 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cutime ) ) );
3592 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cstime ) ) );
3595 difftime(time1, time2)
3599 #XXX: if $xsubpp::WantOptimize is always the default
3600 # sv_setpv(TARG, ...) could be used rather than
3601 # ST(0) = sv_2mortal(newSVpv(...))
3603 strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1)
3619 /* allowing user-supplied (rather than literal) formats
3620 * is normally frowned upon as a potential security risk;
3621 * but this is part of the API so we have to allow it */
3622 GCC_DIAG_IGNORE_STMT(-Wformat-nonliteral);
3623 buf = my_strftime(SvPV_nolen(fmt), sec, min, hour, mday, mon, year, wday, yday, isdst);
3624 GCC_DIAG_RESTORE_STMT;
3625 sv = sv_newmortal();
3627 STRLEN len = strlen(buf);
3628 sv_usepvn_flags(sv, buf, len, SV_HAS_TRAILING_NUL);
3630 || ( is_utf8_non_invariant_string((U8*) buf, len)
3631 #ifdef USE_LOCALE_TIME
3632 && _is_cur_LC_category_utf8(LC_TIME)
3633 #else /* If can't check directly, at least can see if script is consistent,
3634 under UTF-8, which gives us an extra measure of confidence. */
3636 && isSCRIPT_RUN((const U8 *) buf, buf + len,
3637 TRUE, /* Means assume UTF-8 */
3644 else { /* We can't distinguish between errors and just an empty
3645 * return; in all cases just return an empty string */
3646 SvUPGRADE(sv, SVt_PV);
3647 SvPV_set(sv, (char *) "");
3650 SvLEN_set(sv, 0); /* Won't attempt to free the string when sv
3665 PUSHs(newSVpvn_flags(tzname[0], strlen(tzname[0]), SVs_TEMP));
3666 PUSHs(newSVpvn_flags(tzname[1], strlen(tzname[1]), SVs_TEMP));
3672 #ifdef HAS_CTERMID_R
3673 s = (char *) safemalloc((size_t) L_ctermid);
3675 RETVAL = ctermid(s);
3679 #ifdef HAS_CTERMID_R
3688 RETVAL = cuserid(s);
3692 not_here("cuserid");
3703 pathconf(filename, name)
3714 unsigned int seconds
3716 RETVAL = PerlProc_sleep(seconds);
3742 XSprePUSH; PUSHTARG;
3746 lchown(uid, gid, path)
3752 /* yes, the order of arguments is different,
3753 * but consistent with CORE::chown() */
3754 RETVAL = lchown(path, uid, gid);
3756 PERL_UNUSED_VAR(uid);
3757 PERL_UNUSED_VAR(gid);
3758 PERL_UNUSED_VAR(path);
3759 RETVAL = not_here("lchown");