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 # if LONG_DOUBLESIZE > 10
1233 memset((char *)nvp + 10, '\0', LONG_DOUBLESIZE - 10); /* x86 long double */
1237 for (i = 0; i < (int)C_ARRAY_LENGTH(a); i++) {
1239 Perl_warn(aTHX_ "payload lost bits (%"UVxf")", a[i]);
1243 #ifdef NV_PAYLOAD_DEBUG
1244 for (i = 0; i < NVSIZE; i++) {
1245 PerlIO_printf(Perl_debug_log, "%02x ", ((U8 *)(nvp))[i]);
1247 PerlIO_printf(Perl_debug_log, "\n");
1251 static NV_PAYLOAD_TYPE S_getpayload(NV nv)
1254 static const U8 m[] = { NV_NAN_PAYLOAD_MASK };
1255 static const U8 p[] = { NV_NAN_PAYLOAD_PERM };
1256 UV a[(NVSIZE + UVSIZE - 1) / UVSIZE] = { 0 };
1259 NV_PAYLOAD_SIZEOF_ASSERT(m);
1260 NV_PAYLOAD_SIZEOF_ASSERT(p);
1262 for (i = 0; i < (int)sizeof(p); i++) {
1263 if (m[i] && p[i] < NVSIZE) {
1264 U8 s = (p[i] % UVSIZE) << 3;
1265 a[p[i] / UVSIZE] |= (UV)(((U8 *)(&nv))[i] & m[i]) << s;
1268 for (i = (int)C_ARRAY_LENGTH(a) - 1; i >= 0; i--) {
1269 #ifdef NV_PAYLOAD_DEBUG
1270 Perl_warn(aTHX_ "a[%d] = %"UVxf"\n", i, a[i]);
1275 #ifdef NV_PAYLOAD_DEBUG
1276 for (i = 0; i < NVSIZE; i++) {
1277 PerlIO_printf(Perl_debug_log, "%02x ", ((U8 *)(&nv))[i]);
1279 PerlIO_printf(Perl_debug_log, "\n");
1284 /* XXX This comment is just to make I_TERMIO and I_SGTTY visible to
1285 metaconfig for future extension writers. We don't use them in POSIX.
1286 (This is really sneaky :-) --AD
1288 #if defined(I_TERMIOS)
1289 #include <termios.h>
1297 #include <sys/stat.h>
1298 #include <sys/types.h>
1306 # if !defined(WIN32) && !defined(__CYGWIN__) && !defined(NETWARE) && !defined(__UWIN__)
1307 extern char *tzname[];
1310 #if !defined(WIN32) && !defined(__UWIN__) || (defined(__MINGW32__) && !defined(tzname))
1311 char *tzname[] = { "" , "" };
1315 #if defined(__VMS) && !defined(__POSIX_SOURCE)
1317 # include <utsname.h>
1320 # define mkfifo(a,b) (not_here("mkfifo"),-1)
1322 /* The POSIX notion of ttyname() is better served by getname() under VMS */
1323 static char ttnambuf[64];
1324 # define ttyname(fd) (isatty(fd) > 0 ? getname(fd,ttnambuf,0) : NULL)
1327 #if defined (__CYGWIN__)
1328 # define tzname _tzname
1330 #if defined (WIN32) || defined (NETWARE)
1332 # define mkfifo(a,b) not_here("mkfifo")
1333 # define ttyname(a) (char*)not_here("ttyname")
1334 # define sigset_t long
1337 # define mode_t short
1340 # define mode_t short
1342 # define tzset() not_here("tzset")
1344 # ifndef _POSIX_OPEN_MAX
1345 # define _POSIX_OPEN_MAX FOPEN_MAX /* XXX bogus ? */
1348 # define sigaction(a,b,c) not_here("sigaction")
1349 # define sigpending(a) not_here("sigpending")
1350 # define sigprocmask(a,b,c) not_here("sigprocmask")
1351 # define sigsuspend(a) not_here("sigsuspend")
1352 # define sigemptyset(a) not_here("sigemptyset")
1353 # define sigaddset(a,b) not_here("sigaddset")
1354 # define sigdelset(a,b) not_here("sigdelset")
1355 # define sigfillset(a) not_here("sigfillset")
1356 # define sigismember(a,b) not_here("sigismember")
1360 # define setuid(a) not_here("setuid")
1361 # define setgid(a) not_here("setgid")
1362 #endif /* NETWARE */
1363 #ifndef USE_LONG_DOUBLE
1364 # define strtold(s1,s2) not_here("strtold")
1365 #endif /* USE_LONG_DOUBLE */
1369 # if defined(OS2) || defined(__amigaos4__)
1370 # define mkfifo(a,b) not_here("mkfifo")
1371 # else /* !( defined OS2 ) */
1373 # define mkfifo(path, mode) (mknod((path), (mode) | S_IFIFO, 0))
1376 # endif /* !HAS_MKFIFO */
1381 # include <sys/times.h>
1383 # include <sys/utsname.h>
1385 # ifndef __amigaos4__
1386 # include <sys/wait.h>
1391 #endif /* WIN32 || NETWARE */
1395 typedef long SysRetLong;
1396 typedef sigset_t* POSIX__SigSet;
1397 typedef HV* POSIX__SigAction;
1399 typedef struct termios* POSIX__Termios;
1400 #else /* Define termios types to int, and call not_here for the functions.*/
1401 #define POSIX__Termios int
1403 #define tcflag_t int
1405 #define cfgetispeed(x) not_here("cfgetispeed")
1406 #define cfgetospeed(x) not_here("cfgetospeed")
1407 #define tcdrain(x) not_here("tcdrain")
1408 #define tcflush(x,y) not_here("tcflush")
1409 #define tcsendbreak(x,y) not_here("tcsendbreak")
1410 #define cfsetispeed(x,y) not_here("cfsetispeed")
1411 #define cfsetospeed(x,y) not_here("cfsetospeed")
1412 #define ctermid(x) (char *) not_here("ctermid")
1413 #define tcflow(x,y) not_here("tcflow")
1414 #define tcgetattr(x,y) not_here("tcgetattr")
1415 #define tcsetattr(x,y,z) not_here("tcsetattr")
1418 /* Possibly needed prototypes */
1421 double strtod (const char *, char **);
1422 long strtol (const char *, char **, int);
1423 unsigned long strtoul (const char *, char **, int);
1425 long double strtold (const char *, char **);
1430 #ifndef HAS_DIFFTIME
1432 #define difftime(a,b) not_here("difftime")
1435 #ifndef HAS_FPATHCONF
1436 #define fpathconf(f,n) (SysRetLong) not_here("fpathconf")
1439 #define mktime(a) not_here("mktime")
1442 #define nice(a) not_here("nice")
1444 #ifndef HAS_PATHCONF
1445 #define pathconf(f,n) (SysRetLong) not_here("pathconf")
1448 #define sysconf(n) (SysRetLong) not_here("sysconf")
1450 #ifndef HAS_READLINK
1451 #define readlink(a,b,c) not_here("readlink")
1454 #define setpgid(a,b) not_here("setpgid")
1457 #define setsid() not_here("setsid")
1460 #define strcoll(s1,s2) not_here("strcoll")
1463 #define strtod(s1,s2) not_here("strtod")
1466 #define strtold(s1,s2) not_here("strtold")
1469 #define strtol(s1,s2,b) not_here("strtol")
1472 #define strtoul(s1,s2,b) not_here("strtoul")
1475 #define strxfrm(s1,s2,n) not_here("strxfrm")
1477 #ifndef HAS_TCGETPGRP
1478 #define tcgetpgrp(a) not_here("tcgetpgrp")
1480 #ifndef HAS_TCSETPGRP
1481 #define tcsetpgrp(a,b) not_here("tcsetpgrp")
1485 #define times(a) not_here("times")
1486 #endif /* NETWARE */
1489 #define uname(a) not_here("uname")
1492 #define waitpid(a,b,c) not_here("waitpid")
1497 #define mblen(a,b) not_here("mblen")
1500 #ifndef HAS_MBSTOWCS
1501 #define mbstowcs(s, pwcs, n) not_here("mbstowcs")
1504 #define mbtowc(pwc, s, n) not_here("mbtowc")
1506 #ifndef HAS_WCSTOMBS
1507 #define wcstombs(s, pwcs, n) not_here("wcstombs")
1510 #define wctomb(s, wchar) not_here("wcstombs")
1512 #if !defined(HAS_MBLEN) && !defined(HAS_MBSTOWCS) && !defined(HAS_MBTOWC) && !defined(HAS_WCSTOMBS) && !defined(HAS_WCTOMB)
1513 /* If we don't have these functions, then we wouldn't have gotten a typedef
1514 for wchar_t, the wide character type. Defining wchar_t allows the
1515 functions referencing it to compile. Its actual type is then meaningless,
1516 since without the above functions, all sections using it end up calling
1517 not_here() and croak. --Kaveh Ghazi (ghazi@noc.rutgers.edu) 9/18/94. */
1519 #define wchar_t char
1523 #ifndef HAS_LOCALECONV
1524 # define localeconv() not_here("localeconv")
1526 struct lconv_offset {
1531 static const struct lconv_offset lconv_strings[] = {
1532 #ifdef USE_LOCALE_NUMERIC
1533 {"decimal_point", STRUCT_OFFSET(struct lconv, decimal_point)},
1534 {"thousands_sep", STRUCT_OFFSET(struct lconv, thousands_sep)},
1535 # ifndef NO_LOCALECONV_GROUPING
1536 {"grouping", STRUCT_OFFSET(struct lconv, grouping)},
1539 #ifdef USE_LOCALE_MONETARY
1540 {"int_curr_symbol", STRUCT_OFFSET(struct lconv, int_curr_symbol)},
1541 {"currency_symbol", STRUCT_OFFSET(struct lconv, currency_symbol)},
1542 {"mon_decimal_point", STRUCT_OFFSET(struct lconv, mon_decimal_point)},
1543 # ifndef NO_LOCALECONV_MON_THOUSANDS_SEP
1544 {"mon_thousands_sep", STRUCT_OFFSET(struct lconv, mon_thousands_sep)},
1546 # ifndef NO_LOCALECONV_MON_GROUPING
1547 {"mon_grouping", STRUCT_OFFSET(struct lconv, mon_grouping)},
1549 {"positive_sign", STRUCT_OFFSET(struct lconv, positive_sign)},
1550 {"negative_sign", STRUCT_OFFSET(struct lconv, negative_sign)},
1555 #ifdef USE_LOCALE_NUMERIC
1557 /* The Linux man pages say these are the field names for the structure
1558 * components that are LC_NUMERIC; the rest being LC_MONETARY */
1559 # define isLC_NUMERIC_STRING(name) (strcmp(name, "decimal_point") \
1560 || strcmp(name, "thousands_sep") \
1562 /* There should be no harm done \
1563 * checking for this, even if \
1564 * NO_LOCALECONV_GROUPING */ \
1565 || strcmp(name, "grouping"))
1567 # define isLC_NUMERIC_STRING(name) (0)
1570 static const struct lconv_offset lconv_integers[] = {
1571 #ifdef USE_LOCALE_MONETARY
1572 {"int_frac_digits", STRUCT_OFFSET(struct lconv, int_frac_digits)},
1573 {"frac_digits", STRUCT_OFFSET(struct lconv, frac_digits)},
1574 {"p_cs_precedes", STRUCT_OFFSET(struct lconv, p_cs_precedes)},
1575 {"p_sep_by_space", STRUCT_OFFSET(struct lconv, p_sep_by_space)},
1576 {"n_cs_precedes", STRUCT_OFFSET(struct lconv, n_cs_precedes)},
1577 {"n_sep_by_space", STRUCT_OFFSET(struct lconv, n_sep_by_space)},
1578 {"p_sign_posn", STRUCT_OFFSET(struct lconv, p_sign_posn)},
1579 {"n_sign_posn", STRUCT_OFFSET(struct lconv, n_sign_posn)},
1580 #ifdef HAS_LC_MONETARY_2008
1581 {"int_p_cs_precedes", STRUCT_OFFSET(struct lconv, int_p_cs_precedes)},
1582 {"int_p_sep_by_space", STRUCT_OFFSET(struct lconv, int_p_sep_by_space)},
1583 {"int_n_cs_precedes", STRUCT_OFFSET(struct lconv, int_n_cs_precedes)},
1584 {"int_n_sep_by_space", STRUCT_OFFSET(struct lconv, int_n_sep_by_space)},
1585 {"int_p_sign_posn", STRUCT_OFFSET(struct lconv, int_p_sign_posn)},
1586 {"int_n_sign_posn", STRUCT_OFFSET(struct lconv, int_n_sign_posn)},
1592 #endif /* HAS_LOCALECONV */
1594 #ifdef HAS_LONG_DOUBLE
1595 # if LONG_DOUBLESIZE > NVSIZE
1596 # undef HAS_LONG_DOUBLE /* XXX until we figure out how to use them */
1600 #ifndef HAS_LONG_DOUBLE
1612 /* Background: in most systems the low byte of the wait status
1613 * is the signal (the lowest 7 bits) and the coredump flag is
1614 * the eight bit, and the second lowest byte is the exit status.
1615 * BeOS bucks the trend and has the bytes in different order.
1616 * See beos/beos.c for how the reality is bent even in BeOS
1617 * to follow the traditional. However, to make the POSIX
1618 * wait W*() macros to work in BeOS, we need to unbend the
1619 * reality back in place. --jhi */
1620 /* In actual fact the code below is to blame here. Perl has an internal
1621 * representation of the exit status ($?), which it re-composes from the
1622 * OS's representation using the W*() POSIX macros. The code below
1623 * incorrectly uses the W*() macros on the internal representation,
1624 * which fails for OSs that have a different representation (namely BeOS
1625 * and Haiku). WMUNGE() is a hack that converts the internal
1626 * representation into the OS specific one, so that the W*() macros work
1627 * as expected. The better solution would be not to use the W*() macros
1628 * in the first place, though. -- Ingo Weinhold
1630 #if defined(__HAIKU__)
1631 # define WMUNGE(x) (((x) & 0xFF00) >> 8 | ((x) & 0x00FF) << 8)
1633 # define WMUNGE(x) (x)
1637 not_here(const char *s)
1639 croak("POSIX::%s not implemented on this architecture", s);
1643 #include "const-c.inc"
1646 restore_sigmask(pTHX_ SV *osset_sv)
1648 /* Fortunately, restoring the signal mask can't fail, because
1649 * there's nothing we can do about it if it does -- we're not
1650 * supposed to return -1 from sigaction unless the disposition
1653 #if !(defined(__amigaos4__) && defined(__NEWLIB__))
1654 sigset_t *ossetp = (sigset_t *) SvPV_nolen( osset_sv );
1655 (void)sigprocmask(SIG_SETMASK, ossetp, (sigset_t *)0);
1660 allocate_struct(pTHX_ SV *rv, const STRLEN size, const char *packname) {
1661 SV *const t = newSVrv(rv, packname);
1662 void *const p = sv_grow(t, size + 1);
1672 * (1) The CRT maintains its own copy of the environment, separate from
1673 * the Win32API copy.
1675 * (2) CRT getenv() retrieves from this copy. CRT putenv() updates this
1676 * copy, and then calls SetEnvironmentVariableA() to update the Win32API
1679 * (3) win32_getenv() and win32_putenv() call GetEnvironmentVariableA() and
1680 * SetEnvironmentVariableA() directly, bypassing the CRT copy of the
1683 * (4) The CRT strftime() "%Z" implementation calls __tzset(). That
1684 * calls CRT tzset(), but only the first time it is called, and in turn
1685 * that uses CRT getenv("TZ") to retrieve the timezone info from the CRT
1686 * local copy of the environment and hence gets the original setting as
1687 * perl never updates the CRT copy when assigning to $ENV{TZ}.
1689 * Therefore, we need to retrieve the value of $ENV{TZ} and call CRT
1690 * putenv() to update the CRT copy of the environment (if it is different)
1691 * whenever we're about to call tzset().
1693 * In addition to all that, when perl is built with PERL_IMPLICIT_SYS
1696 * (a) Each interpreter has its own copy of the environment inside the
1697 * perlhost structure. That allows applications that host multiple
1698 * independent Perl interpreters to isolate environment changes from
1699 * each other. (This is similar to how the perlhost mechanism keeps a
1700 * separate working directory for each Perl interpreter, so that calling
1701 * chdir() will not affect other interpreters.)
1703 * (b) Only the first Perl interpreter instantiated within a process will
1704 * "write through" environment changes to the process environment.
1706 * (c) Even the primary Perl interpreter won't update the CRT copy of the
1707 * the environment, only the Win32API copy (it calls win32_putenv()).
1709 * As with CPerlHost::Getenv() and CPerlHost::Putenv() themselves, it makes
1710 * sense to only update the process environment when inside the main
1711 * interpreter, but we don't have access to CPerlHost's m_bTopLevel member
1712 * from here so we'll just have to check PL_curinterp instead.
1714 * Therefore, we can simply #undef getenv() and putenv() so that those names
1715 * always refer to the CRT functions, and explicitly call win32_getenv() to
1716 * access perl's %ENV.
1718 * We also #undef malloc() and free() to be sure we are using the CRT
1719 * functions otherwise under PERL_IMPLICIT_SYS they are redefined to calls
1720 * into VMem::Malloc() and VMem::Free() and all allocations will be freed
1721 * when the Perl interpreter is being destroyed so we'd end up with a pointer
1722 * into deallocated memory in environ[] if a program embedding a Perl
1723 * interpreter continues to operate even after the main Perl interpreter has
1726 * Note that we don't free() the malloc()ed memory unless and until we call
1727 * malloc() again ourselves because the CRT putenv() function simply puts its
1728 * pointer argument into the environ[] array (it doesn't make a copy of it)
1729 * so this memory must otherwise be leaked.
1738 fix_win32_tzenv(void)
1740 static char* oldenv = NULL;
1742 const char* perl_tz_env = win32_getenv("TZ");
1743 const char* crt_tz_env = getenv("TZ");
1744 if (perl_tz_env == NULL)
1746 if (crt_tz_env == NULL)
1748 if (strcmp(perl_tz_env, crt_tz_env) != 0) {
1749 newenv = (char*)malloc((strlen(perl_tz_env) + 4) * sizeof(char));
1750 if (newenv != NULL) {
1751 sprintf(newenv, "TZ=%s", perl_tz_env);
1763 * my_tzset - wrapper to tzset() with a fix to make it work (better) on Win32.
1764 * This code is duplicated in the Time-Piece module, so any changes made here
1765 * should be made there too.
1771 #if defined(USE_ITHREADS) && defined(PERL_IMPLICIT_SYS)
1772 if (PL_curinterp == aTHX)
1779 typedef int (*isfunc_t)(int);
1780 typedef void (*any_dptr_t)(void *);
1782 /* This needs to be ALIASed in a custom way, hence can't easily be defined as
1784 static XSPROTO(is_common); /* prototype to pass -Wmissing-prototypes */
1785 static XSPROTO(is_common)
1790 croak_xs_usage(cv, "charstring");
1795 /*int RETVAL = 0; YYY means uncomment this to return false on an
1796 * empty string input */
1798 unsigned char *s = (unsigned char *) SvPV(ST(0), len);
1799 unsigned char *e = s + len;
1800 isfunc_t isfunc = (isfunc_t) XSANY.any_dptr;
1802 if (ckWARN_d(WARN_DEPRECATED)) {
1804 /* Warn exactly once for each lexical place this function is
1805 * called. See thread at
1806 * http://markmail.org/thread/jhqcag5njmx7jpyu */
1808 HV *warned = get_hv("POSIX::_warned", GV_ADD | GV_ADDMULTI);
1809 if (! hv_exists(warned, (const char *)&PL_op, sizeof(PL_op))) {
1810 Perl_warner(aTHX_ packWARN(WARN_DEPRECATED),
1811 "Calling POSIX::%"HEKf"() is deprecated",
1812 HEKfARG(GvNAME_HEK(CvGV(cv))));
1813 (void)hv_store(warned, (const char *)&PL_op, sizeof(PL_op), &PL_sv_yes, 0);
1817 /*if (e > s) { YYY */
1818 for (RETVAL = 1; RETVAL && s < e; s++)
1828 MODULE = POSIX PACKAGE = POSIX
1835 /* silence compiler warning about not_here() defined but not used */
1836 if (0) not_here("");
1838 /* Ensure we get the function, not a macro implementation. Like the C89
1839 standard says we can... */
1841 cv = newXS_deffile("POSIX::isalnum", is_common);
1842 XSANY.any_dptr = (any_dptr_t) &isalnum;
1844 cv = newXS_deffile("POSIX::isalpha", is_common);
1845 XSANY.any_dptr = (any_dptr_t) &isalpha;
1847 cv = newXS_deffile("POSIX::iscntrl", is_common);
1848 XSANY.any_dptr = (any_dptr_t) &iscntrl;
1850 cv = newXS_deffile("POSIX::isdigit", is_common);
1851 XSANY.any_dptr = (any_dptr_t) &isdigit;
1853 cv = newXS_deffile("POSIX::isgraph", is_common);
1854 XSANY.any_dptr = (any_dptr_t) &isgraph;
1856 cv = newXS_deffile("POSIX::islower", is_common);
1857 XSANY.any_dptr = (any_dptr_t) &islower;
1859 cv = newXS_deffile("POSIX::isprint", is_common);
1860 XSANY.any_dptr = (any_dptr_t) &isprint;
1862 cv = newXS_deffile("POSIX::ispunct", is_common);
1863 XSANY.any_dptr = (any_dptr_t) &ispunct;
1865 cv = newXS_deffile("POSIX::isspace", is_common);
1866 XSANY.any_dptr = (any_dptr_t) &isspace;
1868 cv = newXS_deffile("POSIX::isupper", is_common);
1869 XSANY.any_dptr = (any_dptr_t) &isupper;
1871 cv = newXS_deffile("POSIX::isxdigit", is_common);
1872 XSANY.any_dptr = (any_dptr_t) &isxdigit;
1875 MODULE = SigSet PACKAGE = POSIX::SigSet PREFIX = sig
1878 new(packname = "POSIX::SigSet", ...)
1879 const char * packname
1884 = (sigset_t *) allocate_struct(aTHX_ (ST(0) = sv_newmortal()),
1888 for (i = 1; i < items; i++)
1889 sigaddset(s, SvIV(ST(i)));
1895 POSIX::SigSet sigset
1900 RETVAL = ix ? sigdelset(sigset, sig) : sigaddset(sigset, sig);
1906 POSIX::SigSet sigset
1910 RETVAL = ix ? sigfillset(sigset) : sigemptyset(sigset);
1915 sigismember(sigset, sig)
1916 POSIX::SigSet sigset
1919 MODULE = Termios PACKAGE = POSIX::Termios PREFIX = cf
1922 new(packname = "POSIX::Termios", ...)
1923 const char * packname
1927 void *const p = allocate_struct(aTHX_ (ST(0) = sv_newmortal()),
1928 sizeof(struct termios), packname);
1929 /* The previous implementation stored a pointer to an uninitialised
1930 struct termios. Seems safer to initialise it, particularly as
1931 this implementation exposes the struct to prying from perl-space.
1933 memset(p, 0, 1 + sizeof(struct termios));
1936 not_here("termios");
1941 getattr(termios_ref, fd = 0)
1942 POSIX::Termios termios_ref
1945 RETVAL = tcgetattr(fd, termios_ref);
1949 # If we define TCSANOW here then both a found and not found constant sub
1950 # are created causing a Constant subroutine TCSANOW redefined warning
1952 # define DEF_SETATTR_ACTION 0
1954 # define DEF_SETATTR_ACTION TCSANOW
1957 setattr(termios_ref, fd = 0, optional_actions = DEF_SETATTR_ACTION)
1958 POSIX::Termios termios_ref
1960 int optional_actions
1963 /* The second argument to the call is mandatory, but we'd like to give
1964 it a useful default. 0 isn't valid on all operating systems - on
1965 Solaris (at least) TCSANOW, TCSADRAIN and TCSAFLUSH have the same
1966 values as the equivalent ioctls, TCSETS, TCSETSW and TCSETSF. */
1967 if (optional_actions < 0) {
1968 SETERRNO(EINVAL, LIB_INVARG);
1971 RETVAL = tcsetattr(fd, optional_actions, termios_ref);
1974 SETERRNO(EBADF,RMS_IFI);
1981 getispeed(termios_ref)
1982 POSIX::Termios termios_ref
1986 RETVAL = ix ? cfgetospeed(termios_ref) : cfgetispeed(termios_ref);
1991 getiflag(termios_ref)
1992 POSIX::Termios termios_ref
1998 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
2001 RETVAL = termios_ref->c_iflag;
2004 RETVAL = termios_ref->c_oflag;
2007 RETVAL = termios_ref->c_cflag;
2010 RETVAL = termios_ref->c_lflag;
2013 RETVAL = 0; /* silence compiler warning */
2016 not_here(GvNAME(CvGV(cv)));
2023 getcc(termios_ref, ccix)
2024 POSIX::Termios termios_ref
2027 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
2029 croak("Bad getcc subscript");
2030 RETVAL = termios_ref->c_cc[ccix];
2039 setispeed(termios_ref, speed)
2040 POSIX::Termios termios_ref
2046 ? cfsetospeed(termios_ref, speed) : cfsetispeed(termios_ref, speed);
2051 setiflag(termios_ref, flag)
2052 POSIX::Termios termios_ref
2059 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
2062 termios_ref->c_iflag = flag;
2065 termios_ref->c_oflag = flag;
2068 termios_ref->c_cflag = flag;
2071 termios_ref->c_lflag = flag;
2075 not_here(GvNAME(CvGV(cv)));
2079 setcc(termios_ref, ccix, cc)
2080 POSIX::Termios termios_ref
2084 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
2086 croak("Bad setcc subscript");
2087 termios_ref->c_cc[ccix] = cc;
2093 MODULE = POSIX PACKAGE = POSIX
2095 INCLUDE: const-xs.inc
2101 POSIX::WIFEXITED = 1
2102 POSIX::WIFSIGNALED = 2
2103 POSIX::WIFSTOPPED = 3
2107 #if !defined(WEXITSTATUS) || !defined(WIFEXITED) || !defined(WIFSIGNALED) \
2108 || !defined(WIFSTOPPED) || !defined(WSTOPSIG) || !defined(WTERMSIG)
2109 RETVAL = 0; /* Silence compilers that notice this, but don't realise
2110 that not_here() can't return. */
2115 RETVAL = WEXITSTATUS(WMUNGE(status));
2117 not_here("WEXITSTATUS");
2122 RETVAL = WIFEXITED(WMUNGE(status));
2124 not_here("WIFEXITED");
2129 RETVAL = WIFSIGNALED(WMUNGE(status));
2131 not_here("WIFSIGNALED");
2136 RETVAL = WIFSTOPPED(WMUNGE(status));
2138 not_here("WIFSTOPPED");
2143 RETVAL = WSTOPSIG(WMUNGE(status));
2145 not_here("WSTOPSIG");
2150 RETVAL = WTERMSIG(WMUNGE(status));
2152 not_here("WTERMSIG");
2156 croak("Illegal alias %d for POSIX::W*", (int)ix);
2162 open(filename, flags = O_RDONLY, mode = 0666)
2167 if (flags & (O_APPEND|O_CREAT|O_TRUNC|O_RDWR|O_WRONLY|O_EXCL))
2168 TAINT_PROPER("open");
2169 RETVAL = open(filename, flags, mode);
2177 #ifndef HAS_LOCALECONV
2178 localeconv(); /* A stub to call not_here(). */
2180 struct lconv *lcbuf;
2182 /* localeconv() deals with both LC_NUMERIC and LC_MONETARY, but
2183 * LC_MONETARY is already in the correct locale */
2184 DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
2185 STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
2188 sv_2mortal((SV*)RETVAL);
2189 if ((lcbuf = localeconv())) {
2190 const struct lconv_offset *strings = lconv_strings;
2191 const struct lconv_offset *integers = lconv_integers;
2192 const char *ptr = (const char *) lcbuf;
2194 while (strings->name) {
2195 /* This string may be controlled by either LC_NUMERIC, or
2198 #if defined(USE_LOCALE_NUMERIC) && defined(USE_LOCALE_MONETARY)
2199 = _is_cur_LC_category_utf8((isLC_NUMERIC_STRING(strings->name))
2202 #elif defined(USE_LOCALE_NUMERIC)
2203 = _is_cur_LC_category_utf8(LC_NUMERIC);
2204 #elif defined(USE_LOCALE_MONETARY)
2205 = _is_cur_LC_category_utf8(LC_MONETARY);
2210 const char *value = *((const char **)(ptr + strings->offset));
2212 if (value && *value) {
2213 (void) hv_store(RETVAL,
2215 strlen(strings->name),
2216 newSVpvn_utf8(value,
2219 /* We mark it as UTF-8 if a utf8 locale
2220 * and is valid and variant under UTF-8 */
2222 && ! is_invariant_string((U8 *) value, 0)
2223 && is_utf8_string((U8 *) value, 0)),
2229 while (integers->name) {
2230 const char value = *((const char *)(ptr + integers->offset));
2232 if (value != CHAR_MAX)
2233 (void) hv_store(RETVAL, integers->name,
2234 strlen(integers->name), newSViv(value), 0);
2238 RESTORE_LC_NUMERIC_STANDARD();
2239 #endif /* HAS_LOCALECONV */
2244 setlocale(category, locale = 0)
2250 #ifdef USE_LOCALE_NUMERIC
2251 /* A 0 (or NULL) locale means only query what the current one is. We
2252 * have the LC_NUMERIC name saved, because we are normally switched
2253 * into the C locale for it. Switch back so an LC_ALL query will yield
2254 * the correct results; all other categories don't require special
2257 if (category == LC_NUMERIC) {
2258 XSRETURN_PV(PL_numeric_name);
2261 else if (category == LC_ALL) {
2262 SET_NUMERIC_UNDERLYING();
2267 #ifdef WIN32 /* Use wrapper on Windows */
2268 retval = Perl_my_setlocale(aTHX_ category, locale);
2270 retval = setlocale(category, locale);
2272 DEBUG_L(PerlIO_printf(Perl_debug_log,
2273 "%s:%d: %s\n", __FILE__, __LINE__,
2274 _setlocale_debug_string(category, locale, retval)));
2276 /* Should never happen that a query would return an error, but be
2277 * sure and reset to C locale */
2279 SET_NUMERIC_STANDARD();
2284 /* Save retval since subsequent setlocale() calls may overwrite it. */
2285 retval = savepv(retval);
2287 /* For locale == 0, we may have switched to NUMERIC_UNDERLYING. Switch
2290 SET_NUMERIC_STANDARD();
2291 XSRETURN_PV(retval);
2295 #ifdef USE_LOCALE_CTYPE
2296 if (category == LC_CTYPE
2298 || category == LC_ALL
2304 if (category == LC_ALL) {
2305 newctype = setlocale(LC_CTYPE, NULL);
2306 DEBUG_Lv(PerlIO_printf(Perl_debug_log,
2307 "%s:%d: %s\n", __FILE__, __LINE__,
2308 _setlocale_debug_string(LC_CTYPE, NULL, newctype)));
2313 new_ctype(newctype);
2315 #endif /* USE_LOCALE_CTYPE */
2316 #ifdef USE_LOCALE_COLLATE
2317 if (category == LC_COLLATE
2319 || category == LC_ALL
2325 if (category == LC_ALL) {
2326 newcoll = setlocale(LC_COLLATE, NULL);
2327 DEBUG_Lv(PerlIO_printf(Perl_debug_log,
2328 "%s:%d: %s\n", __FILE__, __LINE__,
2329 _setlocale_debug_string(LC_COLLATE, NULL, newcoll)));
2334 new_collate(newcoll);
2336 #endif /* USE_LOCALE_COLLATE */
2337 #ifdef USE_LOCALE_NUMERIC
2338 if (category == LC_NUMERIC
2340 || category == LC_ALL
2346 if (category == LC_ALL) {
2347 newnum = setlocale(LC_NUMERIC, NULL);
2348 DEBUG_Lv(PerlIO_printf(Perl_debug_log,
2349 "%s:%d: %s\n", __FILE__, __LINE__,
2350 _setlocale_debug_string(LC_NUMERIC, NULL, newnum)));
2355 new_numeric(newnum);
2357 #endif /* USE_LOCALE_NUMERIC */
2403 RETVAL = Perl_acos(x); /* C89 math */
2407 RETVAL = c99_acosh(x);
2413 RETVAL = Perl_asin(x); /* C89 math */
2417 RETVAL = c99_asinh(x);
2423 RETVAL = Perl_atan(x); /* C89 math */
2427 RETVAL = c99_atanh(x);
2434 RETVAL = c99_cbrt(x);
2440 RETVAL = Perl_ceil(x); /* C89 math */
2443 RETVAL = Perl_cosh(x); /* C89 math */
2447 RETVAL = c99_erf(x);
2454 RETVAL = c99_erfc(x);
2461 RETVAL = c99_exp2(x);
2468 RETVAL = c99_expm1(x);
2474 RETVAL = Perl_floor(x); /* C89 math */
2478 RETVAL = bessel_j0(x);
2485 RETVAL = bessel_j1(x);
2491 /* XXX Note: the lgamma modifies a global variable (signgam),
2492 * which is evil. Some platforms have lgamma_r, which has
2493 * extra output parameter instead of the global variable. */
2495 RETVAL = c99_lgamma(x);
2501 RETVAL = log10(x); /* C89 math */
2505 RETVAL = c99_log1p(x);
2512 RETVAL = c99_log2(x);
2519 RETVAL = c99_logb(x);
2520 #elif defined(c99_log2) && FLT_RADIX == 2
2521 RETVAL = Perl_floor(c99_log2(PERL_ABS(x)));
2527 #ifdef c99_nearbyint
2528 RETVAL = c99_nearbyint(x);
2530 not_here("nearbyint");
2535 RETVAL = c99_rint(x);
2542 RETVAL = c99_round(x);
2548 RETVAL = Perl_sinh(x); /* C89 math */
2551 RETVAL = Perl_tan(x); /* C89 math */
2554 RETVAL = Perl_tanh(x); /* C89 math */
2558 RETVAL = c99_tgamma(x);
2565 RETVAL = c99_trunc(x);
2572 RETVAL = bessel_y0(x);
2580 RETVAL = bessel_y1(x);
2591 #ifdef HAS_FEGETROUND
2592 RETVAL = my_fegetround();
2595 not_here("fegetround");
2604 #ifdef HAS_FEGETROUND /* canary for fesetround */
2605 RETVAL = fesetround(x);
2606 #elif defined(HAS_FPGETROUND) /* canary for fpsetround */
2608 case FE_TONEAREST: RETVAL = fpsetround(FP_RN); break;
2609 case FE_TOWARDZERO: RETVAL = fpsetround(FP_RZ); break;
2610 case FE_DOWNWARD: RETVAL = fpsetround(FP_RM); break;
2611 case FE_UPWARD: RETVAL = fpsetround(FP_RP); break;
2612 default: RETVAL = -1; break;
2614 #elif defined(__osf__) /* Tru64 */
2616 case FE_TONEAREST: RETVAL = write_rnd(FP_RND_RN); break;
2617 case FE_TOWARDZERO: RETVAL = write_rnd(FP_RND_RZ); break;
2618 case FE_DOWNWARD: RETVAL = write_rnd(FP_RND_RM); break;
2619 case FE_UPWARD: RETVAL = write_rnd(FP_RND_RP); break;
2620 default: RETVAL = -1; break;
2625 not_here("fesetround");
2647 #ifdef c99_fpclassify
2648 RETVAL = c99_fpclassify(x);
2650 not_here("fpclassify");
2655 RETVAL = c99_ilogb(x);
2661 RETVAL = Perl_isfinite(x);
2664 RETVAL = Perl_isinf(x);
2667 RETVAL = Perl_isnan(x);
2671 RETVAL = c99_isnormal(x);
2673 not_here("isnormal");
2678 RETVAL = c99_lrint(x);
2685 RETVAL = c99_lround(x);
2693 RETVAL = Perl_signbit(x);
2695 RETVAL = (x < 0) || (x == -0.0);
2706 RETVAL = S_getpayload(nv);
2711 setpayload(nv, payload)
2715 S_setpayload(&nv, payload, FALSE);
2720 setpayloadsig(nv, payload)
2725 S_setpayload(&nv, payload, TRUE);
2733 RETVAL = Perl_isnan(nv) && NV_NAN_IS_SIGNALING(&nv);
2763 RETVAL = c99_copysign(x, y);
2765 not_here("copysign");
2770 RETVAL = c99_fdim(x, y);
2777 RETVAL = c99_fmax(x, y);
2784 RETVAL = c99_fmin(x, y);
2790 RETVAL = Perl_fmod(x, y); /* C89 math */
2794 RETVAL = c99_hypot(x, y);
2800 #ifdef c99_isgreater
2801 RETVAL = c99_isgreater(x, y);
2803 not_here("isgreater");
2807 #ifdef c99_isgreaterequal
2808 RETVAL = c99_isgreaterequal(x, y);
2810 not_here("isgreaterequal");
2815 RETVAL = c99_isless(x, y);
2821 #ifdef c99_islessequal
2822 RETVAL = c99_islessequal(x, y);
2824 not_here("islessequal");
2828 #ifdef c99_islessgreater
2829 RETVAL = c99_islessgreater(x, y);
2831 not_here("islessgreater");
2835 #ifdef c99_isunordered
2836 RETVAL = c99_isunordered(x, y);
2838 not_here("isunordered");
2842 #ifdef c99_nextafter
2843 RETVAL = c99_nextafter(x, y);
2845 not_here("nextafter");
2849 #ifdef c99_nexttoward
2850 RETVAL = c99_nexttoward(x, y);
2852 not_here("nexttoward");
2857 #ifdef c99_remainder
2858 RETVAL = c99_remainder(x, y);
2860 not_here("remainder");
2872 /* (We already know stack is long enough.) */
2873 PUSHs(sv_2mortal(newSVnv(Perl_frexp(x,&expvar)))); /* C89 math */
2874 PUSHs(sv_2mortal(newSViv(expvar)));
2886 /* (We already know stack is long enough.) */
2887 PUSHs(sv_2mortal(newSVnv(Perl_modf(x,&intvar)))); /* C89 math */
2888 PUSHs(sv_2mortal(newSVnv(intvar)));
2897 PUSHs(sv_2mortal(newSVnv(c99_remquo(x,y,&intvar))));
2898 PUSHs(sv_2mortal(newSVnv(intvar)));
2911 RETVAL = c99_scalbn(x, y);
2931 RETVAL = c99_fma(x, y, z);
2941 /* If no payload given, just return the default NaN.
2942 * This makes a difference in platforms where the default
2943 * NaN is not all zeros. */
2947 S_setpayload(&RETVAL, payload, FALSE);
2949 #elif defined(c99_nan)
2951 STRLEN elen = my_snprintf(PL_efloatbuf, PL_efloatsize, "%g", nv);
2952 if ((IV)elen == -1) {
2955 RETVAL = c99_nan(PL_efloatbuf);
2977 RETVAL = bessel_jn(x, y);
2985 RETVAL = bessel_yn(x, y);
2995 sigaction(sig, optaction, oldaction = 0)
2998 POSIX::SigAction oldaction
3000 #if defined(WIN32) || defined(NETWARE) || (defined(__amigaos4__) && defined(__NEWLIB__))
3001 RETVAL = not_here("sigaction");
3003 # This code is really grody because we're trying to make the signal
3004 # interface look beautiful, which is hard.
3008 POSIX__SigAction action;
3009 GV *siggv = gv_fetchpvs("SIG", GV_ADD, SVt_PVHV);
3010 struct sigaction act;
3011 struct sigaction oact;
3015 POSIX__SigSet sigset;
3020 croak("Negative signals are not allowed");
3023 if (sig == 0 && SvPOK(ST(0))) {
3024 const char *s = SvPVX_const(ST(0));
3025 int i = whichsig(s);
3027 if (i < 0 && memEQ(s, "SIG", 3))
3028 i = whichsig(s + 3);
3030 if (ckWARN(WARN_SIGNAL))
3031 Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
3032 "No such signal: SIG%s", s);
3039 if (sig > NSIG) { /* NSIG - 1 is still okay. */
3040 Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
3041 "No such signal: %d", sig);
3045 sigsvp = hv_fetch(GvHVn(siggv),
3047 strlen(PL_sig_name[sig]),
3050 /* Check optaction and set action */
3051 if(SvTRUE(optaction)) {
3052 if(sv_isa(optaction, "POSIX::SigAction"))
3053 action = (HV*)SvRV(optaction);
3055 croak("action is not of type POSIX::SigAction");
3061 /* sigaction() is supposed to look atomic. In particular, any
3062 * signal handler invoked during a sigaction() call should
3063 * see either the old or the new disposition, and not something
3064 * in between. We use sigprocmask() to make it so.
3067 RETVAL=sigprocmask(SIG_BLOCK, &sset, &osset);
3071 /* Restore signal mask no matter how we exit this block. */
3072 osset_sv = newSVpvn((char *)(&osset), sizeof(sigset_t));
3073 SAVEFREESV( osset_sv );
3074 SAVEDESTRUCTOR_X(restore_sigmask, osset_sv);
3076 RETVAL=-1; /* In case both oldaction and action are 0. */
3078 /* Remember old disposition if desired. */
3080 svp = hv_fetchs(oldaction, "HANDLER", TRUE);
3082 croak("Can't supply an oldaction without a HANDLER");
3083 if(SvTRUE(*sigsvp)) { /* TBD: what if "0"? */
3084 sv_setsv(*svp, *sigsvp);
3087 sv_setpvs(*svp, "DEFAULT");
3089 RETVAL = sigaction(sig, (struct sigaction *)0, & oact);
3094 /* Get back the mask. */
3095 svp = hv_fetchs(oldaction, "MASK", TRUE);
3096 if (sv_isa(*svp, "POSIX::SigSet")) {
3097 sigset = (sigset_t *) SvPV_nolen(SvRV(*svp));
3100 sigset = (sigset_t *) allocate_struct(aTHX_ *svp,
3104 *sigset = oact.sa_mask;
3106 /* Get back the flags. */
3107 svp = hv_fetchs(oldaction, "FLAGS", TRUE);
3108 sv_setiv(*svp, oact.sa_flags);
3110 /* Get back whether the old handler used safe signals. */
3111 svp = hv_fetchs(oldaction, "SAFE", TRUE);
3113 /* compare incompatible pointers by casting to integer */
3114 PTR2nat(oact.sa_handler) == PTR2nat(PL_csighandlerp));
3118 /* Safe signals use "csighandler", which vectors through the
3119 PL_sighandlerp pointer when it's safe to do so.
3120 (BTW, "csighandler" is very different from "sighandler".) */
3121 svp = hv_fetchs(action, "SAFE", FALSE);
3125 (*svp && SvTRUE(*svp))
3126 ? PL_csighandlerp : PL_sighandlerp
3129 /* Vector new Perl handler through %SIG.
3130 (The core signal handlers read %SIG to dispatch.) */
3131 svp = hv_fetchs(action, "HANDLER", FALSE);
3133 croak("Can't supply an action without a HANDLER");
3134 sv_setsv(*sigsvp, *svp);
3136 /* This call actually calls sigaction() with almost the
3137 right settings, including appropriate interpretation
3138 of DEFAULT and IGNORE. However, why are we doing
3139 this when we're about to do it again just below? XXX */
3140 SvSETMAGIC(*sigsvp);
3142 /* And here again we duplicate -- DEFAULT/IGNORE checking. */
3144 const char *s=SvPVX_const(*svp);
3145 if(strEQ(s,"IGNORE")) {
3146 act.sa_handler = SIG_IGN;
3148 else if(strEQ(s,"DEFAULT")) {
3149 act.sa_handler = SIG_DFL;
3153 /* Set up any desired mask. */
3154 svp = hv_fetchs(action, "MASK", FALSE);
3155 if (svp && sv_isa(*svp, "POSIX::SigSet")) {
3156 sigset = (sigset_t *) SvPV_nolen(SvRV(*svp));
3157 act.sa_mask = *sigset;
3160 sigemptyset(& act.sa_mask);
3162 /* Set up any desired flags. */
3163 svp = hv_fetchs(action, "FLAGS", FALSE);
3164 act.sa_flags = svp ? SvIV(*svp) : 0;
3166 /* Don't worry about cleaning up *sigsvp if this fails,
3167 * because that means we tried to disposition a
3168 * nonblockable signal, in which case *sigsvp is
3169 * essentially meaningless anyway.
3171 RETVAL = sigaction(sig, & act, (struct sigaction *)0);
3186 POSIX::SigSet sigset
3191 RETVAL = not_here("sigpending");
3193 RETVAL = ix ? sigsuspend(sigset) : sigpending(sigset);
3201 sigprocmask(how, sigset, oldsigset = 0)
3203 POSIX::SigSet sigset = NO_INIT
3204 POSIX::SigSet oldsigset = NO_INIT
3206 if (! SvOK(ST(1))) {
3208 } else if (sv_isa(ST(1), "POSIX::SigSet")) {
3209 sigset = (sigset_t *) SvPV_nolen(SvRV(ST(1)));
3211 croak("sigset is not of type POSIX::SigSet");
3214 if (items < 3 || ! SvOK(ST(2))) {
3216 } else if (sv_isa(ST(2), "POSIX::SigSet")) {
3217 oldsigset = (sigset_t *) SvPV_nolen(SvRV(ST(2)));
3219 croak("oldsigset is not of type POSIX::SigSet");
3231 if (fd1 >= 0 && fd2 >= 0) {
3233 /* RT #98912 - More Microsoft muppetry - failing to
3234 actually implemented the well known documented POSIX
3235 behaviour for a POSIX API.
3236 http://msdn.microsoft.com/en-us/library/8syseb29.aspx */
3237 RETVAL = dup2(fd1, fd2) == -1 ? -1 : fd2;
3239 RETVAL = dup2(fd1, fd2);
3242 SETERRNO(EBADF,RMS_IFI);
3249 lseek(fd, offset, whence)
3255 Off_t pos = PerlLIO_lseek(fd, offset, whence);
3256 RETVAL = sizeof(Off_t) > sizeof(IV)
3257 ? newSVnv((NV)pos) : newSViv((IV)pos);
3259 SETERRNO(EBADF,RMS_IFI);
3260 RETVAL = newSViv(-1);
3270 if ((incr = nice(incr)) != -1 || errno == 0) {
3272 XPUSHs(newSVpvs_flags("0 but true", SVs_TEMP));
3274 XPUSHs(sv_2mortal(newSViv(incr)));
3281 if (pipe(fds) != -1) {
3283 PUSHs(sv_2mortal(newSViv(fds[0])));
3284 PUSHs(sv_2mortal(newSViv(fds[1])));
3288 read(fd, buffer, nbytes)
3290 SV *sv_buffer = SvROK(ST(1)) ? SvRV(ST(1)) : ST(1);
3294 char * buffer = sv_grow( sv_buffer, nbytes+1 );
3297 SvCUR_set(sv_buffer, RETVAL);
3298 SvPOK_only(sv_buffer);
3299 *SvEND(sv_buffer) = '\0';
3300 SvTAINTED_on(sv_buffer);
3316 tcsetpgrp(fd, pgrp_id)
3325 if (uname(&buf) >= 0) {
3327 PUSHs(newSVpvn_flags(buf.sysname, strlen(buf.sysname), SVs_TEMP));
3328 PUSHs(newSVpvn_flags(buf.nodename, strlen(buf.nodename), SVs_TEMP));
3329 PUSHs(newSVpvn_flags(buf.release, strlen(buf.release), SVs_TEMP));
3330 PUSHs(newSVpvn_flags(buf.version, strlen(buf.version), SVs_TEMP));
3331 PUSHs(newSVpvn_flags(buf.machine, strlen(buf.machine), SVs_TEMP));
3334 uname((char *) 0); /* A stub to call not_here(). */
3338 write(fd, buffer, nbytes)
3349 RETVAL = newSVpvs("");
3350 SvGROW(RETVAL, L_tmpnam);
3351 /* Yes, we know tmpnam() is bad. So bad that some compilers
3352 * and linkers warn against using it. But it is here for
3353 * completeness. POSIX.pod warns against using it.
3355 * Then again, maybe this should be removed at some point.
3356 * No point in enabling dangerous interfaces. */
3357 if (ckWARN_d(WARN_DEPRECATED)) {
3358 HV *warned = get_hv("POSIX::_warned", GV_ADD | GV_ADDMULTI);
3359 if (! hv_exists(warned, (const char *)&PL_op, sizeof(PL_op))) {
3360 Perl_warner(aTHX_ packWARN(WARN_DEPRECATED), "Calling POSIX::tmpnam() is deprecated");
3361 (void)hv_store(warned, (const char *)&PL_op, sizeof(PL_op), &PL_sv_yes, 0);
3364 len = strlen(tmpnam(SvPV(RETVAL, i)));
3365 SvCUR_set(RETVAL, len);
3378 mbstowcs(s, pwcs, n)
3390 wcstombs(s, pwcs, n)
3412 DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
3413 STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
3414 num = strtod(str, &unparsed);
3415 PUSHs(sv_2mortal(newSVnv(num)));
3416 if (GIMME_V == G_ARRAY) {
3419 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3421 PUSHs(&PL_sv_undef);
3423 RESTORE_LC_NUMERIC_STANDARD();
3434 DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
3435 STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
3436 num = strtold(str, &unparsed);
3437 PUSHs(sv_2mortal(newSVnv(num)));
3438 if (GIMME_V == G_ARRAY) {
3441 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3443 PUSHs(&PL_sv_undef);
3445 RESTORE_LC_NUMERIC_STANDARD();
3450 strtol(str, base = 0)
3457 if (base == 0 || (base >= 2 && base <= 36)) {
3458 num = strtol(str, &unparsed, base);
3459 #if IVSIZE < LONGSIZE
3460 if (num < IV_MIN || num > IV_MAX)
3461 PUSHs(sv_2mortal(newSVnv((double)num)));
3464 PUSHs(sv_2mortal(newSViv((IV)num)));
3465 if (GIMME_V == G_ARRAY) {
3468 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3470 PUSHs(&PL_sv_undef);
3473 SETERRNO(EINVAL, LIB_INVARG);
3474 PUSHs(&PL_sv_undef);
3475 if (GIMME_V == G_ARRAY) {
3477 PUSHs(&PL_sv_undef);
3482 strtoul(str, base = 0)
3489 PERL_UNUSED_VAR(str);
3490 PERL_UNUSED_VAR(base);
3491 if (base == 0 || (base >= 2 && base <= 36)) {
3492 num = strtoul(str, &unparsed, base);
3493 #if IVSIZE <= LONGSIZE
3495 PUSHs(sv_2mortal(newSVnv((double)num)));
3498 PUSHs(sv_2mortal(newSViv((IV)num)));
3499 if (GIMME_V == G_ARRAY) {
3502 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3504 PUSHs(&PL_sv_undef);
3507 SETERRNO(EINVAL, LIB_INVARG);
3508 PUSHs(&PL_sv_undef);
3509 if (GIMME_V == G_ARRAY) {
3511 PUSHs(&PL_sv_undef);
3523 char *p = SvPV(src,srclen);
3525 buflen = srclen * 4 + 1;
3526 ST(0) = sv_2mortal(newSV(buflen));
3527 dstlen = strxfrm(SvPVX(ST(0)), p, (size_t)buflen);
3528 if (dstlen >= buflen) {
3530 SvGROW(ST(0), dstlen);
3531 strxfrm(SvPVX(ST(0)), p, (size_t)dstlen);
3534 SvCUR_set(ST(0), dstlen);
3539 mkfifo(filename, mode)
3546 RETVAL = access(filename, mode);
3548 TAINT_PROPER("mkfifo");
3549 RETVAL = mkfifo(filename, mode);
3562 RETVAL = ix == 1 ? close(fd)
3563 : (ix < 1 ? tcdrain(fd) : dup(fd));
3565 SETERRNO(EBADF,RMS_IFI);
3580 if (fd >= 0 && action >= 0) {
3581 RETVAL = ix == 1 ? tcflush(fd, action)
3582 : (ix < 1 ? tcflow(fd, action) : tcsendbreak(fd, action));
3584 SETERRNO(EBADF,RMS_IFI);
3591 asctime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = -1)
3607 init_tm(&mytm); /* XXX workaround - see init_tm() in core util.c */
3610 mytm.tm_hour = hour;
3611 mytm.tm_mday = mday;
3613 mytm.tm_year = year;
3614 mytm.tm_wday = wday;
3615 mytm.tm_yday = yday;
3616 mytm.tm_isdst = isdst;
3618 const time_t result = mktime(&mytm);
3619 if (result == (time_t)-1)
3621 else if (result == 0)
3622 sv_setpvn(TARG, "0 but true", 10);
3624 sv_setiv(TARG, (IV)result);
3626 sv_setpv(TARG, asctime(&mytm));
3644 realtime = times( &tms );
3646 PUSHs( sv_2mortal( newSViv( (IV) realtime ) ) );
3647 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_utime ) ) );
3648 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_stime ) ) );
3649 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cutime ) ) );
3650 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cstime ) ) );
3653 difftime(time1, time2)
3657 #XXX: if $xsubpp::WantOptimize is always the default
3658 # sv_setpv(TARG, ...) could be used rather than
3659 # ST(0) = sv_2mortal(newSVpv(...))
3661 strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1)
3677 /* allowing user-supplied (rather than literal) formats
3678 * is normally frowned upon as a potential security risk;
3679 * but this is part of the API so we have to allow it */
3680 GCC_DIAG_IGNORE(-Wformat-nonliteral);
3681 buf = my_strftime(SvPV_nolen(fmt), sec, min, hour, mday, mon, year, wday, yday, isdst);
3683 sv = sv_newmortal();
3685 STRLEN len = strlen(buf);
3686 sv_usepvn_flags(sv, buf, len, SV_HAS_TRAILING_NUL);
3688 || (! is_invariant_string((U8*) buf, len)
3689 && is_utf8_string((U8*) buf, len)
3690 #ifdef USE_LOCALE_TIME
3691 && _is_cur_LC_category_utf8(LC_TIME)
3697 else { /* We can't distinguish between errors and just an empty
3698 * return; in all cases just return an empty string */
3699 SvUPGRADE(sv, SVt_PV);
3700 SvPV_set(sv, (char *) "");
3703 SvLEN_set(sv, 0); /* Won't attempt to free the string when sv
3718 PUSHs(newSVpvn_flags(tzname[0], strlen(tzname[0]), SVs_TEMP));
3719 PUSHs(newSVpvn_flags(tzname[1], strlen(tzname[1]), SVs_TEMP));
3725 #ifdef HAS_CTERMID_R
3726 s = (char *) safemalloc((size_t) L_ctermid);
3728 RETVAL = ctermid(s);
3732 #ifdef HAS_CTERMID_R
3741 RETVAL = cuserid(s);
3745 not_here("cuserid");
3756 pathconf(filename, name)
3767 unsigned int seconds
3769 RETVAL = PerlProc_sleep(seconds);
3795 XSprePUSH; PUSHTARG;
3799 lchown(uid, gid, path)
3805 /* yes, the order of arguments is different,
3806 * but consistent with CORE::chown() */
3807 RETVAL = lchown(path, uid, gid);
3809 PERL_UNUSED_VAR(uid);
3810 PERL_UNUSED_VAR(gid);
3811 PERL_UNUSED_VAR(path);
3812 RETVAL = not_here("lchown");