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? */
54 /* XXX This comment is just to make I_TERMIO and I_SGTTY visible to
55 metaconfig for future extension writers. We don't use them in POSIX.
56 (This is really sneaky :-) --AD
58 #if defined(I_TERMIOS)
68 #include <sys/types.h>
76 # if !defined(WIN32) && !defined(__CYGWIN__) && !defined(NETWARE) && !defined(__UWIN__)
77 extern char *tzname[];
80 #if !defined(WIN32) && !defined(__UWIN__) || (defined(__MINGW32__) && !defined(tzname))
81 char *tzname[] = { "" , "" };
85 #if defined(__VMS) && !defined(__POSIX_SOURCE)
86 # include <libdef.h> /* LIB$_INVARG constant */
87 # include <lib$routines.h> /* prototype for lib$ediv() */
88 # include <starlet.h> /* prototype for sys$gettim() */
89 # if DECC_VERSION < 50000000
90 # define pid_t int /* old versions of DECC miss this in types.h */
94 # define mkfifo(a,b) (not_here("mkfifo"),-1)
95 # define tzset() not_here("tzset")
97 #if ((__VMS_VER >= 70000000) && (__DECC_VER >= 50200000)) || (__CRTL_VER >= 70000000)
98 # define HAS_TZNAME /* shows up in VMS 7.0 or Dec C 5.6 */
100 # endif /* __VMS_VER >= 70000000 or Dec C 5.6 */
102 /* The POSIX notion of ttyname() is better served by getname() under VMS */
103 static char ttnambuf[64];
104 # define ttyname(fd) (isatty(fd) > 0 ? getname(fd,ttnambuf,0) : NULL)
106 /* The non-POSIX CRTL times() has void return type, so we just get the
107 current time directly */
108 clock_t vms_times(struct tms *bufptr) {
111 /* Get wall time and convert to 10 ms intervals to
112 * produce the return value that the POSIX standard expects */
113 # if defined(__DECC) && defined (__ALPHA)
116 _ckvmssts(sys$gettim(&vmstime));
118 retval = vmstime & 0x7fffffff;
120 /* (Older hw or ccs don't have an atomic 64-bit type, so we
121 * juggle 32-bit ints (and a float) to produce a time_t result
122 * with minimal loss of information.) */
123 long int vmstime[2],remainder,divisor = 100000;
124 _ckvmssts(sys$gettim((unsigned long int *)vmstime));
125 vmstime[1] &= 0x7fff; /* prevent overflow in EDIV */
126 _ckvmssts(lib$ediv(&divisor,vmstime,(long int *)&retval,&remainder));
128 /* Fill in the struct tms using the CRTL routine . . .*/
129 times((tbuffer_t *)bufptr);
130 return (clock_t) retval;
132 # define times(t) vms_times(t)
134 #if defined (__CYGWIN__)
135 # define tzname _tzname
137 #if defined (WIN32) || defined (NETWARE)
139 # define mkfifo(a,b) not_here("mkfifo")
140 # define ttyname(a) (char*)not_here("ttyname")
141 # define sigset_t long
144 # define mode_t short
147 # define mode_t short
149 # define tzset() not_here("tzset")
151 # ifndef _POSIX_OPEN_MAX
152 # define _POSIX_OPEN_MAX FOPEN_MAX /* XXX bogus ? */
155 # define sigaction(a,b,c) not_here("sigaction")
156 # define sigpending(a) not_here("sigpending")
157 # define sigprocmask(a,b,c) not_here("sigprocmask")
158 # define sigsuspend(a) not_here("sigsuspend")
159 # define sigemptyset(a) not_here("sigemptyset")
160 # define sigaddset(a,b) not_here("sigaddset")
161 # define sigdelset(a,b) not_here("sigdelset")
162 # define sigfillset(a) not_here("sigfillset")
163 # define sigismember(a,b) not_here("sigismember")
167 # define setuid(a) not_here("setuid")
168 # define setgid(a) not_here("setgid")
174 # define mkfifo(a,b) not_here("mkfifo")
175 # else /* !( defined OS2 ) */
177 # define mkfifo(path, mode) (mknod((path), (mode) | S_IFIFO, 0))
180 # endif /* !HAS_MKFIFO */
185 # include <sys/times.h>
187 # include <sys/utsname.h>
189 # include <sys/wait.h>
193 #endif /* WIN32 || NETWARE */
197 /* Perl on Windows assigns WSAGetLastError() return values to errno
198 * (in win32/win32sck.c). Therefore we need to map these values
199 * back to standard symbolic names, but only for those names having
200 * no existing value or an existing value >= 100. (VC++ 2010 defines
201 * a group of names with values >= 100 in its errno.h which we *do*
202 * need to redefine.) The Errno.pm module does a similar mapping.
207 # define EWOULDBLOCK WSAEWOULDBLOCK
211 # define EINPROGRESS WSAEINPROGRESS
215 # define EALREADY WSAEALREADY
219 # define ENOTSOCK WSAENOTSOCK
223 # define EDESTADDRREQ WSAEDESTADDRREQ
227 # define EMSGSIZE WSAEMSGSIZE
231 # define EPROTOTYPE WSAEPROTOTYPE
235 # define ENOPROTOOPT WSAENOPROTOOPT
236 # ifdef EPROTONOSUPPORT
237 # undef EPROTONOSUPPORT
239 # define EPROTONOSUPPORT WSAEPROTONOSUPPORT
240 # ifdef ESOCKTNOSUPPORT
241 # undef ESOCKTNOSUPPORT
243 # define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
247 # define EOPNOTSUPP WSAEOPNOTSUPP
251 # define EPFNOSUPPORT WSAEPFNOSUPPORT
255 # define EAFNOSUPPORT WSAEAFNOSUPPORT
259 # define EADDRINUSE WSAEADDRINUSE
260 # ifdef EADDRNOTAVAIL
261 # undef EADDRNOTAVAIL
263 # define EADDRNOTAVAIL WSAEADDRNOTAVAIL
267 # define ENETDOWN WSAENETDOWN
271 # define ENETUNREACH WSAENETUNREACH
275 # define ENETRESET WSAENETRESET
279 # define ECONNABORTED WSAECONNABORTED
283 # define ECONNRESET WSAECONNRESET
287 # define ENOBUFS WSAENOBUFS
291 # define EISCONN WSAEISCONN
295 # define ENOTCONN WSAENOTCONN
299 # define ESHUTDOWN WSAESHUTDOWN
303 # define ETOOMANYREFS WSAETOOMANYREFS
307 # define ETIMEDOUT WSAETIMEDOUT
311 # define ECONNREFUSED WSAECONNREFUSED
315 # define ELOOP WSAELOOP
319 # define EHOSTDOWN WSAEHOSTDOWN
323 # define EHOSTUNREACH WSAEHOSTUNREACH
327 # define EPROCLIM WSAEPROCLIM
331 # define EUSERS WSAEUSERS
335 # define EDQUOT WSAEDQUOT
339 # define ESTALE WSAESTALE
343 # define EREMOTE WSAEREMOTE
347 # define EDISCON WSAEDISCON
351 typedef long SysRetLong;
352 typedef sigset_t* POSIX__SigSet;
353 typedef HV* POSIX__SigAction;
355 typedef struct termios* POSIX__Termios;
356 #else /* Define termios types to int, and call not_here for the functions.*/
357 #define POSIX__Termios int
361 #define cfgetispeed(x) not_here("cfgetispeed")
362 #define cfgetospeed(x) not_here("cfgetospeed")
363 #define tcdrain(x) not_here("tcdrain")
364 #define tcflush(x,y) not_here("tcflush")
365 #define tcsendbreak(x,y) not_here("tcsendbreak")
366 #define cfsetispeed(x,y) not_here("cfsetispeed")
367 #define cfsetospeed(x,y) not_here("cfsetospeed")
368 #define ctermid(x) (char *) not_here("ctermid")
369 #define tcflow(x,y) not_here("tcflow")
370 #define tcgetattr(x,y) not_here("tcgetattr")
371 #define tcsetattr(x,y,z) not_here("tcsetattr")
374 /* Possibly needed prototypes */
376 double strtod (const char *, char **);
377 long strtol (const char *, char **, int);
378 unsigned long strtoul (const char *, char **, int);
383 #define difftime(a,b) not_here("difftime")
386 #ifndef HAS_FPATHCONF
387 #define fpathconf(f,n) (SysRetLong) not_here("fpathconf")
390 #define mktime(a) not_here("mktime")
393 #define nice(a) not_here("nice")
396 #define pathconf(f,n) (SysRetLong) not_here("pathconf")
399 #define sysconf(n) (SysRetLong) not_here("sysconf")
402 #define readlink(a,b,c) not_here("readlink")
405 #define setpgid(a,b) not_here("setpgid")
408 #define setsid() not_here("setsid")
411 #define strcoll(s1,s2) not_here("strcoll")
414 #define strtod(s1,s2) not_here("strtod")
417 #define strtol(s1,s2,b) not_here("strtol")
420 #define strtoul(s1,s2,b) not_here("strtoul")
423 #define strxfrm(s1,s2,n) not_here("strxfrm")
425 #ifndef HAS_TCGETPGRP
426 #define tcgetpgrp(a) not_here("tcgetpgrp")
428 #ifndef HAS_TCSETPGRP
429 #define tcsetpgrp(a,b) not_here("tcsetpgrp")
433 #define times(a) not_here("times")
437 #define uname(a) not_here("uname")
440 #define waitpid(a,b,c) not_here("waitpid")
445 #define mblen(a,b) not_here("mblen")
449 #define mbstowcs(s, pwcs, n) not_here("mbstowcs")
452 #define mbtowc(pwc, s, n) not_here("mbtowc")
455 #define wcstombs(s, pwcs, n) not_here("wcstombs")
458 #define wctomb(s, wchar) not_here("wcstombs")
460 #if !defined(HAS_MBLEN) && !defined(HAS_MBSTOWCS) && !defined(HAS_MBTOWC) && !defined(HAS_WCSTOMBS) && !defined(HAS_WCTOMB)
461 /* If we don't have these functions, then we wouldn't have gotten a typedef
462 for wchar_t, the wide character type. Defining wchar_t allows the
463 functions referencing it to compile. Its actual type is then meaningless,
464 since without the above functions, all sections using it end up calling
465 not_here() and croak. --Kaveh Ghazi (ghazi@noc.rutgers.edu) 9/18/94. */
471 #ifdef HAS_LOCALECONV
472 struct lconv_offset {
477 const struct lconv_offset lconv_strings[] = {
478 {"decimal_point", offsetof(struct lconv, decimal_point)},
479 {"thousands_sep", offsetof(struct lconv, thousands_sep)},
480 #ifndef NO_LOCALECONV_GROUPING
481 {"grouping", offsetof(struct lconv, grouping)},
483 {"int_curr_symbol", offsetof(struct lconv, int_curr_symbol)},
484 {"currency_symbol", offsetof(struct lconv, currency_symbol)},
485 {"mon_decimal_point", offsetof(struct lconv, mon_decimal_point)},
486 #ifndef NO_LOCALECONV_MON_THOUSANDS_SEP
487 {"mon_thousands_sep", offsetof(struct lconv, mon_thousands_sep)},
489 #ifndef NO_LOCALECONV_MON_GROUPING
490 {"mon_grouping", offsetof(struct lconv, mon_grouping)},
492 {"positive_sign", offsetof(struct lconv, positive_sign)},
493 {"negative_sign", offsetof(struct lconv, negative_sign)},
497 const struct lconv_offset lconv_integers[] = {
498 {"int_frac_digits", offsetof(struct lconv, int_frac_digits)},
499 {"frac_digits", offsetof(struct lconv, frac_digits)},
500 {"p_cs_precedes", offsetof(struct lconv, p_cs_precedes)},
501 {"p_sep_by_space", offsetof(struct lconv, p_sep_by_space)},
502 {"n_cs_precedes", offsetof(struct lconv, n_cs_precedes)},
503 {"n_sep_by_space", offsetof(struct lconv, n_sep_by_space)},
504 {"p_sign_posn", offsetof(struct lconv, p_sign_posn)},
505 {"n_sign_posn", offsetof(struct lconv, n_sign_posn)},
510 #define localeconv() not_here("localeconv")
513 #ifdef HAS_LONG_DOUBLE
514 # if LONG_DOUBLESIZE > NVSIZE
515 # undef HAS_LONG_DOUBLE /* XXX until we figure out how to use them */
519 #ifndef HAS_LONG_DOUBLE
531 /* Background: in most systems the low byte of the wait status
532 * is the signal (the lowest 7 bits) and the coredump flag is
533 * the eight bit, and the second lowest byte is the exit status.
534 * BeOS bucks the trend and has the bytes in different order.
535 * See beos/beos.c for how the reality is bent even in BeOS
536 * to follow the traditional. However, to make the POSIX
537 * wait W*() macros to work in BeOS, we need to unbend the
538 * reality back in place. --jhi */
539 /* In actual fact the code below is to blame here. Perl has an internal
540 * representation of the exit status ($?), which it re-composes from the
541 * OS's representation using the W*() POSIX macros. The code below
542 * incorrectly uses the W*() macros on the internal representation,
543 * which fails for OSs that have a different representation (namely BeOS
544 * and Haiku). WMUNGE() is a hack that converts the internal
545 * representation into the OS specific one, so that the W*() macros work
546 * as expected. The better solution would be not to use the W*() macros
547 * in the first place, though. -- Ingo Weinhold
549 #if defined(__BEOS__) || defined(__HAIKU__)
550 # define WMUNGE(x) (((x) & 0xFF00) >> 8 | ((x) & 0x00FF) << 8)
552 # define WMUNGE(x) (x)
556 not_here(const char *s)
558 croak("POSIX::%s not implemented on this architecture", s);
562 #include "const-c.inc"
565 restore_sigmask(pTHX_ SV *osset_sv)
567 /* Fortunately, restoring the signal mask can't fail, because
568 * there's nothing we can do about it if it does -- we're not
569 * supposed to return -1 from sigaction unless the disposition
572 sigset_t *ossetp = (sigset_t *) SvPV_nolen( osset_sv );
573 (void)sigprocmask(SIG_SETMASK, ossetp, (sigset_t *)0);
577 allocate_struct(pTHX_ SV *rv, const STRLEN size, const char *packname) {
578 SV *const t = newSVrv(rv, packname);
579 void *const p = sv_grow(t, size + 1);
589 * (1) The CRT maintains its own copy of the environment, separate from
592 * (2) CRT getenv() retrieves from this copy. CRT putenv() updates this
593 * copy, and then calls SetEnvironmentVariableA() to update the Win32API
596 * (3) win32_getenv() and win32_putenv() call GetEnvironmentVariableA() and
597 * SetEnvironmentVariableA() directly, bypassing the CRT copy of the
600 * (4) The CRT strftime() "%Z" implementation calls __tzset(). That
601 * calls CRT tzset(), but only the first time it is called, and in turn
602 * that uses CRT getenv("TZ") to retrieve the timezone info from the CRT
603 * local copy of the environment and hence gets the original setting as
604 * perl never updates the CRT copy when assigning to $ENV{TZ}.
606 * Therefore, we need to retrieve the value of $ENV{TZ} and call CRT
607 * putenv() to update the CRT copy of the environment (if it is different)
608 * whenever we're about to call tzset().
610 * In addition to all that, when perl is built with PERL_IMPLICIT_SYS
613 * (a) Each interpreter has its own copy of the environment inside the
614 * perlhost structure. That allows applications that host multiple
615 * independent Perl interpreters to isolate environment changes from
616 * each other. (This is similar to how the perlhost mechanism keeps a
617 * separate working directory for each Perl interpreter, so that calling
618 * chdir() will not affect other interpreters.)
620 * (b) Only the first Perl interpreter instantiated within a process will
621 * "write through" environment changes to the process environment.
623 * (c) Even the primary Perl interpreter won't update the CRT copy of the
624 * the environment, only the Win32API copy (it calls win32_putenv()).
626 * As with CPerlHost::Getenv() and CPerlHost::Putenv() themselves, it makes
627 * sense to only update the process environment when inside the main
628 * interpreter, but we don't have access to CPerlHost's m_bTopLevel member
629 * from here so we'll just have to check PL_curinterp instead.
631 * Therefore, we can simply #undef getenv() and putenv() so that those names
632 * always refer to the CRT functions, and explicitly call win32_getenv() to
633 * access perl's %ENV.
635 * We also #undef malloc() and free() to be sure we are using the CRT
636 * functions otherwise under PERL_IMPLICIT_SYS they are redefined to calls
637 * into VMem::Malloc() and VMem::Free() and all allocations will be freed
638 * when the Perl interpreter is being destroyed so we'd end up with a pointer
639 * into deallocated memory in environ[] if a program embedding a Perl
640 * interpreter continues to operate even after the main Perl interpreter has
643 * Note that we don't free() the malloc()ed memory unless and until we call
644 * malloc() again ourselves because the CRT putenv() function simply puts its
645 * pointer argument into the environ[] array (it doesn't make a copy of it)
646 * so this memory must otherwise be leaked.
655 fix_win32_tzenv(void)
657 static char* oldenv = NULL;
659 const char* perl_tz_env = win32_getenv("TZ");
660 const char* crt_tz_env = getenv("TZ");
661 if (perl_tz_env == NULL)
663 if (crt_tz_env == NULL)
665 if (strcmp(perl_tz_env, crt_tz_env) != 0) {
666 newenv = (char*)malloc((strlen(perl_tz_env) + 4) * sizeof(char));
667 if (newenv != NULL) {
668 sprintf(newenv, "TZ=%s", perl_tz_env);
680 * my_tzset - wrapper to tzset() with a fix to make it work (better) on Win32.
681 * This code is duplicated in the Time-Piece module, so any changes made here
682 * should be made there too.
688 #if defined(USE_ITHREADS) && defined(PERL_IMPLICIT_SYS)
689 if (PL_curinterp == aTHX)
696 typedef int (*isfunc_t)(int);
697 typedef void (*any_dptr_t)(void *);
699 /* This needs to be ALIASed in a custom way, hence can't easily be defined as
701 static XSPROTO(is_common); /* prototype to pass -Wmissing-prototypes */
702 static XSPROTO(is_common)
707 croak_xs_usage(cv, "charstring");
713 unsigned char *s = (unsigned char *) SvPV(ST(0), len);
714 unsigned char *e = s + len;
715 isfunc_t isfunc = (isfunc_t) XSANY.any_dptr;
717 for (RETVAL = 1; RETVAL && s < e; s++)
726 MODULE = POSIX PACKAGE = POSIX
731 const char *file = __FILE__;
733 /* Ensure we get the function, not a macro implementation. Like the C89
734 standard says we can... */
736 cv = newXS("POSIX::isalnum", is_common, file);
737 XSANY.any_dptr = (any_dptr_t) &isalnum;
739 cv = newXS("POSIX::isalpha", is_common, file);
740 XSANY.any_dptr = (any_dptr_t) &isalpha;
742 cv = newXS("POSIX::iscntrl", is_common, file);
743 XSANY.any_dptr = (any_dptr_t) &iscntrl;
745 cv = newXS("POSIX::isdigit", is_common, file);
746 XSANY.any_dptr = (any_dptr_t) &isdigit;
748 cv = newXS("POSIX::isgraph", is_common, file);
749 XSANY.any_dptr = (any_dptr_t) &isgraph;
751 cv = newXS("POSIX::islower", is_common, file);
752 XSANY.any_dptr = (any_dptr_t) &islower;
754 cv = newXS("POSIX::isprint", is_common, file);
755 XSANY.any_dptr = (any_dptr_t) &isprint;
757 cv = newXS("POSIX::ispunct", is_common, file);
758 XSANY.any_dptr = (any_dptr_t) &ispunct;
760 cv = newXS("POSIX::isspace", is_common, file);
761 XSANY.any_dptr = (any_dptr_t) &isspace;
763 cv = newXS("POSIX::isupper", is_common, file);
764 XSANY.any_dptr = (any_dptr_t) &isupper;
766 cv = newXS("POSIX::isxdigit", is_common, file);
767 XSANY.any_dptr = (any_dptr_t) &isxdigit;
770 MODULE = SigSet PACKAGE = POSIX::SigSet PREFIX = sig
773 new(packname = "POSIX::SigSet", ...)
774 const char * packname
779 = (sigset_t *) allocate_struct(aTHX_ (ST(0) = sv_newmortal()),
783 for (i = 1; i < items; i++)
784 sigaddset(s, SvIV(ST(i)));
795 RETVAL = ix ? sigdelset(sigset, sig) : sigaddset(sigset, sig);
805 RETVAL = ix ? sigfillset(sigset) : sigemptyset(sigset);
810 sigismember(sigset, sig)
814 MODULE = Termios PACKAGE = POSIX::Termios PREFIX = cf
817 new(packname = "POSIX::Termios", ...)
818 const char * packname
822 void *const p = allocate_struct(aTHX_ (ST(0) = sv_newmortal()),
823 sizeof(struct termios), packname);
824 /* The previous implementation stored a pointer to an uninitialised
825 struct termios. Seems safer to initialise it, particularly as
826 this implementation exposes the struct to prying from perl-space.
828 memset(p, 0, 1 + sizeof(struct termios));
836 getattr(termios_ref, fd = 0)
837 POSIX::Termios termios_ref
840 RETVAL = tcgetattr(fd, termios_ref);
844 # If we define TCSANOW here then both a found and not found constant sub
845 # are created causing a Constant subroutine TCSANOW redefined warning
847 # define DEF_SETATTR_ACTION 0
849 # define DEF_SETATTR_ACTION TCSANOW
852 setattr(termios_ref, fd = 0, optional_actions = DEF_SETATTR_ACTION)
853 POSIX::Termios termios_ref
857 /* The second argument to the call is mandatory, but we'd like to give
858 it a useful default. 0 isn't valid on all operating systems - on
859 Solaris (at least) TCSANOW, TCSADRAIN and TCSAFLUSH have the same
860 values as the equivalent ioctls, TCSETS, TCSETSW and TCSETSF. */
861 RETVAL = tcsetattr(fd, optional_actions, termios_ref);
866 getispeed(termios_ref)
867 POSIX::Termios termios_ref
871 RETVAL = ix ? cfgetospeed(termios_ref) : cfgetispeed(termios_ref);
876 getiflag(termios_ref)
877 POSIX::Termios termios_ref
883 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
886 RETVAL = termios_ref->c_iflag;
889 RETVAL = termios_ref->c_oflag;
892 RETVAL = termios_ref->c_cflag;
895 RETVAL = termios_ref->c_lflag;
899 not_here(GvNAME(CvGV(cv)));
906 getcc(termios_ref, ccix)
907 POSIX::Termios termios_ref
910 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
912 croak("Bad getcc subscript");
913 RETVAL = termios_ref->c_cc[ccix];
922 setispeed(termios_ref, speed)
923 POSIX::Termios termios_ref
929 ? cfsetospeed(termios_ref, speed) : cfsetispeed(termios_ref, speed);
934 setiflag(termios_ref, flag)
935 POSIX::Termios termios_ref
942 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
945 termios_ref->c_iflag = flag;
948 termios_ref->c_oflag = flag;
951 termios_ref->c_cflag = flag;
954 termios_ref->c_lflag = flag;
958 not_here(GvNAME(CvGV(cv)));
962 setcc(termios_ref, ccix, cc)
963 POSIX::Termios termios_ref
967 #ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
969 croak("Bad setcc subscript");
970 termios_ref->c_cc[ccix] = cc;
976 MODULE = POSIX PACKAGE = POSIX
978 INCLUDE: const-xs.inc
985 POSIX::WIFSIGNALED = 2
986 POSIX::WIFSTOPPED = 3
990 #if !defined(WEXITSTATUS) || !defined(WIFEXITED) || !defined(WIFSIGNALED) \
991 || !defined(WIFSTOPPED) || !defined(WSTOPSIG) || !defined(WTERMSIG)
992 RETVAL = 0; /* Silence compilers that notice this, but don't realise
993 that not_here() can't return. */
998 RETVAL = WEXITSTATUS(WMUNGE(status));
1000 not_here("WEXITSTATUS");
1005 RETVAL = WIFEXITED(WMUNGE(status));
1007 not_here("WIFEXITED");
1012 RETVAL = WIFSIGNALED(WMUNGE(status));
1014 not_here("WIFSIGNALED");
1019 RETVAL = WIFSTOPPED(WMUNGE(status));
1021 not_here("WIFSTOPPED");
1026 RETVAL = WSTOPSIG(WMUNGE(status));
1028 not_here("WSTOPSIG");
1033 RETVAL = WTERMSIG(WMUNGE(status));
1035 not_here("WTERMSIG");
1039 Perl_croak(aTHX_ "Illegal alias %d for POSIX::W*", (int)ix);
1045 open(filename, flags = O_RDONLY, mode = 0666)
1050 if (flags & (O_APPEND|O_CREAT|O_TRUNC|O_RDWR|O_WRONLY|O_EXCL))
1051 TAINT_PROPER("open");
1052 RETVAL = open(filename, flags, mode);
1060 #ifdef HAS_LOCALECONV
1061 struct lconv *lcbuf;
1063 sv_2mortal((SV*)RETVAL);
1064 if ((lcbuf = localeconv())) {
1065 const struct lconv_offset *strings = lconv_strings;
1066 const struct lconv_offset *integers = lconv_integers;
1067 const char *ptr = (const char *) lcbuf;
1070 const char *value = *((const char **)(ptr + strings->offset));
1072 if (value && *value)
1073 (void) hv_store(RETVAL, strings->name, strlen(strings->name),
1074 newSVpv(value, 0), 0);
1075 } while ((++strings)->name);
1078 const char value = *((const char *)(ptr + integers->offset));
1080 if (value != CHAR_MAX)
1081 (void) hv_store(RETVAL, integers->name,
1082 strlen(integers->name), newSViv(value), 0);
1083 } while ((++integers)->name);
1086 localeconv(); /* A stub to call not_here(). */
1092 setlocale(category, locale = 0)
1098 retval = setlocale(category, locale);
1100 /* Save retval since subsequent setlocale() calls
1101 * may overwrite it. */
1102 RETVAL = savepv(retval);
1103 #ifdef USE_LOCALE_CTYPE
1104 if (category == LC_CTYPE
1106 || category == LC_ALL
1112 if (category == LC_ALL)
1113 newctype = setlocale(LC_CTYPE, NULL);
1117 new_ctype(newctype);
1119 #endif /* USE_LOCALE_CTYPE */
1120 #ifdef USE_LOCALE_COLLATE
1121 if (category == LC_COLLATE
1123 || category == LC_ALL
1129 if (category == LC_ALL)
1130 newcoll = setlocale(LC_COLLATE, NULL);
1134 new_collate(newcoll);
1136 #endif /* USE_LOCALE_COLLATE */
1137 #ifdef USE_LOCALE_NUMERIC
1138 if (category == LC_NUMERIC
1140 || category == LC_ALL
1146 if (category == LC_ALL)
1147 newnum = setlocale(LC_NUMERIC, NULL);
1151 new_numeric(newnum);
1153 #endif /* USE_LOCALE_NUMERIC */
1221 /* (We already know stack is long enough.) */
1222 PUSHs(sv_2mortal(newSVnv(frexp(x,&expvar))));
1223 PUSHs(sv_2mortal(newSViv(expvar)));
1235 /* (We already know stack is long enough.) */
1236 PUSHs(sv_2mortal(newSVnv(Perl_modf(x,&intvar))));
1237 PUSHs(sv_2mortal(newSVnv(intvar)));
1240 sigaction(sig, optaction, oldaction = 0)
1243 POSIX::SigAction oldaction
1245 #if defined(WIN32) || defined(NETWARE)
1246 RETVAL = not_here("sigaction");
1248 # This code is really grody because we're trying to make the signal
1249 # interface look beautiful, which is hard.
1253 POSIX__SigAction action;
1254 GV *siggv = gv_fetchpvs("SIG", GV_ADD, SVt_PVHV);
1255 struct sigaction act;
1256 struct sigaction oact;
1260 POSIX__SigSet sigset;
1265 croak("Negative signals are not allowed");
1268 if (sig == 0 && SvPOK(ST(0))) {
1269 const char *s = SvPVX_const(ST(0));
1270 int i = whichsig(s);
1272 if (i < 0 && memEQ(s, "SIG", 3))
1273 i = whichsig(s + 3);
1275 if (ckWARN(WARN_SIGNAL))
1276 Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
1277 "No such signal: SIG%s", s);
1284 if (sig > NSIG) { /* NSIG - 1 is still okay. */
1285 Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
1286 "No such signal: %d", sig);
1290 sigsvp = hv_fetch(GvHVn(siggv),
1292 strlen(PL_sig_name[sig]),
1295 /* Check optaction and set action */
1296 if(SvTRUE(optaction)) {
1297 if(sv_isa(optaction, "POSIX::SigAction"))
1298 action = (HV*)SvRV(optaction);
1300 croak("action is not of type POSIX::SigAction");
1306 /* sigaction() is supposed to look atomic. In particular, any
1307 * signal handler invoked during a sigaction() call should
1308 * see either the old or the new disposition, and not something
1309 * in between. We use sigprocmask() to make it so.
1312 RETVAL=sigprocmask(SIG_BLOCK, &sset, &osset);
1316 /* Restore signal mask no matter how we exit this block. */
1317 osset_sv = newSVpvn((char *)(&osset), sizeof(sigset_t));
1318 SAVEFREESV( osset_sv );
1319 SAVEDESTRUCTOR_X(restore_sigmask, osset_sv);
1321 RETVAL=-1; /* In case both oldaction and action are 0. */
1323 /* Remember old disposition if desired. */
1325 svp = hv_fetchs(oldaction, "HANDLER", TRUE);
1327 croak("Can't supply an oldaction without a HANDLER");
1328 if(SvTRUE(*sigsvp)) { /* TBD: what if "0"? */
1329 sv_setsv(*svp, *sigsvp);
1332 sv_setpvs(*svp, "DEFAULT");
1334 RETVAL = sigaction(sig, (struct sigaction *)0, & oact);
1339 /* Get back the mask. */
1340 svp = hv_fetchs(oldaction, "MASK", TRUE);
1341 if (sv_isa(*svp, "POSIX::SigSet")) {
1342 sigset = (sigset_t *) SvPV_nolen(SvRV(*svp));
1345 sigset = (sigset_t *) allocate_struct(aTHX_ *svp,
1349 *sigset = oact.sa_mask;
1351 /* Get back the flags. */
1352 svp = hv_fetchs(oldaction, "FLAGS", TRUE);
1353 sv_setiv(*svp, oact.sa_flags);
1355 /* Get back whether the old handler used safe signals. */
1356 svp = hv_fetchs(oldaction, "SAFE", TRUE);
1358 /* compare incompatible pointers by casting to integer */
1359 PTR2nat(oact.sa_handler) == PTR2nat(PL_csighandlerp));
1363 /* Safe signals use "csighandler", which vectors through the
1364 PL_sighandlerp pointer when it's safe to do so.
1365 (BTW, "csighandler" is very different from "sighandler".) */
1366 svp = hv_fetchs(action, "SAFE", FALSE);
1370 (*svp && SvTRUE(*svp))
1371 ? PL_csighandlerp : PL_sighandlerp
1374 /* Vector new Perl handler through %SIG.
1375 (The core signal handlers read %SIG to dispatch.) */
1376 svp = hv_fetchs(action, "HANDLER", FALSE);
1378 croak("Can't supply an action without a HANDLER");
1379 sv_setsv(*sigsvp, *svp);
1381 /* This call actually calls sigaction() with almost the
1382 right settings, including appropriate interpretation
1383 of DEFAULT and IGNORE. However, why are we doing
1384 this when we're about to do it again just below? XXX */
1385 SvSETMAGIC(*sigsvp);
1387 /* And here again we duplicate -- DEFAULT/IGNORE checking. */
1389 const char *s=SvPVX_const(*svp);
1390 if(strEQ(s,"IGNORE")) {
1391 act.sa_handler = SIG_IGN;
1393 else if(strEQ(s,"DEFAULT")) {
1394 act.sa_handler = SIG_DFL;
1398 /* Set up any desired mask. */
1399 svp = hv_fetchs(action, "MASK", FALSE);
1400 if (svp && sv_isa(*svp, "POSIX::SigSet")) {
1401 sigset = (sigset_t *) SvPV_nolen(SvRV(*svp));
1402 act.sa_mask = *sigset;
1405 sigemptyset(& act.sa_mask);
1407 /* Set up any desired flags. */
1408 svp = hv_fetchs(action, "FLAGS", FALSE);
1409 act.sa_flags = svp ? SvIV(*svp) : 0;
1411 /* Don't worry about cleaning up *sigsvp if this fails,
1412 * because that means we tried to disposition a
1413 * nonblockable signal, in which case *sigsvp is
1414 * essentially meaningless anyway.
1416 RETVAL = sigaction(sig, & act, (struct sigaction *)0);
1431 POSIX::SigSet sigset
1435 RETVAL = ix ? sigsuspend(sigset) : sigpending(sigset);
1440 sigprocmask(how, sigset, oldsigset = 0)
1442 POSIX::SigSet sigset = NO_INIT
1443 POSIX::SigSet oldsigset = NO_INIT
1445 if (! SvOK(ST(1))) {
1447 } else if (sv_isa(ST(1), "POSIX::SigSet")) {
1448 sigset = (sigset_t *) SvPV_nolen(SvRV(ST(1)));
1450 croak("sigset is not of type POSIX::SigSet");
1453 if (items < 3 || ! SvOK(ST(2))) {
1455 } else if (sv_isa(ST(2), "POSIX::SigSet")) {
1456 oldsigset = (sigset_t *) SvPV_nolen(SvRV(ST(2)));
1458 croak("oldsigset is not of type POSIX::SigSet");
1471 lseek(fd, offset, whence)
1476 Off_t pos = PerlLIO_lseek(fd, offset, whence);
1477 RETVAL = sizeof(Off_t) > sizeof(IV)
1478 ? newSVnv((NV)pos) : newSViv((IV)pos);
1487 if ((incr = nice(incr)) != -1 || errno == 0) {
1489 XPUSHs(newSVpvs_flags("0 but true", SVs_TEMP));
1491 XPUSHs(sv_2mortal(newSViv(incr)));
1498 if (pipe(fds) != -1) {
1500 PUSHs(sv_2mortal(newSViv(fds[0])));
1501 PUSHs(sv_2mortal(newSViv(fds[1])));
1505 read(fd, buffer, nbytes)
1507 SV *sv_buffer = SvROK(ST(1)) ? SvRV(ST(1)) : ST(1);
1511 char * buffer = sv_grow( sv_buffer, nbytes+1 );
1514 SvCUR_set(sv_buffer, RETVAL);
1515 SvPOK_only(sv_buffer);
1516 *SvEND(sv_buffer) = '\0';
1517 SvTAINTED_on(sv_buffer);
1533 tcsetpgrp(fd, pgrp_id)
1542 if (uname(&buf) >= 0) {
1544 PUSHs(newSVpvn_flags(buf.sysname, strlen(buf.sysname), SVs_TEMP));
1545 PUSHs(newSVpvn_flags(buf.nodename, strlen(buf.nodename), SVs_TEMP));
1546 PUSHs(newSVpvn_flags(buf.release, strlen(buf.release), SVs_TEMP));
1547 PUSHs(newSVpvn_flags(buf.version, strlen(buf.version), SVs_TEMP));
1548 PUSHs(newSVpvn_flags(buf.machine, strlen(buf.machine), SVs_TEMP));
1551 uname((char *) 0); /* A stub to call not_here(). */
1555 write(fd, buffer, nbytes)
1566 RETVAL = newSVpvn("", 0);
1567 SvGROW(RETVAL, L_tmpnam);
1568 len = strlen(tmpnam(SvPV(RETVAL, i)));
1569 SvCUR_set(RETVAL, len);
1582 mbstowcs(s, pwcs, n)
1594 wcstombs(s, pwcs, n)
1616 SET_NUMERIC_LOCAL();
1617 num = strtod(str, &unparsed);
1618 PUSHs(sv_2mortal(newSVnv(num)));
1619 if (GIMME == G_ARRAY) {
1622 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1624 PUSHs(&PL_sv_undef);
1628 strtol(str, base = 0)
1635 num = strtol(str, &unparsed, base);
1636 #if IVSIZE <= LONGSIZE
1637 if (num < IV_MIN || num > IV_MAX)
1638 PUSHs(sv_2mortal(newSVnv((double)num)));
1641 PUSHs(sv_2mortal(newSViv((IV)num)));
1642 if (GIMME == G_ARRAY) {
1645 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1647 PUSHs(&PL_sv_undef);
1651 strtoul(str, base = 0)
1658 num = strtoul(str, &unparsed, base);
1659 #if IVSIZE <= LONGSIZE
1661 PUSHs(sv_2mortal(newSVnv((double)num)));
1664 PUSHs(sv_2mortal(newSViv((IV)num)));
1665 if (GIMME == G_ARRAY) {
1668 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1670 PUSHs(&PL_sv_undef);
1680 char *p = SvPV(src,srclen);
1682 ST(0) = sv_2mortal(newSV(srclen*4+1));
1683 dstlen = strxfrm(SvPVX(ST(0)), p, (size_t)srclen);
1684 if (dstlen > srclen) {
1686 SvGROW(ST(0), dstlen);
1687 strxfrm(SvPVX(ST(0)), p, (size_t)dstlen);
1690 SvCUR_set(ST(0), dstlen);
1695 mkfifo(filename, mode)
1702 RETVAL = access(filename, mode);
1704 TAINT_PROPER("mkfifo");
1705 RETVAL = mkfifo(filename, mode);
1717 RETVAL = ix == 1 ? close(fd)
1718 : (ix < 1 ? tcdrain(fd) : dup(fd));
1731 RETVAL = ix == 1 ? tcflush(fd, action)
1732 : (ix < 1 ? tcflow(fd, action) : tcsendbreak(fd, action));
1737 asctime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = -1)
1753 init_tm(&mytm); /* XXX workaround - see init_tm() above */
1756 mytm.tm_hour = hour;
1757 mytm.tm_mday = mday;
1759 mytm.tm_year = year;
1760 mytm.tm_wday = wday;
1761 mytm.tm_yday = yday;
1762 mytm.tm_isdst = isdst;
1764 const long result = mktime(&mytm);
1767 else if (result == 0)
1768 sv_setpvn(TARG, "0 but true", 10);
1770 sv_setiv(TARG, (IV)result);
1772 sv_setpv(TARG, asctime(&mytm));
1790 realtime = times( &tms );
1792 PUSHs( sv_2mortal( newSViv( (IV) realtime ) ) );
1793 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_utime ) ) );
1794 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_stime ) ) );
1795 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cutime ) ) );
1796 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cstime ) ) );
1799 difftime(time1, time2)
1803 #XXX: if $xsubpp::WantOptimize is always the default
1804 # sv_setpv(TARG, ...) could be used rather than
1805 # ST(0) = sv_2mortal(newSVpv(...))
1807 strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1)
1820 char *buf = my_strftime(SvPV_nolen(fmt), sec, min, hour, mday, mon, year, wday, yday, isdst);
1822 SV *const sv = sv_newmortal();
1823 sv_usepvn_flags(sv, buf, strlen(buf), SV_HAS_TRAILING_NUL);
1840 PUSHs(newSVpvn_flags(tzname[0], strlen(tzname[0]), SVs_TEMP));
1841 PUSHs(newSVpvn_flags(tzname[1], strlen(tzname[1]), SVs_TEMP));
1847 #ifdef HAS_CTERMID_R
1848 s = (char *) safemalloc((size_t) L_ctermid);
1850 RETVAL = ctermid(s);
1854 #ifdef HAS_CTERMID_R
1863 RETVAL = cuserid(s);
1866 not_here("cuserid");
1877 pathconf(filename, name)
1891 PL_egid = getegid();
1902 PL_euid = geteuid();
1920 XSprePUSH; PUSHTARG;
1924 lchown(uid, gid, path)
1930 /* yes, the order of arguments is different,
1931 * but consistent with CORE::chown() */
1932 RETVAL = lchown(path, uid, gid);
1934 RETVAL = not_here("lchown");