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
20 #if defined(PERL_IMPLICIT_SYS)
24 # define open PerlLIO_open3
27 #ifdef I_DIRENT /* XXX maybe better to just rely on perl.h? */
32 #include <sys/errno2.h>
60 #if defined(USE_QUADMATH) && defined(I_QUADMATH)
77 # define M_LOG2E M_LOG2Eq
78 # define M_LOG10E M_LOG10Eq
80 # define M_LN10 M_LN10q
82 # define M_PI_2 M_PI_2q
83 # define M_PI_4 M_PI_4q
84 # define M_1_PI M_1_PIq
85 # define M_2_PI M_2_PIq
86 # define M_2_SQRTPI M_2_SQRTPIq
87 # define M_SQRT2 M_SQRT2q
88 # define M_SQRT1_2 M_SQRT1_2q
92 # ifdef USE_LONG_DOUBLE
106 # define FLOAT_C(c) CAT2(c,L)
108 # define FLOAT_C(c) (c)
112 # define M_E FLOAT_C(2.71828182845904523536028747135266250)
115 # define M_LOG2E FLOAT_C(1.44269504088896340735992468100189214)
118 # define M_LOG10E FLOAT_C(0.434294481903251827651128918916605082)
121 # define M_LN2 FLOAT_C(0.693147180559945309417232121458176568)
124 # define M_LN10 FLOAT_C(2.30258509299404568401799145468436421)
127 # define M_PI FLOAT_C(3.14159265358979323846264338327950288)
130 # define M_PI_2 FLOAT_C(1.57079632679489661923132169163975144)
133 # define M_PI_4 FLOAT_C(0.785398163397448309615660845819875721)
136 # define M_1_PI FLOAT_C(0.318309886183790671537767526745028724)
139 # define M_2_PI FLOAT_C(0.636619772367581343075535053490057448)
142 # define M_2_SQRTPI FLOAT_C(1.12837916709551257389615890312154517)
145 # define M_SQRT2 FLOAT_C(1.41421356237309504880168872420969808)
148 # define M_SQRT1_2 FLOAT_C(0.707106781186547524400844362104849039)
153 #if !defined(INFINITY) && defined(NV_INF)
154 # define INFINITY NV_INF
157 #if !defined(NAN) && defined(NV_NAN)
161 #if !defined(Inf) && defined(NV_INF)
165 #if !defined(NaN) && defined(NV_NAN)
169 /* We will have an emulation. */
171 # define FP_INFINITE 0
174 # define FP_SUBNORMAL 3
178 /* We will have an emulation. */
180 # define FE_TOWARDZERO 0
181 # define FE_TONEAREST 1
183 # define FE_DOWNWARD 3
188 acos asin atan atan2 ceil cos cosh exp fabs floor fmod frexp ldexp
189 log log10 modf pow sin sinh sqrt tan tanh
191 * Implemented in core:
193 atan2 cos exp log pow sin sqrt
197 acosh asinh atanh cbrt copysign erf erfc exp2 expm1 fdim fma fmax
198 fmin fpclassify hypot ilogb isfinite isgreater isgreaterequal isinf
199 isless islessequal islessgreater isnan isnormal isunordered lgamma
200 log1p log2 logb lrint lround nan nearbyint nextafter nexttoward remainder
201 remquo rint round scalbn signbit tgamma trunc
204 http://pubs.opengroup.org/onlinepubs/009695399/basedefs/math.h.html
206 * Berkeley/SVID extensions:
210 * Configure already (5.21.5) scans for:
212 copysign*l* fpclassify isfinite isinf isnan isnan*l* ilogb*l* signbit scalbn*l*
214 * For floating-point round mode (which matters for e.g. lrint and rint)
216 fegetround fesetround
220 /* XXX Constant FP_FAST_FMA (if true, FMA is faster) */
222 /* XXX Add ldiv(), lldiv()? It's C99, but from stdlib.h, not math.h */
224 /* XXX Beware old gamma() -- one cannot know whether that is the
225 * gamma or the log of gamma, that's why the new tgamma and lgamma.
226 * Though also remember lgamma_r. */
228 /* Certain AIX releases have the C99 math, but not in long double.
229 * The <math.h> has them, e.g. __expl128, but no library has them!
231 * Also see the comments in hints/aix.sh about long doubles. */
233 #if defined(USE_QUADMATH) && defined(I_QUADMATH)
234 # define c99_acosh acoshq
235 # define c99_asinh asinhq
236 # define c99_atanh atanhq
237 # define c99_cbrt cbrtq
238 # define c99_copysign copysignq
239 # define c99_erf erfq
240 # define c99_erfc erfcq
242 # define c99_expm1 expm1q
243 # define c99_fdim fdimq
244 # define c99_fma fmaq
245 # define c99_fmax fmaxq
246 # define c99_fmin fminq
247 # define c99_hypot hypotq
248 # define c99_ilogb ilogbq
249 # define c99_lgamma lgammaq
250 # define c99_log1p log1pq
251 # define c99_log2 log2q
253 # if defined(USE_64_BIT_INT) && QUADKIND == QUAD_IS_LONG_LONG
254 # define c99_lrint llrintq
255 # define c99_lround llroundq
257 # define c99_lrint lrintq
258 # define c99_lround lroundq
260 # define c99_nan nanq
261 # define c99_nearbyint nearbyintq
262 # define c99_nextafter nextafterq
264 # define c99_remainder remainderq
265 # define c99_remquo remquoq
266 # define c99_rint rintq
267 # define c99_round roundq
268 # define c99_scalbn scalbnq
269 # define c99_signbit signbitq
270 # define c99_tgamma tgammaq
271 # define c99_trunc truncq
272 # define bessel_j0 j0q
273 # define bessel_j1 j1q
274 # define bessel_jn jnq
275 # define bessel_y0 y0q
276 # define bessel_y1 y1q
277 # define bessel_yn ynq
278 #elif defined(USE_LONG_DOUBLE) && \
279 (defined(HAS_FREXPL) || defined(HAS_ILOGBL)) && defined(HAS_SQRTL)
280 /* Use some of the Configure scans for long double math functions
281 * as the canary for all the C99 *l variants being defined. */
282 # define c99_acosh acoshl
283 # define c99_asinh asinhl
284 # define c99_atanh atanhl
285 # define c99_cbrt cbrtl
286 # define c99_copysign copysignl
287 # define c99_erf erfl
288 # define c99_erfc erfcl
289 # define c99_exp2 exp2l
290 # define c99_expm1 expm1l
291 # define c99_fdim fdiml
292 # define c99_fma fmal
293 # define c99_fmax fmaxl
294 # define c99_fmin fminl
295 # define c99_hypot hypotl
296 # define c99_ilogb ilogbl
297 # define c99_lgamma lgammal
298 # define c99_log1p log1pl
299 # define c99_log2 log2l
300 # define c99_logb logbl
301 # if defined(USE_64_BIT_INT) && QUADKIND == QUAD_IS_LONG_LONG && defined(HAS_LLRINTL)
302 # define c99_lrint llrintl
303 # elif defined(HAS_LRINTL)
304 # define c99_lrint lrintl
306 # if defined(USE_64_BIT_INT) && QUADKIND == QUAD_IS_LONG_LONG && defined(HAS_LLROUNDL)
307 # define c99_lround llroundl
308 # elif defined(HAS_LROUNDL)
309 # define c99_lround lroundl
311 # define c99_nan nanl
312 # define c99_nearbyint nearbyintl
313 # define c99_nextafter nextafterl
314 # define c99_nexttoward nexttowardl
315 # define c99_remainder remainderl
316 # define c99_remquo remquol
317 # define c99_rint rintl
318 # define c99_round roundl
319 # define c99_scalbn scalbnl
320 # ifdef HAS_SIGNBIT /* possibly bad assumption */
321 # define c99_signbit signbitl
323 # define c99_tgamma tgammal
324 # define c99_trunc truncl
326 # define c99_acosh acosh
327 # define c99_asinh asinh
328 # define c99_atanh atanh
329 # define c99_cbrt cbrt
330 # define c99_copysign copysign
332 # define c99_erfc erfc
333 # define c99_exp2 exp2
334 # define c99_expm1 expm1
335 # define c99_fdim fdim
337 # define c99_fmax fmax
338 # define c99_fmin fmin
339 # define c99_hypot hypot
340 # define c99_ilogb ilogb
341 # define c99_lgamma lgamma
342 # define c99_log1p log1p
343 # define c99_log2 log2
344 # define c99_logb logb
345 # if defined(USE_64_BIT_INT) && QUADKIND == QUAD_IS_LONG_LONG && defined(HAS_LLRINT)
346 # define c99_lrint llrint
348 # define c99_lrint lrint
350 # if defined(USE_64_BIT_INT) && QUADKIND == QUAD_IS_LONG_LONG && defined(HAS_LLROUND)
351 # define c99_lround llround
353 # define c99_lround lround
356 # define c99_nearbyint nearbyint
357 # define c99_nextafter nextafter
358 # define c99_nexttoward nexttoward
359 # define c99_remainder remainder
360 # define c99_remquo remquo
361 # define c99_rint rint
362 # define c99_round round
363 # define c99_scalbn scalbn
364 /* We already define Perl_signbit in perl.h. */
366 # define c99_signbit signbit
368 # define c99_tgamma tgamma
369 # define c99_trunc trunc
372 /* AIX xlc (__IBMC__) really doesn't have the following long double
373 * math interfaces (no __acoshl128 aka acoshl, etc.), see
374 * hints/aix.sh. These are in the -lc128 but fail to be found
375 * during dynamic linking/loading.
377 * XXX1 Better Configure scans
378 * XXX2 Is this xlc version dependent? */
379 #if defined(USE_LONG_DOUBLE) && defined(__IBMC__)
399 # undef c99_nearbyint
400 # undef c99_nextafter
401 # undef c99_nexttoward
402 # undef c99_remainder
413 # define isunordered(x, y) (Perl_isnan(x) || Perl_isnan(y))
414 # elif defined(HAS_UNORDERED)
415 # define isunordered(x, y) unordered(x, y)
419 /* XXX these isgreater/isnormal/isunordered macros definitions should
420 * be moved further in the file to be part of the emulations, so that
421 * platforms can e.g. #undef c99_isunordered and have it work like
422 * it does for the other interfaces. */
424 #if !defined(isgreater) && defined(isunordered)
425 # define isgreater(x, y) (!isunordered((x), (y)) && (x) > (y))
426 # define isgreaterequal(x, y) (!isunordered((x), (y)) && (x) >= (y))
427 # define isless(x, y) (!isunordered((x), (y)) && (x) < (y))
428 # define islessequal(x, y) (!isunordered((x), (y)) && (x) <= (y))
429 # define islessgreater(x, y) (!isunordered((x), (y)) && \
430 ((x) > (y) || (y) > (x)))
433 /* Check both the Configure symbol and the macro-ness (like C99 promises). */
434 #if defined(HAS_FPCLASSIFY) && defined(fpclassify)
435 # define c99_fpclassify fpclassify
437 /* Like isnormal(), the isfinite(), isinf(), and isnan() are also C99
438 and also (sizeof-arg-aware) macros, but they are already well taken
439 care of by Configure et al, and defined in perl.h as
440 Perl_isfinite(), Perl_isinf(), and Perl_isnan(). */
442 # define c99_isnormal isnormal
444 #ifdef isgreater /* canary for all the C99 is*<cmp>* macros. */
445 # define c99_isgreater isgreater
446 # define c99_isgreaterequal isgreaterequal
447 # define c99_isless isless
448 # define c99_islessequal islessequal
449 # define c99_islessgreater islessgreater
450 # define c99_isunordered isunordered
453 /* The Great Wall of Undef where according to the definedness of HAS_FOO symbols
454 * the corresponding c99_foo wrappers are undefined. This list doesn't include
455 * the isfoo() interfaces because they are either type-aware macros, or dealt
456 * separately, already in perl.h */
497 #ifndef HAS_FPCLASSIFY
498 # undef c99_fpclassify
527 #ifndef HAS_NEARBYINT
528 # undef c99_nearbyint
530 #ifndef HAS_NEXTAFTER
531 # undef c99_nextafter
533 #ifndef HAS_NEXTTOWARD
534 # undef c99_nexttoward
536 #ifndef HAS_REMAINDER
537 # undef c99_remainder
563 /* Some APIs exist under Win32 with "underbar" names. */
566 # undef c99_nextafter
567 # define c99_hypot _hypot
568 # define c99_logb _logb
569 # define c99_nextafter _nextafter
571 # define bessel_j0 _j0
572 # define bessel_j1 _j1
573 # define bessel_jn _jn
574 # define bessel_y0 _y0
575 # define bessel_y1 _y1
576 # define bessel_yn _yn
580 /* The Bessel functions: BSD, SVID, XPG4, and POSIX. But not C99. */
581 #if defined(HAS_J0) && !defined(bessel_j0)
582 # if defined(USE_LONG_DOUBLE) && defined(HAS_J0L)
583 # define bessel_j0 j0l
584 # define bessel_j1 j1l
585 # define bessel_jn jnl
586 # define bessel_y0 y0l
587 # define bessel_y1 y1l
588 # define bessel_yn ynl
590 # define bessel_j0 j0
591 # define bessel_j1 j1
592 # define bessel_jn jn
593 # define bessel_y0 y0
594 # define bessel_y1 y1
595 # define bessel_yn yn
599 /* Emulations for missing math APIs.
601 * Keep in mind that the point of many of these functions is that
602 * they, if available, are supposed to give more precise/more
603 * numerically stable results.
605 * See e.g. http://www.johndcook.com/math_h.html
609 static NV my_acosh(NV x)
611 return Perl_log(x + Perl_sqrt(x * x - 1));
613 # define c99_acosh my_acosh
617 static NV my_asinh(NV x)
619 return Perl_log(x + Perl_sqrt(x * x + 1));
621 # define c99_asinh my_asinh
625 static NV my_atanh(NV x)
627 return (Perl_log(1 + x) - Perl_log(1 - x)) / 2;
629 # define c99_atanh my_atanh
633 static NV my_cbrt(NV x)
635 static const NV one_third = (NV)1.0/3;
636 return x >= 0.0 ? Perl_pow(x, one_third) : -Perl_pow(-x, one_third);
638 # define c99_cbrt my_cbrt
642 static NV my_copysign(NV x, NV y)
644 return y >= 0 ? (x < 0 ? -x : x) : (x < 0 ? x : -x);
646 # define c99_copysign my_copysign
649 /* XXX cosh (though c89) */
652 static NV my_erf(NV x)
654 /* http://www.johndcook.com/cpp_erf.html -- public domain */
656 NV a2 = -0.284496736;
658 NV a4 = -1.453152027;
662 int sign = x < 0 ? -1 : 1; /* Save the sign. */
665 /* Abramowitz and Stegun formula 7.1.26 */
666 t = 1.0 / (1.0 + p * x);
667 y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1) * t * Perl_exp(-x*x);
671 # define c99_erf my_erf
675 static NV my_erfc(NV x) {
676 /* This is not necessarily numerically stable, but better than nothing. */
677 return 1.0 - c99_erf(x);
679 # define c99_erfc my_erfc
683 static NV my_exp2(NV x)
685 return Perl_pow((NV)2.0, x);
687 # define c99_exp2 my_exp2
691 static NV my_expm1(NV x)
693 if (PERL_ABS(x) < 1e-5)
694 /* http://www.johndcook.com/cpp_expm1.html -- public domain.
695 * Taylor series, the first four terms (the last term quartic). */
696 /* Probably not enough for long doubles. */
697 return x * (1.0 + x * (1/2.0 + x * (1/6.0 + x/24.0)));
699 return Perl_exp(x) - 1;
701 # define c99_expm1 my_expm1
705 static NV my_fdim(NV x, NV y)
707 return (Perl_isnan(x) || Perl_isnan(y)) ? NV_NAN : (x > y ? x - y : 0);
709 # define c99_fdim my_fdim
713 static NV my_fma(NV x, NV y, NV z)
717 # define c99_fma my_fma
721 static NV my_fmax(NV x, NV y)
724 return Perl_isnan(y) ? NV_NAN : y;
725 } else if (Perl_isnan(y)) {
728 return x > y ? x : y;
730 # define c99_fmax my_fmax
734 static NV my_fmin(NV x, NV y)
737 return Perl_isnan(y) ? NV_NAN : y;
738 } else if (Perl_isnan(y)) {
741 return x < y ? x : y;
743 # define c99_fmin my_fmin
746 #ifndef c99_fpclassify
748 static IV my_fpclassify(NV x)
750 #ifdef Perl_fp_class_inf
751 if (Perl_fp_class_inf(x)) return FP_INFINITE;
752 if (Perl_fp_class_nan(x)) return FP_NAN;
753 if (Perl_fp_class_norm(x)) return FP_NORMAL;
754 if (Perl_fp_class_denorm(x)) return FP_SUBNORMAL;
755 if (Perl_fp_class_zero(x)) return FP_ZERO;
756 # define c99_fpclassify my_fpclassify
764 static NV my_hypot(NV x, NV y)
766 /* http://en.wikipedia.org/wiki/Hypot */
768 x = PERL_ABS(x); /* Take absolute values. */
774 if (x < y) { /* Swap so that y is less. */
780 return x * Perl_sqrt(1.0 + t * t);
782 # define c99_hypot my_hypot
786 static IV my_ilogb(NV x)
788 return (IV)(Perl_log(x) * M_LOG2E);
790 # define c99_ilogb my_ilogb
793 /* tgamma and lgamma emulations based on
794 * http://www.johndcook.com/cpp_gamma.html,
795 * code placed in public domain.
797 * Note that these implementations (neither the johndcook originals
798 * nor these) do NOT set the global signgam variable. This is not
799 * necessarily a bad thing. */
801 /* Note that the tgamma() and lgamma() implementations
802 * here depend on each other. */
804 #if !defined(HAS_TGAMMA) || !defined(c99_tgamma)
805 static NV my_tgamma(NV x);
806 # define c99_tgamma my_tgamma
807 # define USE_MY_TGAMMA
809 #if !defined(HAS_LGAMMA) || !defined(c99_lgamma)
810 static NV my_lgamma(NV x);
811 # define c99_lgamma my_lgamma
812 # define USE_MY_LGAMMA
816 static NV my_tgamma(NV x)
818 const NV gamma = 0.577215664901532860606512090; /* Euler's gamma constant. */
819 if (Perl_isnan(x) || x < 0.0)
821 if (x == 0.0 || x == NV_INF)
822 return x == -0.0 ? -NV_INF : NV_INF;
824 /* The function domain is split into three intervals:
825 * (0, 0.001), [0.001, 12), and (12, infinity) */
827 /* First interval: (0, 0.001)
828 * For small values, 1/tgamma(x) has power series x + gamma x^2,
829 * so in this range, 1/tgamma(x) = x + gamma x^2 with error on the order of x^3.
830 * The relative error over this interval is less than 6e-7. */
832 return 1.0 / (x * (1.0 + gamma * x));
834 /* Second interval: [0.001, 12) */
836 double y = x; /* Working copy. */
838 /* Numerator coefficients for approximation over the interval (1,2) */
839 static const NV p[] = {
840 -1.71618513886549492533811E+0,
841 2.47656508055759199108314E+1,
842 -3.79804256470945635097577E+2,
843 6.29331155312818442661052E+2,
844 8.66966202790413211295064E+2,
845 -3.14512729688483675254357E+4,
846 -3.61444134186911729807069E+4,
847 6.64561438202405440627855E+4
849 /* Denominator coefficients for approximation over the interval (1, 2) */
850 static const NV q[] = {
851 -3.08402300119738975254353E+1,
852 3.15350626979604161529144E+2,
853 -1.01515636749021914166146E+3,
854 -3.10777167157231109440444E+3,
855 2.25381184209801510330112E+4,
856 4.75584627752788110767815E+3,
857 -1.34659959864969306392456E+5,
858 -1.15132259675553483497211E+5
869 n = (int)Perl_floor(y) - 1;
873 for (i = 0; i < 8; i++) {
874 num = (num + p[i]) * z;
875 den = den * z + q[i];
877 result = num / den + 1.0;
880 /* Use the identity tgamma(z) = tgamma(z+1)/z
881 * The variable "result" now holds tgamma of the original y + 1
882 * Thus we use y - 1 to get back the original y. */
886 /* Use the identity tgamma(z+n) = z*(z+1)* ... *(z+n-1)*tgamma(z) */
887 for (i = 0; i < n; i++)
894 /* Third interval: [12, +Inf) */
895 #if LDBL_MANT_DIG == 113 /* IEEE quad prec */
905 return Perl_exp(c99_lgamma(x));
910 static NV my_lgamma(NV x)
914 if (x <= 0 || x == NV_INF)
916 if (x == 1.0 || x == 2.0)
919 return Perl_log(PERL_ABS(c99_tgamma(x)));
920 /* Abramowitz and Stegun 6.1.41
921 * Asymptotic series should be good to at least 11 or 12 figures
922 * For error analysis, see Whittiker and Watson
923 * A Course in Modern Analysis (1927), page 252 */
925 static const NV c[8] = {
935 NV z = 1.0 / (x * x);
937 static const NV half_log_of_two_pi =
938 0.91893853320467274178032973640562;
941 for (i = 6; i >= 0; i--) {
946 return (x - 0.5) * Perl_log(x) - x + half_log_of_two_pi + series;
952 static NV my_log1p(NV x)
954 /* http://www.johndcook.com/cpp_log_one_plus_x.html -- public domain.
955 * Taylor series, the first four terms (the last term quartic). */
960 if (PERL_ABS(x) > 1e-4)
961 return Perl_log(1.0 + x);
963 /* Probably not enough for long doubles. */
964 return x * (1.0 + x * (-1/2.0 + x * (1/3.0 - x/4.0)));
966 # define c99_log1p my_log1p
970 static NV my_log2(NV x)
972 return Perl_log(x) * M_LOG2E;
974 # define c99_log2 my_log2
981 static int my_fegetround()
983 #ifdef HAS_FEGETROUND
985 #elif defined(HAS_FPGETROUND)
986 switch (fpgetround()) {
987 case FP_RN: return FE_TONEAREST;
988 case FP_RZ: return FE_TOWARDZERO;
989 case FP_RM: return FE_DOWNWARD;
990 case FP_RP: return FE_UPWARD;
993 #elif defined(FLT_ROUNDS)
994 switch (FLT_ROUNDS) {
995 case 0: return FE_TOWARDZERO;
996 case 1: return FE_TONEAREST;
997 case 2: return FE_UPWARD;
998 case 3: return FE_DOWNWARD;
1001 #elif defined(__osf__) /* Tru64 */
1002 switch (read_rnd()) {
1003 case FP_RND_RN: return FE_TONEAREST;
1004 case FP_RND_RZ: return FE_TOWARDZERO;
1005 case FP_RND_RM: return FE_DOWNWARD;
1006 case FP_RND_RP: return FE_UPWARD;
1014 /* Toward closest integer. */
1015 #define MY_ROUND_NEAREST(x) ((NV)((IV)((x) >= 0.0 ? (x) + 0.5 : (x) - 0.5)))
1018 #define MY_ROUND_TRUNC(x) ((NV)((IV)(x)))
1020 /* Toward minus infinity. */
1021 #define MY_ROUND_DOWN(x) ((NV)((IV)((x) >= 0.0 ? (x) : (x) - 0.5)))
1023 /* Toward plus infinity. */
1024 #define MY_ROUND_UP(x) ((NV)((IV)((x) >= 0.0 ? (x) + 0.5 : (x))))
1026 #if (!defined(c99_nearbyint) || !defined(c99_lrint)) && defined(FE_TONEAREST)
1027 static NV my_rint(NV x)
1030 switch (my_fegetround()) {
1031 case FE_TONEAREST: return MY_ROUND_NEAREST(x);
1032 case FE_TOWARDZERO: return MY_ROUND_TRUNC(x);
1033 case FE_DOWNWARD: return MY_ROUND_DOWN(x);
1034 case FE_UPWARD: return MY_ROUND_UP(x);
1035 default: return NV_NAN;
1037 #elif defined(HAS_FPGETROUND)
1038 switch (fpgetround()) {
1039 case FP_RN: return MY_ROUND_NEAREST(x);
1040 case FP_RZ: return MY_ROUND_TRUNC(x);
1041 case FP_RM: return MY_ROUND_DOWN(x);
1042 case FE_RP: return MY_ROUND_UP(x);
1043 default: return NV_NAN;
1051 /* XXX nearbyint() and rint() are not really identical -- but the difference
1052 * is messy: nearbyint is defined NOT to raise FE_INEXACT floating point
1053 * exceptions, while rint() is defined to MAYBE raise them. At the moment
1054 * Perl is blissfully unaware of such fine detail of floating point. */
1055 #ifndef c99_nearbyint
1056 # ifdef FE_TONEAREST
1057 # define c99_nearbyrint my_rint
1062 # ifdef FE_TONEAREST
1063 static IV my_lrint(NV x)
1065 return (IV)my_rint(x);
1067 # define c99_lrint my_lrint
1072 static IV my_lround(NV x)
1074 return (IV)MY_ROUND_NEAREST(x);
1076 # define c99_lround my_lround
1084 # ifdef FE_TONEAREST
1085 # define c99_rint my_rint
1090 static NV my_round(NV x)
1092 return MY_ROUND_NEAREST(x);
1094 # define c99_round my_round
1098 # if defined(Perl_ldexp) && FLT_RADIX == 2
1099 static NV my_scalbn(NV x, int y)
1101 return Perl_ldexp(x, y);
1103 # define c99_scalbn my_scalbn
1107 /* XXX sinh (though c89) */
1109 /* tgamma -- see lgamma */
1111 /* XXX tanh (though c89) */
1114 static NV my_trunc(NV x)
1116 return MY_ROUND_TRUNC(x);
1118 # define c99_trunc my_trunc
1121 #undef NV_PAYLOAD_DEBUG
1123 /* NOTE: the NaN payload API implementation is hand-rolled, since the
1124 * APIs are only proposed ones as of June 2015, so very few, if any,
1125 * platforms have implementations yet, so HAS_SETPAYLOAD and such are
1126 * unlikely to be helpful.
1128 * XXX - if the core numification wants to actually generate
1129 * the nan payload in "nan(123)", and maybe "nans(456)", for
1130 * signaling payload", this needs to be moved to e.g. numeric.c
1131 * (look for grok_infnan)
1133 * Conversely, if the core stringification wants the nan payload
1134 * and/or the nan quiet/signaling distinction, S_getpayload()
1135 * from this file needs to be moved, to e.g. sv.c (look for S_infnan_2pv),
1136 * and the (trivial) functionality of issignaling() copied
1137 * (for generating "NaNS", or maybe even "NaNQ") -- or maybe there
1138 * are too many formatting parameters for simple stringification?
1141 /* While it might make sense for the payload to be UV or IV,
1142 * to avoid conversion loss, the proposed ISO interfaces use
1143 * a floating point input, which is then truncated to integer,
1144 * and only the integer part being used. This is workable,
1145 * except for: (1) the conversion loss (2) suboptimal for
1146 * 32-bit integer platforms. A workaround API for (2) and
1147 * in general for bit-honesty would be an array of integers
1148 * as the payload... but the proposed C API does nothing of
1150 #if NVSIZE == UVSIZE
1151 # define NV_PAYLOAD_TYPE UV
1153 # define NV_PAYLOAD_TYPE NV
1156 #ifdef LONGDOUBLE_DOUBLEDOUBLE
1157 # define NV_PAYLOAD_SIZEOF_ASSERT(a) assert(sizeof(a) == NVSIZE / 2)
1159 # define NV_PAYLOAD_SIZEOF_ASSERT(a) assert(sizeof(a) == NVSIZE)
1162 static void S_setpayload(NV* nvp, NV_PAYLOAD_TYPE payload, bool signaling)
1165 static const U8 m[] = { NV_NAN_PAYLOAD_MASK };
1166 static const U8 p[] = { NV_NAN_PAYLOAD_PERM };
1167 UV a[(NVSIZE + UVSIZE - 1) / UVSIZE] = { 0 };
1169 NV_PAYLOAD_SIZEOF_ASSERT(m);
1170 NV_PAYLOAD_SIZEOF_ASSERT(p);
1172 /* Divide the input into the array in "base unsigned integer" in
1173 * little-endian order. Note that the integer might be smaller than
1174 * an NV (if UV is U32, for example). */
1175 #if NVSIZE == UVSIZE
1176 a[0] = payload; /* The trivial case. */
1179 NV t1 = c99_trunc(payload); /* towards zero (drop fractional) */
1180 #ifdef NV_PAYLOAD_DEBUG
1181 Perl_warn(aTHX_ "t1 = %"NVgf" (payload %"NVgf")\n", t1, payload);
1184 a[0] = (UV)t1; /* Fast path, also avoids rounding errors (right?) */
1186 /* UVSIZE < NVSIZE or payload > UV_MAX.
1188 * This may happen for example if:
1189 * (1) UVSIZE == 32 and common 64-bit double NV
1190 * (32-bit system not using -Duse64bitint)
1191 * (2) UVSIZE == 64 and the x86-style 80-bit long double NV
1192 * (note that here the room for payload is actually the 64 bits)
1193 * (3) UVSIZE == 64 and the 128-bit IEEE 764 quadruple NV
1194 * (112 bits in mantissa, 111 bits room for payload)
1196 * NOTE: this is very sensitive to correctly functioning
1197 * fmod()/fmodl(), and correct casting of big-unsigned-integer to NV.
1198 * If these don't work right, especially the low order bits
1199 * are in danger. For example Solaris and AIX seem to have issues
1200 * here, especially if using 32-bit UVs. */
1202 for (i = 0, t2 = t1; i < (int)C_ARRAY_LENGTH(a); i++) {
1203 a[i] = (UV)Perl_fmod(t2, (NV)UV_MAX);
1204 t2 = Perl_floor(t2 / (NV)UV_MAX);
1209 #ifdef NV_PAYLOAD_DEBUG
1210 for (i = 0; i < (int)C_ARRAY_LENGTH(a); i++) {
1211 Perl_warn(aTHX_ "a[%d] = 0x%"UVxf"\n", i, a[i]);
1214 for (i = 0; i < (int)sizeof(p); i++) {
1215 if (m[i] && p[i] < sizeof(p)) {
1216 U8 s = (p[i] % UVSIZE) << 3;
1217 UV u = a[p[i] / UVSIZE] & ((UV)0xFF << s);
1218 U8 b = (U8)((u >> s) & m[i]);
1219 ((U8 *)(nvp))[i] &= ~m[i]; /* For NaNs with non-zero payload bits. */
1220 ((U8 *)(nvp))[i] |= b;
1221 #ifdef NV_PAYLOAD_DEBUG
1222 Perl_warn(aTHX_ "set p[%2d] = %02x (i = %d, m = %02x, s = %2d, b = %02x, u = %08"UVxf")\n", i, ((U8 *)(nvp))[i], i, m[i], s, b, u);
1224 a[p[i] / UVSIZE] &= ~u;
1228 NV_NAN_SET_SIGNALING(nvp);
1230 #ifdef USE_LONG_DOUBLE
1231 # if LONG_DOUBLEKIND == 3 || LONG_DOUBLEKIND == 4
1232 memset((char *)nvp + 10, '\0', LONG_DOUBLESIZE - 10); /* x86 long double */
1235 for (i = 0; i < (int)C_ARRAY_LENGTH(a); i++) {
1237 Perl_warn(aTHX_ "payload lost bits (%"UVxf")", a[i]);
1241 #ifdef NV_PAYLOAD_DEBUG
1242 for (i = 0; i < NVSIZE; i++) {
1243 PerlIO_printf(Perl_debug_log, "%02x ", ((U8 *)(nvp))[i]);
1245 PerlIO_printf(Perl_debug_log, "\n");
1249 static NV_PAYLOAD_TYPE S_getpayload(NV nv)
1252 static const U8 m[] = { NV_NAN_PAYLOAD_MASK };
1253 static const U8 p[] = { NV_NAN_PAYLOAD_PERM };
1254 UV a[(NVSIZE + UVSIZE - 1) / UVSIZE] = { 0 };
1257 NV_PAYLOAD_SIZEOF_ASSERT(m);
1258 NV_PAYLOAD_SIZEOF_ASSERT(p);
1260 for (i = 0; i < (int)sizeof(p); i++) {
1261 if (m[i] && p[i] < NVSIZE) {
1262 U8 s = (p[i] % UVSIZE) << 3;
1263 a[p[i] / UVSIZE] |= (UV)(((U8 *)(&nv))[i] & m[i]) << s;
1266 for (i = (int)C_ARRAY_LENGTH(a) - 1; i >= 0; i--) {
1267 #ifdef NV_PAYLOAD_DEBUG
1268 Perl_warn(aTHX_ "a[%d] = %"UVxf"\n", i, a[i]);
1273 #ifdef NV_PAYLOAD_DEBUG
1274 for (i = 0; i < NVSIZE; i++) {
1275 PerlIO_printf(Perl_debug_log, "%02x ", ((U8 *)(&nv))[i]);
1277 PerlIO_printf(Perl_debug_log, "\n");
1282 /* XXX This comment is just to make I_TERMIO and I_SGTTY visible to
1283 metaconfig for future extension writers. We don't use them in POSIX.
1284 (This is really sneaky :-) --AD
1286 #if defined(I_TERMIOS)
1287 #include <termios.h>
1295 #include <sys/stat.h>
1296 #include <sys/types.h>
1304 # if !defined(WIN32) && !defined(__CYGWIN__) && !defined(NETWARE) && !defined(__UWIN__)
1305 extern char *tzname[];
1308 #if !defined(WIN32) && !defined(__UWIN__) || (defined(__MINGW32__) && !defined(tzname))
1309 char *tzname[] = { "" , "" };
1313 #if defined(__VMS) && !defined(__POSIX_SOURCE)
1315 # include <utsname.h>
1318 # define mkfifo(a,b) (not_here("mkfifo"),-1)
1320 /* The POSIX notion of ttyname() is better served by getname() under VMS */
1321 static char ttnambuf[64];
1322 # define ttyname(fd) (isatty(fd) > 0 ? getname(fd,ttnambuf,0) : NULL)
1325 #if defined (__CYGWIN__)
1326 # define tzname _tzname
1328 #if defined (WIN32) || defined (NETWARE)
1330 # define mkfifo(a,b) not_here("mkfifo")
1331 # define ttyname(a) (char*)not_here("ttyname")
1332 # define sigset_t long
1335 # define mode_t short
1338 # define mode_t short
1340 # define tzset() not_here("tzset")
1342 # ifndef _POSIX_OPEN_MAX
1343 # define _POSIX_OPEN_MAX FOPEN_MAX /* XXX bogus ? */
1346 # define sigaction(a,b,c) not_here("sigaction")
1347 # define sigpending(a) not_here("sigpending")
1348 # define sigprocmask(a,b,c) not_here("sigprocmask")
1349 # define sigsuspend(a) not_here("sigsuspend")
1350 # define sigemptyset(a) not_here("sigemptyset")
1351 # define sigaddset(a,b) not_here("sigaddset")
1352 # define sigdelset(a,b) not_here("sigdelset")
1353 # define sigfillset(a) not_here("sigfillset")
1354 # define sigismember(a,b) not_here("sigismember")
1358 # define setuid(a) not_here("setuid")
1359 # define setgid(a) not_here("setgid")
1360 #endif /* NETWARE */
1361 #ifndef USE_LONG_DOUBLE
1362 # define strtold(s1,s2) not_here("strtold")
1363 #endif /* USE_LONG_DOUBLE */
1368 # define mkfifo(a,b) not_here("mkfifo")
1369 # else /* !( defined OS2 ) */
1371 # define mkfifo(path, mode) (mknod((path), (mode) | S_IFIFO, 0))
1374 # endif /* !HAS_MKFIFO */
1379 # include <sys/times.h>
1381 # include <sys/utsname.h>
1383 # include <sys/wait.h>
1387 #endif /* WIN32 || NETWARE */
1391 typedef long SysRetLong;
1392 typedef sigset_t* POSIX__SigSet;
1393 typedef HV* POSIX__SigAction;
1395 typedef struct termios* POSIX__Termios;
1396 #else /* Define termios types to int, and call not_here for the functions.*/
1397 #define POSIX__Termios int
1399 #define tcflag_t int
1401 #define cfgetispeed(x) not_here("cfgetispeed")
1402 #define cfgetospeed(x) not_here("cfgetospeed")
1403 #define tcdrain(x) not_here("tcdrain")
1404 #define tcflush(x,y) not_here("tcflush")
1405 #define tcsendbreak(x,y) not_here("tcsendbreak")
1406 #define cfsetispeed(x,y) not_here("cfsetispeed")
1407 #define cfsetospeed(x,y) not_here("cfsetospeed")
1408 #define ctermid(x) (char *) not_here("ctermid")
1409 #define tcflow(x,y) not_here("tcflow")
1410 #define tcgetattr(x,y) not_here("tcgetattr")
1411 #define tcsetattr(x,y,z) not_here("tcsetattr")
1414 /* Possibly needed prototypes */
1417 double strtod (const char *, char **);
1418 long strtol (const char *, char **, int);
1419 unsigned long strtoul (const char *, char **, int);
1421 long double strtold (const char *, char **);
1426 #ifndef HAS_DIFFTIME
1428 #define difftime(a,b) not_here("difftime")
1431 #ifndef HAS_FPATHCONF
1432 #define fpathconf(f,n) (SysRetLong) not_here("fpathconf")
1435 #define mktime(a) not_here("mktime")
1438 #define nice(a) not_here("nice")
1440 #ifndef HAS_PATHCONF
1441 #define pathconf(f,n) (SysRetLong) not_here("pathconf")
1444 #define sysconf(n) (SysRetLong) not_here("sysconf")
1446 #ifndef HAS_READLINK
1447 #define readlink(a,b,c) not_here("readlink")
1450 #define setpgid(a,b) not_here("setpgid")
1453 #define setsid() not_here("setsid")
1456 #define strcoll(s1,s2) not_here("strcoll")
1459 #define strtod(s1,s2) not_here("strtod")
1462 #define strtold(s1,s2) not_here("strtold")
1465 #define strtol(s1,s2,b) not_here("strtol")
1468 #define strtoul(s1,s2,b) not_here("strtoul")
1471 #define strxfrm(s1,s2,n) not_here("strxfrm")
1473 #ifndef HAS_TCGETPGRP
1474 #define tcgetpgrp(a) not_here("tcgetpgrp")
1476 #ifndef HAS_TCSETPGRP
1477 #define tcsetpgrp(a,b) not_here("tcsetpgrp")
1481 #define times(a) not_here("times")
1482 #endif /* NETWARE */
1485 #define uname(a) not_here("uname")
1488 #define waitpid(a,b,c) not_here("waitpid")
1493 #define mblen(a,b) not_here("mblen")
1496 #ifndef HAS_MBSTOWCS
1497 #define mbstowcs(s, pwcs, n) not_here("mbstowcs")
1500 #define mbtowc(pwc, s, n) not_here("mbtowc")
1502 #ifndef HAS_WCSTOMBS
1503 #define wcstombs(s, pwcs, n) not_here("wcstombs")
1506 #define wctomb(s, wchar) not_here("wcstombs")
1508 #if !defined(HAS_MBLEN) && !defined(HAS_MBSTOWCS) && !defined(HAS_MBTOWC) && !defined(HAS_WCSTOMBS) && !defined(HAS_WCTOMB)
1509 /* If we don't have these functions, then we wouldn't have gotten a typedef
1510 for wchar_t, the wide character type. Defining wchar_t allows the
1511 functions referencing it to compile. Its actual type is then meaningless,
1512 since without the above functions, all sections using it end up calling
1513 not_here() and croak. --Kaveh Ghazi (ghazi@noc.rutgers.edu) 9/18/94. */
1515 #define wchar_t char
1519 #ifndef HAS_LOCALECONV
1520 # define localeconv() not_here("localeconv")
1522 struct lconv_offset {
1527 const struct lconv_offset lconv_strings[] = {
1528 #ifdef USE_LOCALE_NUMERIC
1529 {"decimal_point", STRUCT_OFFSET(struct lconv, decimal_point)},
1530 {"thousands_sep", STRUCT_OFFSET(struct lconv, thousands_sep)},
1531 # ifndef NO_LOCALECONV_GROUPING
1532 {"grouping", STRUCT_OFFSET(struct lconv, grouping)},
1535 #ifdef USE_LOCALE_MONETARY
1536 {"int_curr_symbol", STRUCT_OFFSET(struct lconv, int_curr_symbol)},
1537 {"currency_symbol", STRUCT_OFFSET(struct lconv, currency_symbol)},
1538 {"mon_decimal_point", STRUCT_OFFSET(struct lconv, mon_decimal_point)},
1539 # ifndef NO_LOCALECONV_MON_THOUSANDS_SEP
1540 {"mon_thousands_sep", STRUCT_OFFSET(struct lconv, mon_thousands_sep)},
1542 # ifndef NO_LOCALECONV_MON_GROUPING
1543 {"mon_grouping", STRUCT_OFFSET(struct lconv, mon_grouping)},
1545 {"positive_sign", STRUCT_OFFSET(struct lconv, positive_sign)},
1546 {"negative_sign", STRUCT_OFFSET(struct lconv, negative_sign)},
1551 #ifdef USE_LOCALE_NUMERIC
1553 /* The Linux man pages say these are the field names for the structure
1554 * components that are LC_NUMERIC; the rest being LC_MONETARY */
1555 # define isLC_NUMERIC_STRING(name) (strcmp(name, "decimal_point") \
1556 || strcmp(name, "thousands_sep") \
1558 /* There should be no harm done \
1559 * checking for this, even if \
1560 * NO_LOCALECONV_GROUPING */ \
1561 || strcmp(name, "grouping"))
1563 # define isLC_NUMERIC_STRING(name) (0)
1566 const struct lconv_offset lconv_integers[] = {
1567 #ifdef USE_LOCALE_MONETARY
1568 {"int_frac_digits", STRUCT_OFFSET(struct lconv, int_frac_digits)},
1569 {"frac_digits", STRUCT_OFFSET(struct lconv, frac_digits)},
1570 {"p_cs_precedes", STRUCT_OFFSET(struct lconv, p_cs_precedes)},
1571 {"p_sep_by_space", STRUCT_OFFSET(struct lconv, p_sep_by_space)},
1572 {"n_cs_precedes", STRUCT_OFFSET(struct lconv, n_cs_precedes)},
1573 {"n_sep_by_space", STRUCT_OFFSET(struct lconv, n_sep_by_space)},
1574 {"p_sign_posn", STRUCT_OFFSET(struct lconv, p_sign_posn)},
1575 {"n_sign_posn", STRUCT_OFFSET(struct lconv, n_sign_posn)},
1576 #ifdef HAS_LC_MONETARY_2008
1577 {"int_p_cs_precedes", STRUCT_OFFSET(struct lconv, int_p_cs_precedes)},
1578 {"int_p_sep_by_space", STRUCT_OFFSET(struct lconv, int_p_sep_by_space)},
1579 {"int_n_cs_precedes", STRUCT_OFFSET(struct lconv, int_n_cs_precedes)},
1580 {"int_n_sep_by_space", STRUCT_OFFSET(struct lconv, int_n_sep_by_space)},
1581 {"int_p_sign_posn", STRUCT_OFFSET(struct lconv, int_p_sign_posn)},
1582 {"int_n_sign_posn", STRUCT_OFFSET(struct lconv, int_n_sign_posn)},
1588 #endif /* HAS_LOCALECONV */
1590 #ifdef HAS_LONG_DOUBLE
1591 # if LONG_DOUBLESIZE > NVSIZE
1592 # undef HAS_LONG_DOUBLE /* XXX until we figure out how to use them */
1596 #ifndef HAS_LONG_DOUBLE
1608 /* Background: in most systems the low byte of the wait status
1609 * is the signal (the lowest 7 bits) and the coredump flag is
1610 * the eight bit, and the second lowest byte is the exit status.
1611 * BeOS bucks the trend and has the bytes in different order.
1612 * See beos/beos.c for how the reality is bent even in BeOS
1613 * to follow the traditional. However, to make the POSIX
1614 * wait W*() macros to work in BeOS, we need to unbend the
1615 * reality back in place. --jhi */
1616 /* In actual fact the code below is to blame here. Perl has an internal
1617 * representation of the exit status ($?), which it re-composes from the
1618 * OS's representation using the W*() POSIX macros. The code below
1619 * incorrectly uses the W*() macros on the internal representation,
1620 * which fails for OSs that have a different representation (namely BeOS
1621 * and Haiku). WMUNGE() is a hack that converts the internal
1622 * representation into the OS specific one, so that the W*() macros work
1623 * as expected. The better solution would be not to use the W*() macros
1624 * in the first place, though. -- Ingo Weinhold
1626 #if defined(__HAIKU__)
1627 # define WMUNGE(x) (((x) & 0xFF00) >> 8 | ((x) & 0x00FF) << 8)
1629 # define WMUNGE(x) (x)
1633 not_here(const char *s)
1635 croak("POSIX::%s not implemented on this architecture", s);
1639 #include "const-c.inc"
1642 restore_sigmask(pTHX_ SV *osset_sv)
1644 /* Fortunately, restoring the signal mask can't fail, because
1645 * there's nothing we can do about it if it does -- we're not
1646 * supposed to return -1 from sigaction unless the disposition
1649 sigset_t *ossetp = (sigset_t *) SvPV_nolen( osset_sv );
1650 (void)sigprocmask(SIG_SETMASK, ossetp, (sigset_t *)0);
1654 allocate_struct(pTHX_ SV *rv, const STRLEN size, const char *packname) {
1655 SV *const t = newSVrv(rv, packname);
1656 void *const p = sv_grow(t, size + 1);
1666 * (1) The CRT maintains its own copy of the environment, separate from
1667 * the Win32API copy.
1669 * (2) CRT getenv() retrieves from this copy. CRT putenv() updates this
1670 * copy, and then calls SetEnvironmentVariableA() to update the Win32API
1673 * (3) win32_getenv() and win32_putenv() call GetEnvironmentVariableA() and
1674 * SetEnvironmentVariableA() directly, bypassing the CRT copy of the
1677 * (4) The CRT strftime() "%Z" implementation calls __tzset(). That
1678 * calls CRT tzset(), but only the first time it is called, and in turn
1679 * that uses CRT getenv("TZ") to retrieve the timezone info from the CRT
1680 * local copy of the environment and hence gets the original setting as
1681 * perl never updates the CRT copy when assigning to $ENV{TZ}.
1683 * Therefore, we need to retrieve the value of $ENV{TZ} and call CRT
1684 * putenv() to update the CRT copy of the environment (if it is different)
1685 * whenever we're about to call tzset().
1687 * In addition to all that, when perl is built with PERL_IMPLICIT_SYS
1690 * (a) Each interpreter has its own copy of the environment inside the
1691 * perlhost structure. That allows applications that host multiple
1692 * independent Perl interpreters to isolate environment changes from
1693 * each other. (This is similar to how the perlhost mechanism keeps a
1694 * separate working directory for each Perl interpreter, so that calling
1695 * chdir() will not affect other interpreters.)
1697 * (b) Only the first Perl interpreter instantiated within a process will
1698 * "write through" environment changes to the process environment.
1700 * (c) Even the primary Perl interpreter won't update the CRT copy of the
1701 * the environment, only the Win32API copy (it calls win32_putenv()).
1703 * As with CPerlHost::Getenv() and CPerlHost::Putenv() themselves, it makes
1704 * sense to only update the process environment when inside the main
1705 * interpreter, but we don't have access to CPerlHost's m_bTopLevel member
1706 * from here so we'll just have to check PL_curinterp instead.
1708 * Therefore, we can simply #undef getenv() and putenv() so that those names
1709 * always refer to the CRT functions, and explicitly call win32_getenv() to
1710 * access perl's %ENV.
1712 * We also #undef malloc() and free() to be sure we are using the CRT
1713 * functions otherwise under PERL_IMPLICIT_SYS they are redefined to calls
1714 * into VMem::Malloc() and VMem::Free() and all allocations will be freed
1715 * when the Perl interpreter is being destroyed so we'd end up with a pointer
1716 * into deallocated memory in environ[] if a program embedding a Perl
1717 * interpreter continues to operate even after the main Perl interpreter has
1720 * Note that we don't free() the malloc()ed memory unless and until we call
1721 * malloc() again ourselves because the CRT putenv() function simply puts its
1722 * pointer argument into the environ[] array (it doesn't make a copy of it)
1723 * so this memory must otherwise be leaked.
1732 fix_win32_tzenv(void)
1734 static char* oldenv = NULL;
1736 const char* perl_tz_env = win32_getenv("TZ");
1737 const char* crt_tz_env = getenv("TZ");
1738 if (perl_tz_env == NULL)
1740 if (crt_tz_env == NULL)
1742 if (strcmp(perl_tz_env, crt_tz_env) != 0) {
1743 newenv = (char*)malloc((strlen(perl_tz_env) + 4) * sizeof(char));
1744 if (newenv != NULL) {
1745 sprintf(newenv, "TZ=%s", perl_tz_env);
1757 * my_tzset - wrapper to tzset() with a fix to make it work (better) on Win32.
1758 * This code is duplicated in the Time-Piece module, so any changes made here
1759 * should be made there too.
1765 #if defined(USE_ITHREADS) && defined(PERL_IMPLICIT_SYS)
1766 if (PL_curinterp == aTHX)
1773 typedef int (*isfunc_t)(int);
1774 typedef void (*any_dptr_t)(void *);
1776 /* This needs to be ALIASed in a custom way, hence can't easily be defined as
1778 static XSPROTO(is_common); /* prototype to pass -Wmissing-prototypes */
1779 static XSPROTO(is_common)
1784 croak_xs_usage(cv, "charstring");
1789 /*int RETVAL = 0; YYY means uncomment this to return false on an
1790 * empty string input */
1792 unsigned char *s = (unsigned char *) SvPV(ST(0), len);
1793 unsigned char *e = s + len;
1794 isfunc_t isfunc = (isfunc_t) XSANY.any_dptr;
1796 if (ckWARN_d(WARN_DEPRECATED)) {
1798 /* Warn exactly once for each lexical place this function is
1799 * called. See thread at
1800 * http://markmail.org/thread/jhqcag5njmx7jpyu */
1802 HV *warned = get_hv("POSIX::_warned", GV_ADD | GV_ADDMULTI);
1803 if (! hv_exists(warned, (const char *)&PL_op, sizeof(PL_op))) {
1804 Perl_warner(aTHX_ packWARN(WARN_DEPRECATED),
1805 "Calling POSIX::%"HEKf"() is deprecated",
1806 HEKfARG(GvNAME_HEK(CvGV(cv))));
1807 (void)hv_store(warned, (const char *)&PL_op, sizeof(PL_op), &PL_sv_yes, 0);
1811 /*if (e > s) { YYY */
1812 for (RETVAL = 1; RETVAL && s < e; s++)
1822 MODULE = POSIX PACKAGE = POSIX
1829 /* silence compiler warning about not_here() defined but not used */
1830 if (0) not_here("");
1832 /* Ensure we get the function, not a macro implementation. Like the C89
1833 standard says we can... */
1835 cv = newXS_deffile("POSIX::isalnum", is_common);
1836 XSANY.any_dptr = (any_dptr_t) &isalnum;
1838 cv = newXS_deffile("POSIX::isalpha", is_common);
1839 XSANY.any_dptr = (any_dptr_t) &isalpha;
1841 cv = newXS_deffile("POSIX::iscntrl", is_common);
1842 XSANY.any_dptr = (any_dptr_t) &iscntrl;
1844 cv = newXS_deffile("POSIX::isdigit", is_common);
1845 XSANY.any_dptr = (any_dptr_t) &isdigit;
1847 cv = newXS_deffile("POSIX::isgraph", is_common);
1848 XSANY.any_dptr = (any_dptr_t) &isgraph;
1850 cv = newXS_deffile("POSIX::islower", is_common);
1851 XSANY.any_dptr = (any_dptr_t) &islower;
1853 cv = newXS_deffile("POSIX::isprint", is_common);
1854 XSANY.any_dptr = (any_dptr_t) &isprint;
1856 cv = newXS_deffile("POSIX::ispunct", is_common);
1857 XSANY.any_dptr = (any_dptr_t) &ispunct;
1859 cv = newXS_deffile("POSIX::isspace", is_common);
1860 XSANY.any_dptr = (any_dptr_t) &isspace;
1862 cv = newXS_deffile("POSIX::isupper", is_common);
1863 XSANY.any_dptr = (any_dptr_t) &isupper;
1865 cv = newXS_deffile("POSIX::isxdigit", is_common);
1866 XSANY.any_dptr = (any_dptr_t) &isxdigit;
1869 MODULE = SigSet PACKAGE = POSIX::SigSet PREFIX = sig
1872 new(packname = "POSIX::SigSet", ...)
1873 const char * packname
1878 = (sigset_t *) allocate_struct(aTHX_ (ST(0) = sv_newmortal()),
1882 for (i = 1; i < items; i++)
1883 sigaddset(s, SvIV(ST(i)));
1889 POSIX::SigSet sigset
1894 RETVAL = ix ? sigdelset(sigset, sig) : sigaddset(sigset, sig);
1900 POSIX::SigSet sigset
1904 RETVAL = ix ? sigfillset(sigset) : sigemptyset(sigset);
1909 sigismember(sigset, sig)
1910 POSIX::SigSet sigset
1913 MODULE = Termios PACKAGE = POSIX::Termios PREFIX = cf
1916 new(packname = "POSIX::Termios", ...)
1917 const char * packname
1921 void *const p = allocate_struct(aTHX_ (ST(0) = sv_newmortal()),
1922 sizeof(struct termios), packname);
1923 /* The previous implementation stored a pointer to an uninitialised
1924 struct termios. Seems safer to initialise it, particularly as
1925 this implementation exposes the struct to prying from perl-space.
1927 memset(p, 0, 1 + sizeof(struct termios));
1930 not_here("termios");
1935 getattr(termios_ref, fd = 0)
1936 POSIX::Termios termios_ref
1939 RETVAL = tcgetattr(fd, termios_ref);
1943 # If we define TCSANOW here then both a found and not found constant sub
1944 # are created causing a Constant subroutine TCSANOW redefined warning
1946 # define DEF_SETATTR_ACTION 0
1948 # define DEF_SETATTR_ACTION TCSANOW
1951 setattr(termios_ref, fd = 0, optional_actions = DEF_SETATTR_ACTION)
1952 POSIX::Termios termios_ref
1954 int optional_actions
1956 /* The second argument to the call is mandatory, but we'd like to give
1957 it a useful default. 0 isn't valid on all operating systems - on
1958 Solaris (at least) TCSANOW, TCSADRAIN and TCSAFLUSH have the same
1959 values as the equivalent ioctls, TCSETS, TCSETSW and TCSETSF. */
1960 RETVAL = tcsetattr(fd, optional_actions, termios_ref);
1965 getispeed(termios_ref)
1966 POSIX::Termios termios_ref
1970 RETVAL = ix ? cfgetospeed(termios_ref) : cfgetispeed(termios_ref);
1975 getiflag(termios_ref)
1976 POSIX::Termios termios_ref
1982 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
1985 RETVAL = termios_ref->c_iflag;
1988 RETVAL = termios_ref->c_oflag;
1991 RETVAL = termios_ref->c_cflag;
1994 RETVAL = termios_ref->c_lflag;
1997 RETVAL = 0; /* silence compiler warning */
2000 not_here(GvNAME(CvGV(cv)));
2007 getcc(termios_ref, ccix)
2008 POSIX::Termios termios_ref
2011 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
2013 croak("Bad getcc subscript");
2014 RETVAL = termios_ref->c_cc[ccix];
2023 setispeed(termios_ref, speed)
2024 POSIX::Termios termios_ref
2030 ? cfsetospeed(termios_ref, speed) : cfsetispeed(termios_ref, speed);
2035 setiflag(termios_ref, flag)
2036 POSIX::Termios termios_ref
2043 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
2046 termios_ref->c_iflag = flag;
2049 termios_ref->c_oflag = flag;
2052 termios_ref->c_cflag = flag;
2055 termios_ref->c_lflag = flag;
2059 not_here(GvNAME(CvGV(cv)));
2063 setcc(termios_ref, ccix, cc)
2064 POSIX::Termios termios_ref
2068 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
2070 croak("Bad setcc subscript");
2071 termios_ref->c_cc[ccix] = cc;
2077 MODULE = POSIX PACKAGE = POSIX
2079 INCLUDE: const-xs.inc
2085 POSIX::WIFEXITED = 1
2086 POSIX::WIFSIGNALED = 2
2087 POSIX::WIFSTOPPED = 3
2091 #if !defined(WEXITSTATUS) || !defined(WIFEXITED) || !defined(WIFSIGNALED) \
2092 || !defined(WIFSTOPPED) || !defined(WSTOPSIG) || !defined(WTERMSIG)
2093 RETVAL = 0; /* Silence compilers that notice this, but don't realise
2094 that not_here() can't return. */
2099 RETVAL = WEXITSTATUS(WMUNGE(status));
2101 not_here("WEXITSTATUS");
2106 RETVAL = WIFEXITED(WMUNGE(status));
2108 not_here("WIFEXITED");
2113 RETVAL = WIFSIGNALED(WMUNGE(status));
2115 not_here("WIFSIGNALED");
2120 RETVAL = WIFSTOPPED(WMUNGE(status));
2122 not_here("WIFSTOPPED");
2127 RETVAL = WSTOPSIG(WMUNGE(status));
2129 not_here("WSTOPSIG");
2134 RETVAL = WTERMSIG(WMUNGE(status));
2136 not_here("WTERMSIG");
2140 croak("Illegal alias %d for POSIX::W*", (int)ix);
2146 open(filename, flags = O_RDONLY, mode = 0666)
2151 if (flags & (O_APPEND|O_CREAT|O_TRUNC|O_RDWR|O_WRONLY|O_EXCL))
2152 TAINT_PROPER("open");
2153 RETVAL = open(filename, flags, mode);
2161 #ifndef HAS_LOCALECONV
2162 localeconv(); /* A stub to call not_here(). */
2164 struct lconv *lcbuf;
2166 /* localeconv() deals with both LC_NUMERIC and LC_MONETARY, but
2167 * LC_MONETARY is already in the correct locale */
2168 DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
2169 STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
2172 sv_2mortal((SV*)RETVAL);
2173 if ((lcbuf = localeconv())) {
2174 const struct lconv_offset *strings = lconv_strings;
2175 const struct lconv_offset *integers = lconv_integers;
2176 const char *ptr = (const char *) lcbuf;
2178 while (strings->name) {
2179 /* This string may be controlled by either LC_NUMERIC, or
2182 #if defined(USE_LOCALE_NUMERIC) && defined(USE_LOCALE_MONETARY)
2183 = _is_cur_LC_category_utf8((isLC_NUMERIC_STRING(strings->name))
2186 #elif defined(USE_LOCALE_NUMERIC)
2187 = _is_cur_LC_category_utf8(LC_NUMERIC);
2188 #elif defined(USE_LOCALE_MONETARY)
2189 = _is_cur_LC_category_utf8(LC_MONETARY);
2194 const char *value = *((const char **)(ptr + strings->offset));
2196 if (value && *value) {
2197 (void) hv_store(RETVAL,
2199 strlen(strings->name),
2200 newSVpvn_utf8(value,
2203 /* We mark it as UTF-8 if a utf8 locale
2204 * and is valid and variant under UTF-8 */
2206 && ! is_invariant_string((U8 *) value, 0)
2207 && is_utf8_string((U8 *) value, 0)),
2213 while (integers->name) {
2214 const char value = *((const char *)(ptr + integers->offset));
2216 if (value != CHAR_MAX)
2217 (void) hv_store(RETVAL, integers->name,
2218 strlen(integers->name), newSViv(value), 0);
2222 RESTORE_LC_NUMERIC_STANDARD();
2223 #endif /* HAS_LOCALECONV */
2228 setlocale(category, locale = 0)
2234 #ifdef USE_LOCALE_NUMERIC
2235 /* A 0 (or NULL) locale means only query what the current one is. We
2236 * have the LC_NUMERIC name saved, because we are normally switched
2237 * into the C locale for it. Switch back so an LC_ALL query will yield
2238 * the correct results; all other categories don't require special
2241 if (category == LC_NUMERIC) {
2242 XSRETURN_PV(PL_numeric_name);
2245 else if (category == LC_ALL) {
2246 SET_NUMERIC_UNDERLYING();
2251 #ifdef WIN32 /* Use wrapper on Windows */
2252 retval = Perl_my_setlocale(aTHX_ category, locale);
2254 retval = setlocale(category, locale);
2257 /* Should never happen that a query would return an error, but be
2258 * sure and reset to C locale */
2260 SET_NUMERIC_STANDARD();
2265 /* Save retval since subsequent setlocale() calls may overwrite it. */
2266 retval = savepv(retval);
2268 /* For locale == 0, we may have switched to NUMERIC_UNDERLYING. Switch
2271 SET_NUMERIC_STANDARD();
2272 XSRETURN_PV(retval);
2276 #ifdef USE_LOCALE_CTYPE
2277 if (category == LC_CTYPE
2279 || category == LC_ALL
2285 if (category == LC_ALL)
2286 newctype = setlocale(LC_CTYPE, NULL);
2290 new_ctype(newctype);
2292 #endif /* USE_LOCALE_CTYPE */
2293 #ifdef USE_LOCALE_COLLATE
2294 if (category == LC_COLLATE
2296 || category == LC_ALL
2302 if (category == LC_ALL)
2303 newcoll = setlocale(LC_COLLATE, NULL);
2307 new_collate(newcoll);
2309 #endif /* USE_LOCALE_COLLATE */
2310 #ifdef USE_LOCALE_NUMERIC
2311 if (category == LC_NUMERIC
2313 || category == LC_ALL
2319 if (category == LC_ALL)
2320 newnum = setlocale(LC_NUMERIC, NULL);
2324 new_numeric(newnum);
2326 #endif /* USE_LOCALE_NUMERIC */
2372 RETVAL = Perl_acos(x); /* C89 math */
2376 RETVAL = c99_acosh(x);
2382 RETVAL = Perl_asin(x); /* C89 math */
2386 RETVAL = c99_asinh(x);
2392 RETVAL = Perl_atan(x); /* C89 math */
2396 RETVAL = c99_atanh(x);
2403 RETVAL = c99_cbrt(x);
2409 RETVAL = Perl_ceil(x); /* C89 math */
2412 RETVAL = Perl_cosh(x); /* C89 math */
2416 RETVAL = c99_erf(x);
2423 RETVAL = c99_erfc(x);
2430 RETVAL = c99_exp2(x);
2437 RETVAL = c99_expm1(x);
2443 RETVAL = Perl_floor(x); /* C89 math */
2447 RETVAL = bessel_j0(x);
2454 RETVAL = bessel_j1(x);
2460 /* XXX Note: the lgamma modifies a global variable (signgam),
2461 * which is evil. Some platforms have lgamma_r, which has
2462 * extra output parameter instead of the global variable. */
2464 RETVAL = c99_lgamma(x);
2470 RETVAL = log10(x); /* C89 math */
2474 RETVAL = c99_log1p(x);
2481 RETVAL = c99_log2(x);
2488 RETVAL = c99_logb(x);
2489 #elif defined(c99_log2) && FLT_RADIX == 2
2490 RETVAL = Perl_floor(c99_log2(PERL_ABS(x)));
2496 #ifdef c99_nearbyint
2497 RETVAL = c99_nearbyint(x);
2499 not_here("nearbyint");
2504 RETVAL = c99_rint(x);
2511 RETVAL = c99_round(x);
2517 RETVAL = Perl_sinh(x); /* C89 math */
2520 RETVAL = Perl_tan(x); /* C89 math */
2523 RETVAL = Perl_tanh(x); /* C89 math */
2527 RETVAL = c99_tgamma(x);
2534 RETVAL = c99_trunc(x);
2541 RETVAL = bessel_y0(x);
2549 RETVAL = bessel_y1(x);
2560 #ifdef HAS_FEGETROUND
2561 RETVAL = my_fegetround();
2564 not_here("fegetround");
2573 #ifdef HAS_FEGETROUND /* canary for fesetround */
2574 RETVAL = fesetround(x);
2575 #elif defined(HAS_FPGETROUND) /* canary for fpsetround */
2577 case FE_TONEAREST: RETVAL = fpsetround(FP_RN); break;
2578 case FE_TOWARDZERO: RETVAL = fpsetround(FP_RZ); break;
2579 case FE_DOWNWARD: RETVAL = fpsetround(FP_RM); break;
2580 case FE_UPWARD: RETVAL = fpsetround(FP_RP); break;
2581 default: RETVAL = -1; break;
2583 #elif defined(__osf__) /* Tru64 */
2585 case FE_TONEAREST: RETVAL = write_rnd(FP_RND_RN); break;
2586 case FE_TOWARDZERO: RETVAL = write_rnd(FP_RND_RZ); break;
2587 case FE_DOWNWARD: RETVAL = write_rnd(FP_RND_RM); break;
2588 case FE_UPWARD: RETVAL = write_rnd(FP_RND_RP); break;
2589 default: RETVAL = -1; break;
2594 not_here("fesetround");
2616 #ifdef c99_fpclassify
2617 RETVAL = c99_fpclassify(x);
2619 not_here("fpclassify");
2624 RETVAL = c99_ilogb(x);
2630 RETVAL = Perl_isfinite(x);
2633 RETVAL = Perl_isinf(x);
2636 RETVAL = Perl_isnan(x);
2640 RETVAL = c99_isnormal(x);
2642 not_here("isnormal");
2647 RETVAL = c99_lrint(x);
2654 RETVAL = c99_lround(x);
2662 RETVAL = Perl_signbit(x);
2664 RETVAL = (x < 0) || (x == -0.0);
2675 RETVAL = S_getpayload(nv);
2680 setpayload(nv, payload)
2684 S_setpayload(&nv, payload, FALSE);
2689 setpayloadsig(nv, payload)
2694 S_setpayload(&nv, payload, TRUE);
2702 RETVAL = Perl_isnan(nv) && NV_NAN_IS_SIGNALING(&nv);
2732 RETVAL = c99_copysign(x, y);
2734 not_here("copysign");
2739 RETVAL = c99_fdim(x, y);
2746 RETVAL = c99_fmax(x, y);
2753 RETVAL = c99_fmin(x, y);
2759 RETVAL = Perl_fmod(x, y); /* C89 math */
2763 RETVAL = c99_hypot(x, y);
2769 #ifdef c99_isgreater
2770 RETVAL = c99_isgreater(x, y);
2772 not_here("isgreater");
2776 #ifdef c99_isgreaterequal
2777 RETVAL = c99_isgreaterequal(x, y);
2779 not_here("isgreaterequal");
2784 RETVAL = c99_isless(x, y);
2790 #ifdef c99_islessequal
2791 RETVAL = c99_islessequal(x, y);
2793 not_here("islessequal");
2797 #ifdef c99_islessgreater
2798 RETVAL = c99_islessgreater(x, y);
2800 not_here("islessgreater");
2804 #ifdef c99_isunordered
2805 RETVAL = c99_isunordered(x, y);
2807 not_here("isunordered");
2811 #ifdef c99_nextafter
2812 RETVAL = c99_nextafter(x, y);
2814 not_here("nextafter");
2818 #ifdef c99_nexttoward
2819 RETVAL = c99_nexttoward(x, y);
2821 not_here("nexttoward");
2826 #ifdef c99_remainder
2827 RETVAL = c99_remainder(x, y);
2829 not_here("remainder");
2841 /* (We already know stack is long enough.) */
2842 PUSHs(sv_2mortal(newSVnv(Perl_frexp(x,&expvar)))); /* C89 math */
2843 PUSHs(sv_2mortal(newSViv(expvar)));
2855 /* (We already know stack is long enough.) */
2856 PUSHs(sv_2mortal(newSVnv(Perl_modf(x,&intvar)))); /* C89 math */
2857 PUSHs(sv_2mortal(newSVnv(intvar)));
2866 PUSHs(sv_2mortal(newSVnv(c99_remquo(x,y,&intvar))));
2867 PUSHs(sv_2mortal(newSVnv(intvar)));
2880 RETVAL = c99_scalbn(x, y);
2900 RETVAL = c99_fma(x, y, z);
2910 /* If no payload given, just return the default NaN.
2911 * This makes a difference in platforms where the default
2912 * NaN is not all zeros. */
2916 S_setpayload(&RETVAL, payload, FALSE);
2918 #elif defined(c99_nan)
2920 STRLEN elen = my_snprintf(PL_efloatbuf, PL_efloatsize, "%g", nv);
2921 if ((IV)elen == -1) {
2924 RETVAL = c99_nan(PL_efloatbuf);
2946 RETVAL = bessel_jn(x, y);
2954 RETVAL = bessel_yn(x, y);
2964 sigaction(sig, optaction, oldaction = 0)
2967 POSIX::SigAction oldaction
2969 #if defined(WIN32) || defined(NETWARE)
2970 RETVAL = not_here("sigaction");
2972 # This code is really grody because we're trying to make the signal
2973 # interface look beautiful, which is hard.
2977 POSIX__SigAction action;
2978 GV *siggv = gv_fetchpvs("SIG", GV_ADD, SVt_PVHV);
2979 struct sigaction act;
2980 struct sigaction oact;
2984 POSIX__SigSet sigset;
2989 croak("Negative signals are not allowed");
2992 if (sig == 0 && SvPOK(ST(0))) {
2993 const char *s = SvPVX_const(ST(0));
2994 int i = whichsig(s);
2996 if (i < 0 && memEQ(s, "SIG", 3))
2997 i = whichsig(s + 3);
2999 if (ckWARN(WARN_SIGNAL))
3000 Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
3001 "No such signal: SIG%s", s);
3008 if (sig > NSIG) { /* NSIG - 1 is still okay. */
3009 Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
3010 "No such signal: %d", sig);
3014 sigsvp = hv_fetch(GvHVn(siggv),
3016 strlen(PL_sig_name[sig]),
3019 /* Check optaction and set action */
3020 if(SvTRUE(optaction)) {
3021 if(sv_isa(optaction, "POSIX::SigAction"))
3022 action = (HV*)SvRV(optaction);
3024 croak("action is not of type POSIX::SigAction");
3030 /* sigaction() is supposed to look atomic. In particular, any
3031 * signal handler invoked during a sigaction() call should
3032 * see either the old or the new disposition, and not something
3033 * in between. We use sigprocmask() to make it so.
3036 RETVAL=sigprocmask(SIG_BLOCK, &sset, &osset);
3040 /* Restore signal mask no matter how we exit this block. */
3041 osset_sv = newSVpvn((char *)(&osset), sizeof(sigset_t));
3042 SAVEFREESV( osset_sv );
3043 SAVEDESTRUCTOR_X(restore_sigmask, osset_sv);
3045 RETVAL=-1; /* In case both oldaction and action are 0. */
3047 /* Remember old disposition if desired. */
3049 svp = hv_fetchs(oldaction, "HANDLER", TRUE);
3051 croak("Can't supply an oldaction without a HANDLER");
3052 if(SvTRUE(*sigsvp)) { /* TBD: what if "0"? */
3053 sv_setsv(*svp, *sigsvp);
3056 sv_setpvs(*svp, "DEFAULT");
3058 RETVAL = sigaction(sig, (struct sigaction *)0, & oact);
3063 /* Get back the mask. */
3064 svp = hv_fetchs(oldaction, "MASK", TRUE);
3065 if (sv_isa(*svp, "POSIX::SigSet")) {
3066 sigset = (sigset_t *) SvPV_nolen(SvRV(*svp));
3069 sigset = (sigset_t *) allocate_struct(aTHX_ *svp,
3073 *sigset = oact.sa_mask;
3075 /* Get back the flags. */
3076 svp = hv_fetchs(oldaction, "FLAGS", TRUE);
3077 sv_setiv(*svp, oact.sa_flags);
3079 /* Get back whether the old handler used safe signals. */
3080 svp = hv_fetchs(oldaction, "SAFE", TRUE);
3082 /* compare incompatible pointers by casting to integer */
3083 PTR2nat(oact.sa_handler) == PTR2nat(PL_csighandlerp));
3087 /* Safe signals use "csighandler", which vectors through the
3088 PL_sighandlerp pointer when it's safe to do so.
3089 (BTW, "csighandler" is very different from "sighandler".) */
3090 svp = hv_fetchs(action, "SAFE", FALSE);
3094 (*svp && SvTRUE(*svp))
3095 ? PL_csighandlerp : PL_sighandlerp
3098 /* Vector new Perl handler through %SIG.
3099 (The core signal handlers read %SIG to dispatch.) */
3100 svp = hv_fetchs(action, "HANDLER", FALSE);
3102 croak("Can't supply an action without a HANDLER");
3103 sv_setsv(*sigsvp, *svp);
3105 /* This call actually calls sigaction() with almost the
3106 right settings, including appropriate interpretation
3107 of DEFAULT and IGNORE. However, why are we doing
3108 this when we're about to do it again just below? XXX */
3109 SvSETMAGIC(*sigsvp);
3111 /* And here again we duplicate -- DEFAULT/IGNORE checking. */
3113 const char *s=SvPVX_const(*svp);
3114 if(strEQ(s,"IGNORE")) {
3115 act.sa_handler = SIG_IGN;
3117 else if(strEQ(s,"DEFAULT")) {
3118 act.sa_handler = SIG_DFL;
3122 /* Set up any desired mask. */
3123 svp = hv_fetchs(action, "MASK", FALSE);
3124 if (svp && sv_isa(*svp, "POSIX::SigSet")) {
3125 sigset = (sigset_t *) SvPV_nolen(SvRV(*svp));
3126 act.sa_mask = *sigset;
3129 sigemptyset(& act.sa_mask);
3131 /* Set up any desired flags. */
3132 svp = hv_fetchs(action, "FLAGS", FALSE);
3133 act.sa_flags = svp ? SvIV(*svp) : 0;
3135 /* Don't worry about cleaning up *sigsvp if this fails,
3136 * because that means we tried to disposition a
3137 * nonblockable signal, in which case *sigsvp is
3138 * essentially meaningless anyway.
3140 RETVAL = sigaction(sig, & act, (struct sigaction *)0);
3155 POSIX::SigSet sigset
3159 RETVAL = ix ? sigsuspend(sigset) : sigpending(sigset);
3166 sigprocmask(how, sigset, oldsigset = 0)
3168 POSIX::SigSet sigset = NO_INIT
3169 POSIX::SigSet oldsigset = NO_INIT
3171 if (! SvOK(ST(1))) {
3173 } else if (sv_isa(ST(1), "POSIX::SigSet")) {
3174 sigset = (sigset_t *) SvPV_nolen(SvRV(ST(1)));
3176 croak("sigset is not of type POSIX::SigSet");
3179 if (items < 3 || ! SvOK(ST(2))) {
3181 } else if (sv_isa(ST(2), "POSIX::SigSet")) {
3182 oldsigset = (sigset_t *) SvPV_nolen(SvRV(ST(2)));
3184 croak("oldsigset is not of type POSIX::SigSet");
3197 /* RT #98912 - More Microsoft muppetry - failing to actually implemented
3198 the well known documented POSIX behaviour for a POSIX API.
3199 http://msdn.microsoft.com/en-us/library/8syseb29.aspx */
3200 RETVAL = dup2(fd1, fd2) == -1 ? -1 : fd2;
3202 RETVAL = dup2(fd1, fd2);
3208 lseek(fd, offset, whence)
3214 Off_t pos = PerlLIO_lseek(fd, offset, whence);
3215 RETVAL = sizeof(Off_t) > sizeof(IV)
3216 ? newSVnv((NV)pos) : newSViv((IV)pos);
3218 SETERRNO(EBADF,RMS_IFI);
3219 RETVAL = newSViv(-1);
3229 if ((incr = nice(incr)) != -1 || errno == 0) {
3231 XPUSHs(newSVpvs_flags("0 but true", SVs_TEMP));
3233 XPUSHs(sv_2mortal(newSViv(incr)));
3240 if (pipe(fds) != -1) {
3242 PUSHs(sv_2mortal(newSViv(fds[0])));
3243 PUSHs(sv_2mortal(newSViv(fds[1])));
3247 read(fd, buffer, nbytes)
3249 SV *sv_buffer = SvROK(ST(1)) ? SvRV(ST(1)) : ST(1);
3253 char * buffer = sv_grow( sv_buffer, nbytes+1 );
3256 SvCUR_set(sv_buffer, RETVAL);
3257 SvPOK_only(sv_buffer);
3258 *SvEND(sv_buffer) = '\0';
3259 SvTAINTED_on(sv_buffer);
3275 tcsetpgrp(fd, pgrp_id)
3284 if (uname(&buf) >= 0) {
3286 PUSHs(newSVpvn_flags(buf.sysname, strlen(buf.sysname), SVs_TEMP));
3287 PUSHs(newSVpvn_flags(buf.nodename, strlen(buf.nodename), SVs_TEMP));
3288 PUSHs(newSVpvn_flags(buf.release, strlen(buf.release), SVs_TEMP));
3289 PUSHs(newSVpvn_flags(buf.version, strlen(buf.version), SVs_TEMP));
3290 PUSHs(newSVpvn_flags(buf.machine, strlen(buf.machine), SVs_TEMP));
3293 uname((char *) 0); /* A stub to call not_here(). */
3297 write(fd, buffer, nbytes)
3308 RETVAL = newSVpvs("");
3309 SvGROW(RETVAL, L_tmpnam);
3310 /* Yes, we know tmpnam() is bad. So bad that some compilers
3311 * and linkers warn against using it. But it is here for
3312 * completeness. POSIX.pod warns against using it.
3314 * Then again, maybe this should be removed at some point.
3315 * No point in enabling dangerous interfaces. */
3316 if (ckWARN_d(WARN_DEPRECATED)) {
3317 HV *warned = get_hv("POSIX::_warned", GV_ADD | GV_ADDMULTI);
3318 if (! hv_exists(warned, (const char *)&PL_op, sizeof(PL_op))) {
3319 Perl_warner(aTHX_ packWARN(WARN_DEPRECATED), "Calling POSIX::tmpnam() is deprecated");
3320 (void)hv_store(warned, (const char *)&PL_op, sizeof(PL_op), &PL_sv_yes, 0);
3323 len = strlen(tmpnam(SvPV(RETVAL, i)));
3324 SvCUR_set(RETVAL, len);
3337 mbstowcs(s, pwcs, n)
3349 wcstombs(s, pwcs, n)
3371 DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
3372 STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
3373 num = strtod(str, &unparsed);
3374 PUSHs(sv_2mortal(newSVnv(num)));
3375 if (GIMME_V == G_ARRAY) {
3378 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3380 PUSHs(&PL_sv_undef);
3382 RESTORE_LC_NUMERIC_STANDARD();
3393 DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
3394 STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
3395 num = strtold(str, &unparsed);
3396 PUSHs(sv_2mortal(newSVnv(num)));
3397 if (GIMME_V == G_ARRAY) {
3400 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3402 PUSHs(&PL_sv_undef);
3404 RESTORE_LC_NUMERIC_STANDARD();
3409 strtol(str, base = 0)
3416 num = strtol(str, &unparsed, base);
3417 #if IVSIZE <= LONGSIZE
3418 if (num < IV_MIN || num > IV_MAX)
3419 PUSHs(sv_2mortal(newSVnv((double)num)));
3422 PUSHs(sv_2mortal(newSViv((IV)num)));
3423 if (GIMME_V == G_ARRAY) {
3426 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3428 PUSHs(&PL_sv_undef);
3432 strtoul(str, base = 0)
3439 PERL_UNUSED_VAR(str);
3440 PERL_UNUSED_VAR(base);
3441 num = strtoul(str, &unparsed, base);
3442 #if IVSIZE <= LONGSIZE
3444 PUSHs(sv_2mortal(newSVnv((double)num)));
3447 PUSHs(sv_2mortal(newSViv((IV)num)));
3448 if (GIMME_V == G_ARRAY) {
3451 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3453 PUSHs(&PL_sv_undef);
3464 char *p = SvPV(src,srclen);
3466 buflen = srclen * 4 + 1;
3467 ST(0) = sv_2mortal(newSV(buflen));
3468 dstlen = strxfrm(SvPVX(ST(0)), p, (size_t)buflen);
3469 if (dstlen >= buflen) {
3471 SvGROW(ST(0), dstlen);
3472 strxfrm(SvPVX(ST(0)), p, (size_t)dstlen);
3475 SvCUR_set(ST(0), dstlen);
3480 mkfifo(filename, mode)
3487 RETVAL = access(filename, mode);
3489 TAINT_PROPER("mkfifo");
3490 RETVAL = mkfifo(filename, mode);
3502 RETVAL = ix == 1 ? close(fd)
3503 : (ix < 1 ? tcdrain(fd) : dup(fd));
3516 RETVAL = ix == 1 ? tcflush(fd, action)
3517 : (ix < 1 ? tcflow(fd, action) : tcsendbreak(fd, action));
3522 asctime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = -1)
3538 init_tm(&mytm); /* XXX workaround - see init_tm() in core util.c */
3541 mytm.tm_hour = hour;
3542 mytm.tm_mday = mday;
3544 mytm.tm_year = year;
3545 mytm.tm_wday = wday;
3546 mytm.tm_yday = yday;
3547 mytm.tm_isdst = isdst;
3549 const time_t result = mktime(&mytm);
3550 if (result == (time_t)-1)
3552 else if (result == 0)
3553 sv_setpvn(TARG, "0 but true", 10);
3555 sv_setiv(TARG, (IV)result);
3557 sv_setpv(TARG, asctime(&mytm));
3575 realtime = times( &tms );
3577 PUSHs( sv_2mortal( newSViv( (IV) realtime ) ) );
3578 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_utime ) ) );
3579 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_stime ) ) );
3580 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cutime ) ) );
3581 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cstime ) ) );
3584 difftime(time1, time2)
3588 #XXX: if $xsubpp::WantOptimize is always the default
3589 # sv_setpv(TARG, ...) could be used rather than
3590 # ST(0) = sv_2mortal(newSVpv(...))
3592 strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1)
3608 /* allowing user-supplied (rather than literal) formats
3609 * is normally frowned upon as a potential security risk;
3610 * but this is part of the API so we have to allow it */
3611 GCC_DIAG_IGNORE(-Wformat-nonliteral);
3612 buf = my_strftime(SvPV_nolen(fmt), sec, min, hour, mday, mon, year, wday, yday, isdst);
3614 sv = sv_newmortal();
3616 STRLEN len = strlen(buf);
3617 sv_usepvn_flags(sv, buf, len, SV_HAS_TRAILING_NUL);
3619 || (! is_invariant_string((U8*) buf, len)
3620 && is_utf8_string((U8*) buf, len)
3621 #ifdef USE_LOCALE_TIME
3622 && _is_cur_LC_category_utf8(LC_TIME)
3628 else { /* We can't distinguish between errors and just an empty
3629 * return; in all cases just return an empty string */
3630 SvUPGRADE(sv, SVt_PV);
3631 SvPV_set(sv, (char *) "");
3634 SvLEN_set(sv, 0); /* Won't attempt to free the string when sv
3649 PUSHs(newSVpvn_flags(tzname[0], strlen(tzname[0]), SVs_TEMP));
3650 PUSHs(newSVpvn_flags(tzname[1], strlen(tzname[1]), SVs_TEMP));
3656 #ifdef HAS_CTERMID_R
3657 s = (char *) safemalloc((size_t) L_ctermid);
3659 RETVAL = ctermid(s);
3663 #ifdef HAS_CTERMID_R
3672 RETVAL = cuserid(s);
3676 not_here("cuserid");
3687 pathconf(filename, name)
3698 unsigned int seconds
3700 RETVAL = PerlProc_sleep(seconds);
3726 XSprePUSH; PUSHTARG;
3730 lchown(uid, gid, path)
3736 /* yes, the order of arguments is different,
3737 * but consistent with CORE::chown() */
3738 RETVAL = lchown(path, uid, gid);
3740 PERL_UNUSED_VAR(uid);
3741 PERL_UNUSED_VAR(gid);
3742 PERL_UNUSED_VAR(path);
3743 RETVAL = not_here("lchown");