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 #if defined(USE_LONG_DOUBLE) && defined(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;
1398 typedef int POSIX__SigNo;
1399 typedef int POSIX__Fd;
1401 typedef struct termios* POSIX__Termios;
1402 #else /* Define termios types to int, and call not_here for the functions.*/
1403 #define POSIX__Termios int
1405 #define tcflag_t int
1407 #define cfgetispeed(x) not_here("cfgetispeed")
1408 #define cfgetospeed(x) not_here("cfgetospeed")
1409 #define tcdrain(x) not_here("tcdrain")
1410 #define tcflush(x,y) not_here("tcflush")
1411 #define tcsendbreak(x,y) not_here("tcsendbreak")
1412 #define cfsetispeed(x,y) not_here("cfsetispeed")
1413 #define cfsetospeed(x,y) not_here("cfsetospeed")
1414 #define ctermid(x) (char *) not_here("ctermid")
1415 #define tcflow(x,y) not_here("tcflow")
1416 #define tcgetattr(x,y) not_here("tcgetattr")
1417 #define tcsetattr(x,y,z) not_here("tcsetattr")
1420 /* Possibly needed prototypes */
1423 double strtod (const char *, char **);
1424 long strtol (const char *, char **, int);
1425 unsigned long strtoul (const char *, char **, int);
1427 long double strtold (const char *, char **);
1432 #ifndef HAS_DIFFTIME
1434 #define difftime(a,b) not_here("difftime")
1437 #ifndef HAS_FPATHCONF
1438 #define fpathconf(f,n) (SysRetLong) not_here("fpathconf")
1441 #define mktime(a) not_here("mktime")
1444 #define nice(a) not_here("nice")
1446 #ifndef HAS_PATHCONF
1447 #define pathconf(f,n) (SysRetLong) not_here("pathconf")
1450 #define sysconf(n) (SysRetLong) not_here("sysconf")
1452 #ifndef HAS_READLINK
1453 #define readlink(a,b,c) not_here("readlink")
1456 #define setpgid(a,b) not_here("setpgid")
1459 #define setsid() not_here("setsid")
1462 #define strcoll(s1,s2) not_here("strcoll")
1465 #define strtod(s1,s2) not_here("strtod")
1468 #define strtold(s1,s2) not_here("strtold")
1471 #define strtol(s1,s2,b) not_here("strtol")
1474 #define strtoul(s1,s2,b) not_here("strtoul")
1477 #define strxfrm(s1,s2,n) not_here("strxfrm")
1479 #ifndef HAS_TCGETPGRP
1480 #define tcgetpgrp(a) not_here("tcgetpgrp")
1482 #ifndef HAS_TCSETPGRP
1483 #define tcsetpgrp(a,b) not_here("tcsetpgrp")
1487 #define times(a) not_here("times")
1488 #endif /* NETWARE */
1491 #define uname(a) not_here("uname")
1494 #define waitpid(a,b,c) not_here("waitpid")
1499 #define mblen(a,b) not_here("mblen")
1502 #ifndef HAS_MBSTOWCS
1503 #define mbstowcs(s, pwcs, n) not_here("mbstowcs")
1506 #define mbtowc(pwc, s, n) not_here("mbtowc")
1508 #ifndef HAS_WCSTOMBS
1509 #define wcstombs(s, pwcs, n) not_here("wcstombs")
1512 #define wctomb(s, wchar) not_here("wcstombs")
1514 #if !defined(HAS_MBLEN) && !defined(HAS_MBSTOWCS) && !defined(HAS_MBTOWC) && !defined(HAS_WCSTOMBS) && !defined(HAS_WCTOMB)
1515 /* If we don't have these functions, then we wouldn't have gotten a typedef
1516 for wchar_t, the wide character type. Defining wchar_t allows the
1517 functions referencing it to compile. Its actual type is then meaningless,
1518 since without the above functions, all sections using it end up calling
1519 not_here() and croak. --Kaveh Ghazi (ghazi@noc.rutgers.edu) 9/18/94. */
1521 #define wchar_t char
1525 #ifndef HAS_LOCALECONV
1526 # define localeconv() not_here("localeconv")
1528 struct lconv_offset {
1533 static const struct lconv_offset lconv_strings[] = {
1534 #ifdef USE_LOCALE_NUMERIC
1535 {"decimal_point", STRUCT_OFFSET(struct lconv, decimal_point)},
1536 {"thousands_sep", STRUCT_OFFSET(struct lconv, thousands_sep)},
1537 # ifndef NO_LOCALECONV_GROUPING
1538 {"grouping", STRUCT_OFFSET(struct lconv, grouping)},
1541 #ifdef USE_LOCALE_MONETARY
1542 {"int_curr_symbol", STRUCT_OFFSET(struct lconv, int_curr_symbol)},
1543 {"currency_symbol", STRUCT_OFFSET(struct lconv, currency_symbol)},
1544 {"mon_decimal_point", STRUCT_OFFSET(struct lconv, mon_decimal_point)},
1545 # ifndef NO_LOCALECONV_MON_THOUSANDS_SEP
1546 {"mon_thousands_sep", STRUCT_OFFSET(struct lconv, mon_thousands_sep)},
1548 # ifndef NO_LOCALECONV_MON_GROUPING
1549 {"mon_grouping", STRUCT_OFFSET(struct lconv, mon_grouping)},
1551 {"positive_sign", STRUCT_OFFSET(struct lconv, positive_sign)},
1552 {"negative_sign", STRUCT_OFFSET(struct lconv, negative_sign)},
1557 #ifdef USE_LOCALE_NUMERIC
1559 /* The Linux man pages say these are the field names for the structure
1560 * components that are LC_NUMERIC; the rest being LC_MONETARY */
1561 # define isLC_NUMERIC_STRING(name) (strEQ(name, "decimal_point") \
1562 || strEQ(name, "thousands_sep") \
1564 /* There should be no harm done \
1565 * checking for this, even if \
1566 * NO_LOCALECONV_GROUPING */ \
1567 || strEQ(name, "grouping"))
1569 # define isLC_NUMERIC_STRING(name) (0)
1572 static const struct lconv_offset lconv_integers[] = {
1573 #ifdef USE_LOCALE_MONETARY
1574 {"int_frac_digits", STRUCT_OFFSET(struct lconv, int_frac_digits)},
1575 {"frac_digits", STRUCT_OFFSET(struct lconv, frac_digits)},
1576 {"p_cs_precedes", STRUCT_OFFSET(struct lconv, p_cs_precedes)},
1577 {"p_sep_by_space", STRUCT_OFFSET(struct lconv, p_sep_by_space)},
1578 {"n_cs_precedes", STRUCT_OFFSET(struct lconv, n_cs_precedes)},
1579 {"n_sep_by_space", STRUCT_OFFSET(struct lconv, n_sep_by_space)},
1580 {"p_sign_posn", STRUCT_OFFSET(struct lconv, p_sign_posn)},
1581 {"n_sign_posn", STRUCT_OFFSET(struct lconv, n_sign_posn)},
1582 #ifdef HAS_LC_MONETARY_2008
1583 {"int_p_cs_precedes", STRUCT_OFFSET(struct lconv, int_p_cs_precedes)},
1584 {"int_p_sep_by_space", STRUCT_OFFSET(struct lconv, int_p_sep_by_space)},
1585 {"int_n_cs_precedes", STRUCT_OFFSET(struct lconv, int_n_cs_precedes)},
1586 {"int_n_sep_by_space", STRUCT_OFFSET(struct lconv, int_n_sep_by_space)},
1587 {"int_p_sign_posn", STRUCT_OFFSET(struct lconv, int_p_sign_posn)},
1588 {"int_n_sign_posn", STRUCT_OFFSET(struct lconv, int_n_sign_posn)},
1594 #endif /* HAS_LOCALECONV */
1596 #ifdef HAS_LONG_DOUBLE
1597 # if LONG_DOUBLESIZE > NVSIZE
1598 # undef HAS_LONG_DOUBLE /* XXX until we figure out how to use them */
1602 #ifndef HAS_LONG_DOUBLE
1614 /* Background: in most systems the low byte of the wait status
1615 * is the signal (the lowest 7 bits) and the coredump flag is
1616 * the eight bit, and the second lowest byte is the exit status.
1617 * BeOS bucks the trend and has the bytes in different order.
1618 * See beos/beos.c for how the reality is bent even in BeOS
1619 * to follow the traditional. However, to make the POSIX
1620 * wait W*() macros to work in BeOS, we need to unbend the
1621 * reality back in place. --jhi */
1622 /* In actual fact the code below is to blame here. Perl has an internal
1623 * representation of the exit status ($?), which it re-composes from the
1624 * OS's representation using the W*() POSIX macros. The code below
1625 * incorrectly uses the W*() macros on the internal representation,
1626 * which fails for OSs that have a different representation (namely BeOS
1627 * and Haiku). WMUNGE() is a hack that converts the internal
1628 * representation into the OS specific one, so that the W*() macros work
1629 * as expected. The better solution would be not to use the W*() macros
1630 * in the first place, though. -- Ingo Weinhold
1632 #if defined(__HAIKU__)
1633 # define WMUNGE(x) (((x) & 0xFF00) >> 8 | ((x) & 0x00FF) << 8)
1635 # define WMUNGE(x) (x)
1639 not_here(const char *s)
1641 croak("POSIX::%s not implemented on this architecture", s);
1645 #include "const-c.inc"
1648 restore_sigmask(pTHX_ SV *osset_sv)
1650 /* Fortunately, restoring the signal mask can't fail, because
1651 * there's nothing we can do about it if it does -- we're not
1652 * supposed to return -1 from sigaction unless the disposition
1655 #if !(defined(__amigaos4__) && defined(__NEWLIB__))
1656 sigset_t *ossetp = (sigset_t *) SvPV_nolen( osset_sv );
1657 (void)sigprocmask(SIG_SETMASK, ossetp, (sigset_t *)0);
1662 allocate_struct(pTHX_ SV *rv, const STRLEN size, const char *packname) {
1663 SV *const t = newSVrv(rv, packname);
1664 void *const p = sv_grow(t, size + 1);
1666 /* Ensure at least one use of not_here() to avoid "defined but not
1667 * used" warning. This is not at all related to allocate_struct(); I
1668 * just needed somewhere to dump it - DAPM */
1669 if (0) { not_here(""); }
1679 * (1) The CRT maintains its own copy of the environment, separate from
1680 * the Win32API copy.
1682 * (2) CRT getenv() retrieves from this copy. CRT putenv() updates this
1683 * copy, and then calls SetEnvironmentVariableA() to update the Win32API
1686 * (3) win32_getenv() and win32_putenv() call GetEnvironmentVariableA() and
1687 * SetEnvironmentVariableA() directly, bypassing the CRT copy of the
1690 * (4) The CRT strftime() "%Z" implementation calls __tzset(). That
1691 * calls CRT tzset(), but only the first time it is called, and in turn
1692 * that uses CRT getenv("TZ") to retrieve the timezone info from the CRT
1693 * local copy of the environment and hence gets the original setting as
1694 * perl never updates the CRT copy when assigning to $ENV{TZ}.
1696 * Therefore, we need to retrieve the value of $ENV{TZ} and call CRT
1697 * putenv() to update the CRT copy of the environment (if it is different)
1698 * whenever we're about to call tzset().
1700 * In addition to all that, when perl is built with PERL_IMPLICIT_SYS
1703 * (a) Each interpreter has its own copy of the environment inside the
1704 * perlhost structure. That allows applications that host multiple
1705 * independent Perl interpreters to isolate environment changes from
1706 * each other. (This is similar to how the perlhost mechanism keeps a
1707 * separate working directory for each Perl interpreter, so that calling
1708 * chdir() will not affect other interpreters.)
1710 * (b) Only the first Perl interpreter instantiated within a process will
1711 * "write through" environment changes to the process environment.
1713 * (c) Even the primary Perl interpreter won't update the CRT copy of the
1714 * the environment, only the Win32API copy (it calls win32_putenv()).
1716 * As with CPerlHost::Getenv() and CPerlHost::Putenv() themselves, it makes
1717 * sense to only update the process environment when inside the main
1718 * interpreter, but we don't have access to CPerlHost's m_bTopLevel member
1719 * from here so we'll just have to check PL_curinterp instead.
1721 * Therefore, we can simply #undef getenv() and putenv() so that those names
1722 * always refer to the CRT functions, and explicitly call win32_getenv() to
1723 * access perl's %ENV.
1725 * We also #undef malloc() and free() to be sure we are using the CRT
1726 * functions otherwise under PERL_IMPLICIT_SYS they are redefined to calls
1727 * into VMem::Malloc() and VMem::Free() and all allocations will be freed
1728 * when the Perl interpreter is being destroyed so we'd end up with a pointer
1729 * into deallocated memory in environ[] if a program embedding a Perl
1730 * interpreter continues to operate even after the main Perl interpreter has
1733 * Note that we don't free() the malloc()ed memory unless and until we call
1734 * malloc() again ourselves because the CRT putenv() function simply puts its
1735 * pointer argument into the environ[] array (it doesn't make a copy of it)
1736 * so this memory must otherwise be leaked.
1745 fix_win32_tzenv(void)
1747 static char* oldenv = NULL;
1749 const char* perl_tz_env = win32_getenv("TZ");
1750 const char* crt_tz_env = getenv("TZ");
1751 if (perl_tz_env == NULL)
1753 if (crt_tz_env == NULL)
1755 if (strcmp(perl_tz_env, crt_tz_env) != 0) {
1756 newenv = (char*)malloc((strlen(perl_tz_env) + 4) * sizeof(char));
1757 if (newenv != NULL) {
1758 sprintf(newenv, "TZ=%s", perl_tz_env);
1770 * my_tzset - wrapper to tzset() with a fix to make it work (better) on Win32.
1771 * This code is duplicated in the Time-Piece module, so any changes made here
1772 * should be made there too.
1778 #if defined(USE_ITHREADS) && defined(PERL_IMPLICIT_SYS)
1779 if (PL_curinterp == aTHX)
1786 MODULE = SigSet PACKAGE = POSIX::SigSet PREFIX = sig
1789 new(packname = "POSIX::SigSet", ...)
1790 const char * packname
1795 = (sigset_t *) allocate_struct(aTHX_ (ST(0) = sv_newmortal()),
1799 for (i = 1; i < items; i++)
1800 sigaddset(s, SvIV(ST(i)));
1806 POSIX::SigSet sigset
1811 RETVAL = ix ? sigdelset(sigset, sig) : sigaddset(sigset, sig);
1817 POSIX::SigSet sigset
1821 RETVAL = ix ? sigfillset(sigset) : sigemptyset(sigset);
1826 sigismember(sigset, sig)
1827 POSIX::SigSet sigset
1830 MODULE = Termios PACKAGE = POSIX::Termios PREFIX = cf
1833 new(packname = "POSIX::Termios", ...)
1834 const char * packname
1838 void *const p = allocate_struct(aTHX_ (ST(0) = sv_newmortal()),
1839 sizeof(struct termios), packname);
1840 /* The previous implementation stored a pointer to an uninitialised
1841 struct termios. Seems safer to initialise it, particularly as
1842 this implementation exposes the struct to prying from perl-space.
1844 memset(p, 0, 1 + sizeof(struct termios));
1847 not_here("termios");
1852 getattr(termios_ref, fd = 0)
1853 POSIX::Termios termios_ref
1856 RETVAL = tcgetattr(fd, termios_ref);
1860 # If we define TCSANOW here then both a found and not found constant sub
1861 # are created causing a Constant subroutine TCSANOW redefined warning
1863 # define DEF_SETATTR_ACTION 0
1865 # define DEF_SETATTR_ACTION TCSANOW
1868 setattr(termios_ref, fd = 0, optional_actions = DEF_SETATTR_ACTION)
1869 POSIX::Termios termios_ref
1871 int optional_actions
1873 /* The second argument to the call is mandatory, but we'd like to give
1874 it a useful default. 0 isn't valid on all operating systems - on
1875 Solaris (at least) TCSANOW, TCSADRAIN and TCSAFLUSH have the same
1876 values as the equivalent ioctls, TCSETS, TCSETSW and TCSETSF. */
1877 if (optional_actions < 0) {
1878 SETERRNO(EINVAL, LIB_INVARG);
1881 RETVAL = tcsetattr(fd, optional_actions, termios_ref);
1887 getispeed(termios_ref)
1888 POSIX::Termios termios_ref
1892 RETVAL = ix ? cfgetospeed(termios_ref) : cfgetispeed(termios_ref);
1897 getiflag(termios_ref)
1898 POSIX::Termios termios_ref
1904 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
1907 RETVAL = termios_ref->c_iflag;
1910 RETVAL = termios_ref->c_oflag;
1913 RETVAL = termios_ref->c_cflag;
1916 RETVAL = termios_ref->c_lflag;
1919 RETVAL = 0; /* silence compiler warning */
1922 not_here(GvNAME(CvGV(cv)));
1929 getcc(termios_ref, ccix)
1930 POSIX::Termios termios_ref
1933 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
1935 croak("Bad getcc subscript");
1936 RETVAL = termios_ref->c_cc[ccix];
1945 setispeed(termios_ref, speed)
1946 POSIX::Termios termios_ref
1952 ? cfsetospeed(termios_ref, speed) : cfsetispeed(termios_ref, speed);
1957 setiflag(termios_ref, flag)
1958 POSIX::Termios termios_ref
1965 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
1968 termios_ref->c_iflag = flag;
1971 termios_ref->c_oflag = flag;
1974 termios_ref->c_cflag = flag;
1977 termios_ref->c_lflag = flag;
1981 not_here(GvNAME(CvGV(cv)));
1985 setcc(termios_ref, ccix, cc)
1986 POSIX::Termios termios_ref
1990 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
1992 croak("Bad setcc subscript");
1993 termios_ref->c_cc[ccix] = cc;
1999 MODULE = POSIX PACKAGE = POSIX
2001 INCLUDE: const-xs.inc
2007 POSIX::WIFEXITED = 1
2008 POSIX::WIFSIGNALED = 2
2009 POSIX::WIFSTOPPED = 3
2013 #if !defined(WEXITSTATUS) || !defined(WIFEXITED) || !defined(WIFSIGNALED) \
2014 || !defined(WIFSTOPPED) || !defined(WSTOPSIG) || !defined(WTERMSIG)
2015 RETVAL = 0; /* Silence compilers that notice this, but don't realise
2016 that not_here() can't return. */
2021 RETVAL = WEXITSTATUS(WMUNGE(status));
2023 not_here("WEXITSTATUS");
2028 RETVAL = WIFEXITED(WMUNGE(status));
2030 not_here("WIFEXITED");
2035 RETVAL = WIFSIGNALED(WMUNGE(status));
2037 not_here("WIFSIGNALED");
2042 RETVAL = WIFSTOPPED(WMUNGE(status));
2044 not_here("WIFSTOPPED");
2049 RETVAL = WSTOPSIG(WMUNGE(status));
2051 not_here("WSTOPSIG");
2056 RETVAL = WTERMSIG(WMUNGE(status));
2058 not_here("WTERMSIG");
2062 croak("Illegal alias %d for POSIX::W*", (int)ix);
2068 open(filename, flags = O_RDONLY, mode = 0666)
2073 if (flags & (O_APPEND|O_CREAT|O_TRUNC|O_RDWR|O_WRONLY|O_EXCL))
2074 TAINT_PROPER("open");
2075 RETVAL = open(filename, flags, mode);
2083 #ifndef HAS_LOCALECONV
2084 localeconv(); /* A stub to call not_here(). */
2086 struct lconv *lcbuf;
2088 /* localeconv() deals with both LC_NUMERIC and LC_MONETARY, but
2089 * LC_MONETARY is already in the correct locale */
2090 DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
2091 STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
2094 sv_2mortal((SV*)RETVAL);
2095 if ((lcbuf = localeconv())) {
2096 const struct lconv_offset *strings = lconv_strings;
2097 const struct lconv_offset *integers = lconv_integers;
2098 const char *ptr = (const char *) lcbuf;
2100 while (strings->name) {
2101 /* This string may be controlled by either LC_NUMERIC, or
2104 #if defined(USE_LOCALE_NUMERIC) && defined(USE_LOCALE_MONETARY)
2105 = _is_cur_LC_category_utf8((isLC_NUMERIC_STRING(strings->name))
2108 #elif defined(USE_LOCALE_NUMERIC)
2109 = _is_cur_LC_category_utf8(LC_NUMERIC);
2110 #elif defined(USE_LOCALE_MONETARY)
2111 = _is_cur_LC_category_utf8(LC_MONETARY);
2116 const char *value = *((const char **)(ptr + strings->offset));
2118 if (value && *value) {
2119 (void) hv_store(RETVAL,
2121 strlen(strings->name),
2122 newSVpvn_utf8(value,
2125 /* We mark it as UTF-8 if a utf8 locale
2126 * and is valid and variant under UTF-8 */
2128 && ! is_invariant_string((U8 *) value, 0)
2129 && is_utf8_string((U8 *) value, 0)),
2135 while (integers->name) {
2136 const char value = *((const char *)(ptr + integers->offset));
2138 if (value != CHAR_MAX)
2139 (void) hv_store(RETVAL, integers->name,
2140 strlen(integers->name), newSViv(value), 0);
2144 RESTORE_LC_NUMERIC_STANDARD();
2145 #endif /* HAS_LOCALECONV */
2150 setlocale(category, locale = 0)
2156 #ifdef USE_LOCALE_NUMERIC
2157 /* A 0 (or NULL) locale means only query what the current one is. We
2158 * have the LC_NUMERIC name saved, because we are normally switched
2159 * into the C locale for it. Switch back so an LC_ALL query will yield
2160 * the correct results; all other categories don't require special
2163 if (category == LC_NUMERIC) {
2164 XSRETURN_PV(PL_numeric_name);
2167 else if (category == LC_ALL) {
2168 SET_NUMERIC_UNDERLYING();
2173 #ifdef WIN32 /* Use wrapper on Windows */
2174 retval = Perl_my_setlocale(aTHX_ category, locale);
2176 retval = setlocale(category, locale);
2178 DEBUG_L(PerlIO_printf(Perl_debug_log,
2179 "%s:%d: %s\n", __FILE__, __LINE__,
2180 _setlocale_debug_string(category, locale, retval)));
2182 /* Should never happen that a query would return an error, but be
2183 * sure and reset to C locale */
2185 SET_NUMERIC_STANDARD();
2190 /* Save retval since subsequent setlocale() calls may overwrite it. */
2191 retval = savepv(retval);
2194 /* For locale == 0, we may have switched to NUMERIC_UNDERLYING. Switch
2197 SET_NUMERIC_STANDARD();
2198 XSRETURN_PV(retval);
2202 #ifdef USE_LOCALE_CTYPE
2203 if (category == LC_CTYPE
2205 || category == LC_ALL
2211 if (category == LC_ALL) {
2212 newctype = setlocale(LC_CTYPE, NULL);
2213 DEBUG_Lv(PerlIO_printf(Perl_debug_log,
2214 "%s:%d: %s\n", __FILE__, __LINE__,
2215 _setlocale_debug_string(LC_CTYPE, NULL, newctype)));
2220 new_ctype(newctype);
2222 #endif /* USE_LOCALE_CTYPE */
2223 #ifdef USE_LOCALE_COLLATE
2224 if (category == LC_COLLATE
2226 || category == LC_ALL
2232 if (category == LC_ALL) {
2233 newcoll = setlocale(LC_COLLATE, NULL);
2234 DEBUG_Lv(PerlIO_printf(Perl_debug_log,
2235 "%s:%d: %s\n", __FILE__, __LINE__,
2236 _setlocale_debug_string(LC_COLLATE, NULL, newcoll)));
2241 new_collate(newcoll);
2243 #endif /* USE_LOCALE_COLLATE */
2244 #ifdef USE_LOCALE_NUMERIC
2245 if (category == LC_NUMERIC
2247 || category == LC_ALL
2253 if (category == LC_ALL) {
2254 newnum = setlocale(LC_NUMERIC, NULL);
2255 DEBUG_Lv(PerlIO_printf(Perl_debug_log,
2256 "%s:%d: %s\n", __FILE__, __LINE__,
2257 _setlocale_debug_string(LC_NUMERIC, NULL, newnum)));
2262 new_numeric(newnum);
2264 #endif /* USE_LOCALE_NUMERIC */
2308 RETVAL = Perl_acos(x); /* C89 math */
2312 RETVAL = c99_acosh(x);
2318 RETVAL = Perl_asin(x); /* C89 math */
2322 RETVAL = c99_asinh(x);
2328 RETVAL = Perl_atan(x); /* C89 math */
2332 RETVAL = c99_atanh(x);
2339 RETVAL = c99_cbrt(x);
2345 RETVAL = Perl_ceil(x); /* C89 math */
2348 RETVAL = Perl_cosh(x); /* C89 math */
2352 RETVAL = c99_erf(x);
2359 RETVAL = c99_erfc(x);
2366 RETVAL = c99_exp2(x);
2373 RETVAL = c99_expm1(x);
2379 RETVAL = Perl_floor(x); /* C89 math */
2383 RETVAL = bessel_j0(x);
2390 RETVAL = bessel_j1(x);
2396 /* XXX Note: the lgamma modifies a global variable (signgam),
2397 * which is evil. Some platforms have lgamma_r, which has
2398 * extra output parameter instead of the global variable. */
2400 RETVAL = c99_lgamma(x);
2406 RETVAL = log10(x); /* C89 math */
2410 RETVAL = c99_log1p(x);
2417 RETVAL = c99_log2(x);
2424 RETVAL = c99_logb(x);
2425 #elif defined(c99_log2) && FLT_RADIX == 2
2426 RETVAL = Perl_floor(c99_log2(PERL_ABS(x)));
2432 #ifdef c99_nearbyint
2433 RETVAL = c99_nearbyint(x);
2435 not_here("nearbyint");
2440 RETVAL = c99_rint(x);
2447 RETVAL = c99_round(x);
2453 RETVAL = Perl_sinh(x); /* C89 math */
2456 RETVAL = Perl_tan(x); /* C89 math */
2459 RETVAL = Perl_tanh(x); /* C89 math */
2463 RETVAL = c99_tgamma(x);
2470 RETVAL = c99_trunc(x);
2477 RETVAL = bessel_y0(x);
2485 RETVAL = bessel_y1(x);
2496 #ifdef HAS_FEGETROUND
2497 RETVAL = my_fegetround();
2500 not_here("fegetround");
2509 #ifdef HAS_FEGETROUND /* canary for fesetround */
2510 RETVAL = fesetround(x);
2511 #elif defined(HAS_FPGETROUND) /* canary for fpsetround */
2513 case FE_TONEAREST: RETVAL = fpsetround(FP_RN); break;
2514 case FE_TOWARDZERO: RETVAL = fpsetround(FP_RZ); break;
2515 case FE_DOWNWARD: RETVAL = fpsetround(FP_RM); break;
2516 case FE_UPWARD: RETVAL = fpsetround(FP_RP); break;
2517 default: RETVAL = -1; break;
2519 #elif defined(__osf__) /* Tru64 */
2521 case FE_TONEAREST: RETVAL = write_rnd(FP_RND_RN); break;
2522 case FE_TOWARDZERO: RETVAL = write_rnd(FP_RND_RZ); break;
2523 case FE_DOWNWARD: RETVAL = write_rnd(FP_RND_RM); break;
2524 case FE_UPWARD: RETVAL = write_rnd(FP_RND_RP); break;
2525 default: RETVAL = -1; break;
2530 not_here("fesetround");
2552 #ifdef c99_fpclassify
2553 RETVAL = c99_fpclassify(x);
2555 not_here("fpclassify");
2560 RETVAL = c99_ilogb(x);
2566 RETVAL = Perl_isfinite(x);
2569 RETVAL = Perl_isinf(x);
2572 RETVAL = Perl_isnan(x);
2576 RETVAL = c99_isnormal(x);
2578 not_here("isnormal");
2583 RETVAL = c99_lrint(x);
2590 RETVAL = c99_lround(x);
2598 RETVAL = Perl_signbit(x);
2600 RETVAL = (x < 0) || (x == -0.0);
2611 RETVAL = S_getpayload(nv);
2616 setpayload(nv, payload)
2620 S_setpayload(&nv, payload, FALSE);
2625 setpayloadsig(nv, payload)
2630 S_setpayload(&nv, payload, TRUE);
2638 RETVAL = Perl_isnan(nv) && NV_NAN_IS_SIGNALING(&nv);
2668 RETVAL = c99_copysign(x, y);
2670 not_here("copysign");
2675 RETVAL = c99_fdim(x, y);
2682 RETVAL = c99_fmax(x, y);
2689 RETVAL = c99_fmin(x, y);
2695 RETVAL = Perl_fmod(x, y); /* C89 math */
2699 RETVAL = c99_hypot(x, y);
2705 #ifdef c99_isgreater
2706 RETVAL = c99_isgreater(x, y);
2708 not_here("isgreater");
2712 #ifdef c99_isgreaterequal
2713 RETVAL = c99_isgreaterequal(x, y);
2715 not_here("isgreaterequal");
2720 RETVAL = c99_isless(x, y);
2726 #ifdef c99_islessequal
2727 RETVAL = c99_islessequal(x, y);
2729 not_here("islessequal");
2733 #ifdef c99_islessgreater
2734 RETVAL = c99_islessgreater(x, y);
2736 not_here("islessgreater");
2740 #ifdef c99_isunordered
2741 RETVAL = c99_isunordered(x, y);
2743 not_here("isunordered");
2747 #ifdef c99_nextafter
2748 RETVAL = c99_nextafter(x, y);
2750 not_here("nextafter");
2754 #ifdef c99_nexttoward
2755 RETVAL = c99_nexttoward(x, y);
2757 not_here("nexttoward");
2762 #ifdef c99_remainder
2763 RETVAL = c99_remainder(x, y);
2765 not_here("remainder");
2777 /* (We already know stack is long enough.) */
2778 PUSHs(sv_2mortal(newSVnv(Perl_frexp(x,&expvar)))); /* C89 math */
2779 PUSHs(sv_2mortal(newSViv(expvar)));
2791 /* (We already know stack is long enough.) */
2792 PUSHs(sv_2mortal(newSVnv(Perl_modf(x,&intvar)))); /* C89 math */
2793 PUSHs(sv_2mortal(newSVnv(intvar)));
2802 PUSHs(sv_2mortal(newSVnv(c99_remquo(x,y,&intvar))));
2803 PUSHs(sv_2mortal(newSVnv(intvar)));
2816 RETVAL = c99_scalbn(x, y);
2833 RETVAL = c99_fma(x, y, z);
2848 /* If no payload given, just return the default NaN.
2849 * This makes a difference in platforms where the default
2850 * NaN is not all zeros. */
2854 S_setpayload(&RETVAL, payload, FALSE);
2856 #elif defined(c99_nan)
2858 STRLEN elen = my_snprintf(PL_efloatbuf, PL_efloatsize, "%g", nv);
2859 if ((IV)elen == -1) {
2862 RETVAL = c99_nan(PL_efloatbuf);
2882 RETVAL = bessel_jn(x, y);
2892 RETVAL = bessel_yn(x, y);
2904 sigaction(sig, optaction, oldaction = 0)
2907 POSIX::SigAction oldaction
2909 #if defined(WIN32) || defined(NETWARE) || (defined(__amigaos4__) && defined(__NEWLIB__))
2910 RETVAL = not_here("sigaction");
2912 # This code is really grody because we are trying to make the signal
2913 # interface look beautiful, which is hard.
2917 POSIX__SigAction action;
2918 GV *siggv = gv_fetchpvs("SIG", GV_ADD, SVt_PVHV);
2919 struct sigaction act;
2920 struct sigaction oact;
2924 POSIX__SigSet sigset;
2929 croak("Negative signals are not allowed");
2932 if (sig == 0 && SvPOK(ST(0))) {
2933 const char *s = SvPVX_const(ST(0));
2934 int i = whichsig(s);
2936 if (i < 0 && memEQ(s, "SIG", 3))
2937 i = whichsig(s + 3);
2939 if (ckWARN(WARN_SIGNAL))
2940 Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
2941 "No such signal: SIG%s", s);
2948 if (sig > NSIG) { /* NSIG - 1 is still okay. */
2949 Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
2950 "No such signal: %d", sig);
2954 sigsvp = hv_fetch(GvHVn(siggv),
2956 strlen(PL_sig_name[sig]),
2959 /* Check optaction and set action */
2960 if(SvTRUE(optaction)) {
2961 if(sv_isa(optaction, "POSIX::SigAction"))
2962 action = (HV*)SvRV(optaction);
2964 croak("action is not of type POSIX::SigAction");
2970 /* sigaction() is supposed to look atomic. In particular, any
2971 * signal handler invoked during a sigaction() call should
2972 * see either the old or the new disposition, and not something
2973 * in between. We use sigprocmask() to make it so.
2976 RETVAL=sigprocmask(SIG_BLOCK, &sset, &osset);
2980 /* Restore signal mask no matter how we exit this block. */
2981 osset_sv = newSVpvn((char *)(&osset), sizeof(sigset_t));
2982 SAVEFREESV( osset_sv );
2983 SAVEDESTRUCTOR_X(restore_sigmask, osset_sv);
2985 RETVAL=-1; /* In case both oldaction and action are 0. */
2987 /* Remember old disposition if desired. */
2989 svp = hv_fetchs(oldaction, "HANDLER", TRUE);
2991 croak("Can't supply an oldaction without a HANDLER");
2992 if(SvTRUE(*sigsvp)) { /* TBD: what if "0"? */
2993 sv_setsv(*svp, *sigsvp);
2996 sv_setpvs(*svp, "DEFAULT");
2998 RETVAL = sigaction(sig, (struct sigaction *)0, & oact);
3003 /* Get back the mask. */
3004 svp = hv_fetchs(oldaction, "MASK", TRUE);
3005 if (sv_isa(*svp, "POSIX::SigSet")) {
3006 sigset = (sigset_t *) SvPV_nolen(SvRV(*svp));
3009 sigset = (sigset_t *) allocate_struct(aTHX_ *svp,
3013 *sigset = oact.sa_mask;
3015 /* Get back the flags. */
3016 svp = hv_fetchs(oldaction, "FLAGS", TRUE);
3017 sv_setiv(*svp, oact.sa_flags);
3019 /* Get back whether the old handler used safe signals. */
3020 svp = hv_fetchs(oldaction, "SAFE", TRUE);
3022 /* compare incompatible pointers by casting to integer */
3023 PTR2nat(oact.sa_handler) == PTR2nat(PL_csighandlerp));
3027 /* Safe signals use "csighandler", which vectors through the
3028 PL_sighandlerp pointer when it's safe to do so.
3029 (BTW, "csighandler" is very different from "sighandler".) */
3030 svp = hv_fetchs(action, "SAFE", FALSE);
3034 (*svp && SvTRUE(*svp))
3035 ? PL_csighandlerp : PL_sighandlerp
3038 /* Vector new Perl handler through %SIG.
3039 (The core signal handlers read %SIG to dispatch.) */
3040 svp = hv_fetchs(action, "HANDLER", FALSE);
3042 croak("Can't supply an action without a HANDLER");
3043 sv_setsv(*sigsvp, *svp);
3045 /* This call actually calls sigaction() with almost the
3046 right settings, including appropriate interpretation
3047 of DEFAULT and IGNORE. However, why are we doing
3048 this when we're about to do it again just below? XXX */
3049 SvSETMAGIC(*sigsvp);
3051 /* And here again we duplicate -- DEFAULT/IGNORE checking. */
3053 const char *s=SvPVX_const(*svp);
3054 if(strEQ(s,"IGNORE")) {
3055 act.sa_handler = SIG_IGN;
3057 else if(strEQ(s,"DEFAULT")) {
3058 act.sa_handler = SIG_DFL;
3062 /* Set up any desired mask. */
3063 svp = hv_fetchs(action, "MASK", FALSE);
3064 if (svp && sv_isa(*svp, "POSIX::SigSet")) {
3065 sigset = (sigset_t *) SvPV_nolen(SvRV(*svp));
3066 act.sa_mask = *sigset;
3069 sigemptyset(& act.sa_mask);
3071 /* Set up any desired flags. */
3072 svp = hv_fetchs(action, "FLAGS", FALSE);
3073 act.sa_flags = svp ? SvIV(*svp) : 0;
3075 /* Don't worry about cleaning up *sigsvp if this fails,
3076 * because that means we tried to disposition a
3077 * nonblockable signal, in which case *sigsvp is
3078 * essentially meaningless anyway.
3080 RETVAL = sigaction(sig, & act, (struct sigaction *)0);
3095 POSIX::SigSet sigset
3100 RETVAL = not_here("sigpending");
3102 RETVAL = ix ? sigsuspend(sigset) : sigpending(sigset);
3110 sigprocmask(how, sigset, oldsigset = 0)
3112 POSIX::SigSet sigset = NO_INIT
3113 POSIX::SigSet oldsigset = NO_INIT
3115 if (! SvOK(ST(1))) {
3117 } else if (sv_isa(ST(1), "POSIX::SigSet")) {
3118 sigset = (sigset_t *) SvPV_nolen(SvRV(ST(1)));
3120 croak("sigset is not of type POSIX::SigSet");
3123 if (items < 3 || ! SvOK(ST(2))) {
3125 } else if (sv_isa(ST(2), "POSIX::SigSet")) {
3126 oldsigset = (sigset_t *) SvPV_nolen(SvRV(ST(2)));
3128 croak("oldsigset is not of type POSIX::SigSet");
3140 if (fd1 >= 0 && fd2 >= 0) {
3142 /* RT #98912 - More Microsoft muppetry - failing to
3143 actually implemented the well known documented POSIX
3144 behaviour for a POSIX API.
3145 http://msdn.microsoft.com/en-us/library/8syseb29.aspx */
3146 RETVAL = dup2(fd1, fd2) == -1 ? -1 : fd2;
3148 RETVAL = dup2(fd1, fd2);
3151 SETERRNO(EBADF,RMS_IFI);
3158 lseek(fd, offset, whence)
3164 Off_t pos = PerlLIO_lseek(fd, offset, whence);
3165 RETVAL = sizeof(Off_t) > sizeof(IV)
3166 ? newSVnv((NV)pos) : newSViv((IV)pos);
3176 if ((incr = nice(incr)) != -1 || errno == 0) {
3178 XPUSHs(newSVpvs_flags("0 but true", SVs_TEMP));
3180 XPUSHs(sv_2mortal(newSViv(incr)));
3187 if (pipe(fds) != -1) {
3189 PUSHs(sv_2mortal(newSViv(fds[0])));
3190 PUSHs(sv_2mortal(newSViv(fds[1])));
3194 read(fd, buffer, nbytes)
3196 SV *sv_buffer = SvROK(ST(1)) ? SvRV(ST(1)) : ST(1);
3200 char * buffer = sv_grow( sv_buffer, nbytes+1 );
3203 SvCUR_set(sv_buffer, RETVAL);
3204 SvPOK_only(sv_buffer);
3205 *SvEND(sv_buffer) = '\0';
3206 SvTAINTED_on(sv_buffer);
3222 tcsetpgrp(fd, pgrp_id)
3231 if (uname(&buf) >= 0) {
3233 PUSHs(newSVpvn_flags(buf.sysname, strlen(buf.sysname), SVs_TEMP));
3234 PUSHs(newSVpvn_flags(buf.nodename, strlen(buf.nodename), SVs_TEMP));
3235 PUSHs(newSVpvn_flags(buf.release, strlen(buf.release), SVs_TEMP));
3236 PUSHs(newSVpvn_flags(buf.version, strlen(buf.version), SVs_TEMP));
3237 PUSHs(newSVpvn_flags(buf.machine, strlen(buf.machine), SVs_TEMP));
3240 uname((char *) 0); /* A stub to call not_here(). */
3244 write(fd, buffer, nbytes)
3258 mbstowcs(s, pwcs, n)
3270 wcstombs(s, pwcs, n)
3292 DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
3293 STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
3294 num = strtod(str, &unparsed);
3295 PUSHs(sv_2mortal(newSVnv(num)));
3296 if (GIMME_V == G_ARRAY) {
3299 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3301 PUSHs(&PL_sv_undef);
3303 RESTORE_LC_NUMERIC_STANDARD();
3314 DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
3315 STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
3316 num = strtold(str, &unparsed);
3317 PUSHs(sv_2mortal(newSVnv(num)));
3318 if (GIMME_V == G_ARRAY) {
3321 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3323 PUSHs(&PL_sv_undef);
3325 RESTORE_LC_NUMERIC_STANDARD();
3330 strtol(str, base = 0)
3337 if (base == 0 || (base >= 2 && base <= 36)) {
3338 num = strtol(str, &unparsed, base);
3339 #if IVSIZE < LONGSIZE
3340 if (num < IV_MIN || num > IV_MAX)
3341 PUSHs(sv_2mortal(newSVnv((double)num)));
3344 PUSHs(sv_2mortal(newSViv((IV)num)));
3345 if (GIMME_V == G_ARRAY) {
3348 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3350 PUSHs(&PL_sv_undef);
3353 SETERRNO(EINVAL, LIB_INVARG);
3354 PUSHs(&PL_sv_undef);
3355 if (GIMME_V == G_ARRAY) {
3357 PUSHs(&PL_sv_undef);
3362 strtoul(str, base = 0)
3369 PERL_UNUSED_VAR(str);
3370 PERL_UNUSED_VAR(base);
3371 if (base == 0 || (base >= 2 && base <= 36)) {
3372 num = strtoul(str, &unparsed, base);
3373 #if IVSIZE <= LONGSIZE
3375 PUSHs(sv_2mortal(newSVnv((double)num)));
3378 PUSHs(sv_2mortal(newSViv((IV)num)));
3379 if (GIMME_V == G_ARRAY) {
3382 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
3384 PUSHs(&PL_sv_undef);
3387 SETERRNO(EINVAL, LIB_INVARG);
3388 PUSHs(&PL_sv_undef);
3389 if (GIMME_V == G_ARRAY) {
3391 PUSHs(&PL_sv_undef);
3403 char *p = SvPV(src,srclen);
3405 buflen = srclen * 4 + 1;
3406 ST(0) = sv_2mortal(newSV(buflen));
3407 dstlen = strxfrm(SvPVX(ST(0)), p, (size_t)buflen);
3408 if (dstlen >= buflen) {
3410 SvGROW(ST(0), dstlen);
3411 strxfrm(SvPVX(ST(0)), p, (size_t)dstlen);
3414 SvCUR_set(ST(0), dstlen);
3419 mkfifo(filename, mode)
3426 RETVAL = access(filename, mode);
3428 TAINT_PROPER("mkfifo");
3429 RETVAL = mkfifo(filename, mode);
3442 RETVAL = ix == 1 ? close(fd)
3443 : (ix < 1 ? tcdrain(fd) : dup(fd));
3445 SETERRNO(EBADF,RMS_IFI);
3461 RETVAL = ix == 1 ? tcflush(fd, action)
3462 : (ix < 1 ? tcflow(fd, action) : tcsendbreak(fd, action));
3464 SETERRNO(EINVAL,LIB_INVARG);
3471 asctime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = -1)
3487 init_tm(&mytm); /* XXX workaround - see init_tm() in core util.c */
3490 mytm.tm_hour = hour;
3491 mytm.tm_mday = mday;
3493 mytm.tm_year = year;
3494 mytm.tm_wday = wday;
3495 mytm.tm_yday = yday;
3496 mytm.tm_isdst = isdst;
3498 const time_t result = mktime(&mytm);
3499 if (result == (time_t)-1)
3501 else if (result == 0)
3502 sv_setpvn(TARG, "0 but true", 10);
3504 sv_setiv(TARG, (IV)result);
3506 sv_setpv(TARG, asctime(&mytm));
3524 realtime = times( &tms );
3526 PUSHs( sv_2mortal( newSViv( (IV) realtime ) ) );
3527 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_utime ) ) );
3528 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_stime ) ) );
3529 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cutime ) ) );
3530 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cstime ) ) );
3533 difftime(time1, time2)
3537 #XXX: if $xsubpp::WantOptimize is always the default
3538 # sv_setpv(TARG, ...) could be used rather than
3539 # ST(0) = sv_2mortal(newSVpv(...))
3541 strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1)
3557 /* allowing user-supplied (rather than literal) formats
3558 * is normally frowned upon as a potential security risk;
3559 * but this is part of the API so we have to allow it */
3560 GCC_DIAG_IGNORE(-Wformat-nonliteral);
3561 buf = my_strftime(SvPV_nolen(fmt), sec, min, hour, mday, mon, year, wday, yday, isdst);
3563 sv = sv_newmortal();
3565 STRLEN len = strlen(buf);
3566 sv_usepvn_flags(sv, buf, len, SV_HAS_TRAILING_NUL);
3568 || (! is_invariant_string((U8*) buf, len)
3569 && is_utf8_string((U8*) buf, len)
3570 #ifdef USE_LOCALE_TIME
3571 && _is_cur_LC_category_utf8(LC_TIME)
3577 else { /* We can't distinguish between errors and just an empty
3578 * return; in all cases just return an empty string */
3579 SvUPGRADE(sv, SVt_PV);
3580 SvPV_set(sv, (char *) "");
3583 SvLEN_set(sv, 0); /* Won't attempt to free the string when sv
3598 PUSHs(newSVpvn_flags(tzname[0], strlen(tzname[0]), SVs_TEMP));
3599 PUSHs(newSVpvn_flags(tzname[1], strlen(tzname[1]), SVs_TEMP));
3605 #ifdef HAS_CTERMID_R
3606 s = (char *) safemalloc((size_t) L_ctermid);
3608 RETVAL = ctermid(s);
3612 #ifdef HAS_CTERMID_R
3621 RETVAL = cuserid(s);
3625 not_here("cuserid");
3636 pathconf(filename, name)
3647 unsigned int seconds
3649 RETVAL = PerlProc_sleep(seconds);
3675 XSprePUSH; PUSHTARG;
3679 lchown(uid, gid, path)
3685 /* yes, the order of arguments is different,
3686 * but consistent with CORE::chown() */
3687 RETVAL = lchown(path, uid, gid);
3689 PERL_UNUSED_VAR(uid);
3690 PERL_UNUSED_VAR(gid);
3691 PERL_UNUSED_VAR(path);
3692 RETVAL = not_here("lchown");