This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Add tests for POSIX::sigpending().
[perl5.git] / ext / POSIX / POSIX.xs
CommitLineData
6e22d046
JH
1#define PERL_EXT_POSIX
2
2986a63f
JH
3#ifdef NETWARE
4 #define _POSIX_
4efcf9a2
SB
5 /*
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
10 */
2986a63f
JH
11 #include <sys/utsname.h>
12#endif /* NETWARE */
13
c5be433b
GS
14#define PERL_NO_GET_CONTEXT
15
463ee0b2 16#include "EXTERN.h"
760ac839 17#define PERLIO_NOT_STDIO 1
463ee0b2
LW
18#include "perl.h"
19#include "XSUB.h"
acfe0abc 20#if defined(PERL_IMPLICIT_SYS)
873ef191
GS
21# undef signal
22# undef open
cd661bb6 23# undef setmode
35ff7856 24# define open PerlLIO_open3
873ef191 25#endif
2304df62 26#include <ctype.h>
a0d0e21e 27#ifdef I_DIRENT /* XXX maybe better to just rely on perl.h? */
2304df62 28#include <dirent.h>
a0d0e21e 29#endif
2304df62 30#include <errno.h>
2304df62
AD
31#ifdef I_FLOAT
32#include <float.h>
33#endif
a0d0e21e 34#ifdef I_LIMITS
2304df62 35#include <limits.h>
a0d0e21e 36#endif
2304df62
AD
37#include <locale.h>
38#include <math.h>
85e6fe83 39#ifdef I_PWD
2304df62 40#include <pwd.h>
85e6fe83 41#endif
2304df62
AD
42#include <setjmp.h>
43#include <signal.h>
2304df62 44#include <stdarg.h>
17c3b450 45
2304df62
AD
46#ifdef I_STDDEF
47#include <stddef.h>
48#endif
6990d991 49
b5846a0b
BS
50#ifdef I_UNISTD
51#include <unistd.h>
52#endif
53
3609ea0d 54/* XXX This comment is just to make I_TERMIO and I_SGTTY visible to
a0d0e21e
LW
55 metaconfig for future extension writers. We don't use them in POSIX.
56 (This is really sneaky :-) --AD
57*/
58#if defined(I_TERMIOS)
59#include <termios.h>
60#endif
a0d0e21e 61#ifdef I_STDLIB
2304df62 62#include <stdlib.h>
a0d0e21e 63#endif
5518ecd4 64#ifndef __ultrix__
2304df62 65#include <string.h>
5518ecd4 66#endif
2304df62 67#include <sys/stat.h>
2304df62 68#include <sys/types.h>
2304df62 69#include <time.h>
6dead956 70#ifdef I_UNISTD
1d2dff63 71#include <unistd.h>
6dead956 72#endif
71be2cbc
PP
73#include <fcntl.h>
74
e2465f50 75#ifdef HAS_TZNAME
fb207d52 76# if !defined(WIN32) && !defined(__CYGWIN__) && !defined(NETWARE) && !defined(__UWIN__)
e2465f50
JH
77extern char *tzname[];
78# endif
79#else
fb207d52 80#if !defined(WIN32) && !defined(__UWIN__) || (defined(__MINGW32__) && !defined(tzname))
e2465f50
JH
81char *tzname[] = { "" , "" };
82#endif
cb2479a8
JH
83#endif
84
aec614a5
NC
85#ifndef PERL_UNUSED_DECL
86# ifdef HASATTRIBUTE
87# if (defined(__GNUC__) && defined(__cplusplus)) || defined(__INTEL_COMPILER)
88# define PERL_UNUSED_DECL
89# else
90# define PERL_UNUSED_DECL __attribute__((unused))
91# endif
27da23d5 92# else
aec614a5 93# define PERL_UNUSED_DECL
27da23d5 94# endif
27da23d5
JH
95#endif
96
97#ifndef dNOOP
98#define dNOOP extern int Perl___notused PERL_UNUSED_DECL
99#endif
100
101#ifndef dVAR
102#define dVAR dNOOP
103#endif
104
6c418a22 105#if defined(__VMS) && !defined(__POSIX_SOURCE)
6c418a22
PP
106# include <libdef.h> /* LIB$_INVARG constant */
107# include <lib$routines.h> /* prototype for lib$ediv() */
108# include <starlet.h> /* prototype for sys$gettim() */
774d564b 109# if DECC_VERSION < 50000000
86200d5c 110# define pid_t int /* old versions of DECC miss this in types.h */
774d564b 111# endif
6c418a22 112
6990d991 113# undef mkfifo
6c418a22
PP
114# define mkfifo(a,b) (not_here("mkfifo"),-1)
115# define tzset() not_here("tzset")
116
5f6761f9
DS
117#if ((__VMS_VER >= 70000000) && (__DECC_VER >= 50200000)) || (__CRTL_VER >= 70000000)
118# define HAS_TZNAME /* shows up in VMS 7.0 or Dec C 5.6 */
119# include <utsname.h>
5f6761f9 120# endif /* __VMS_VER >= 70000000 or Dec C 5.6 */
6c418a22
PP
121
122 /* The POSIX notion of ttyname() is better served by getname() under VMS */
123 static char ttnambuf[64];
124# define ttyname(fd) (isatty(fd) > 0 ? getname(fd,ttnambuf,0) : NULL)
125
126 /* The non-POSIX CRTL times() has void return type, so we just get the
127 current time directly */
34f7a5fe 128 clock_t vms_times(struct tms *bufptr) {
d28f7c37 129 dTHX;
6c418a22
PP
130 clock_t retval;
131 /* Get wall time and convert to 10 ms intervals to
132 * produce the return value that the POSIX standard expects */
133# if defined(__DECC) && defined (__ALPHA)
134# include <ints.h>
135 uint64 vmstime;
136 _ckvmssts(sys$gettim(&vmstime));
137 vmstime /= 100000;
138 retval = vmstime & 0x7fffffff;
139# else
140 /* (Older hw or ccs don't have an atomic 64-bit type, so we
141 * juggle 32-bit ints (and a float) to produce a time_t result
142 * with minimal loss of information.) */
143 long int vmstime[2],remainder,divisor = 100000;
144 _ckvmssts(sys$gettim((unsigned long int *)vmstime));
145 vmstime[1] &= 0x7fff; /* prevent overflow in EDIV */
146 _ckvmssts(lib$ediv(&divisor,vmstime,(long int *)&retval,&remainder));
147# endif
148 /* Fill in the struct tms using the CRTL routine . . .*/
34f7a5fe 149 times((tbuffer_t *)bufptr);
6c418a22
PP
150 return (clock_t) retval;
151 }
152# define times(t) vms_times(t)
153#else
d308986b 154#if defined (__CYGWIN__)
f89d6eaa
FE
155# define tzname _tzname
156#endif
2986a63f 157#if defined (WIN32) || defined (NETWARE)
6990d991 158# undef mkfifo
6dead956 159# define mkfifo(a,b) not_here("mkfifo")
873ef191 160# define ttyname(a) (char*)not_here("ttyname")
6dead956 161# define sigset_t long
86200d5c 162# define pid_t long
6dead956
GS
163# ifdef _MSC_VER
164# define mode_t short
165# endif
62520c91
GS
166# ifdef __MINGW32__
167# define mode_t short
f6c6487a
GS
168# ifndef tzset
169# define tzset() not_here("tzset")
170# endif
171# ifndef _POSIX_OPEN_MAX
172# define _POSIX_OPEN_MAX FOPEN_MAX /* XXX bogus ? */
173# endif
62520c91 174# endif
6dead956
GS
175# define sigaction(a,b,c) not_here("sigaction")
176# define sigpending(a) not_here("sigpending")
177# define sigprocmask(a,b,c) not_here("sigprocmask")
178# define sigsuspend(a) not_here("sigsuspend")
179# define sigemptyset(a) not_here("sigemptyset")
180# define sigaddset(a,b) not_here("sigaddset")
181# define sigdelset(a,b) not_here("sigdelset")
182# define sigfillset(a) not_here("sigfillset")
183# define sigismember(a,b) not_here("sigismember")
2986a63f 184#ifndef NETWARE
6e22d046
JH
185# undef setuid
186# undef setgid
2986a63f
JH
187# define setuid(a) not_here("setuid")
188# define setgid(a) not_here("setgid")
189#endif /* NETWARE */
6dead956 190#else
6990d991
JH
191
192# ifndef HAS_MKFIFO
e37778c2 193# if defined(OS2)
d6a255e6 194# define mkfifo(a,b) not_here("mkfifo")
3609ea0d 195# else /* !( defined OS2 ) */
d6a255e6
IZ
196# ifndef mkfifo
197# define mkfifo(path, mode) (mknod((path), (mode) | S_IFIFO, 0))
198# endif
6990d991
JH
199# endif
200# endif /* !HAS_MKFIFO */
201
e37778c2
NC
202# ifdef I_GRP
203# include <grp.h>
204# endif
205# include <sys/times.h>
206# ifdef HAS_UNAME
207# include <sys/utsname.h>
6c418a22 208# endif
e37778c2 209# include <sys/wait.h>
6c418a22
PP
210# ifdef I_UTIME
211# include <utime.h>
212# endif
2986a63f 213#endif /* WIN32 || NETWARE */
6dead956 214#endif /* __VMS */
2304df62 215
2489f03d
JD
216#ifdef WIN32
217 /* Perl on Windows assigns WSAGetLastError() return values to errno
218 * (in win32/win32sck.c). Therefore we need to map these values
b59e75b3
SH
219 * back to standard symbolic names, but only for those names having
220 * no existing value or an existing value >= 100. (VC++ 2010 defines
221 * a group of names with values >= 100 in its errno.h which we *do*
222 * need to redefine.) The Errno.pm module does a similar mapping.
2489f03d 223 */
b59e75b3
SH
224# ifdef EWOULDBLOCK
225# undef EWOULDBLOCK
2489f03d 226# endif
b59e75b3
SH
227# define EWOULDBLOCK WSAEWOULDBLOCK
228# ifdef EINPROGRESS
229# undef EINPROGRESS
2489f03d 230# endif
b59e75b3
SH
231# define EINPROGRESS WSAEINPROGRESS
232# ifdef EALREADY
233# undef EALREADY
2489f03d 234# endif
b59e75b3
SH
235# define EALREADY WSAEALREADY
236# ifdef ENOTSOCK
237# undef ENOTSOCK
2489f03d 238# endif
b59e75b3
SH
239# define ENOTSOCK WSAENOTSOCK
240# ifdef EDESTADDRREQ
241# undef EDESTADDRREQ
2489f03d 242# endif
b59e75b3
SH
243# define EDESTADDRREQ WSAEDESTADDRREQ
244# ifdef EMSGSIZE
245# undef EMSGSIZE
2489f03d 246# endif
b59e75b3
SH
247# define EMSGSIZE WSAEMSGSIZE
248# ifdef EPROTOTYPE
249# undef EPROTOTYPE
2489f03d 250# endif
b59e75b3
SH
251# define EPROTOTYPE WSAEPROTOTYPE
252# ifdef ENOPROTOOPT
253# undef ENOPROTOOPT
2489f03d 254# endif
b59e75b3
SH
255# define ENOPROTOOPT WSAENOPROTOOPT
256# ifdef EPROTONOSUPPORT
257# undef EPROTONOSUPPORT
2489f03d 258# endif
b59e75b3
SH
259# define EPROTONOSUPPORT WSAEPROTONOSUPPORT
260# ifdef ESOCKTNOSUPPORT
261# undef ESOCKTNOSUPPORT
2489f03d 262# endif
b59e75b3
SH
263# define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
264# ifdef EOPNOTSUPP
265# undef EOPNOTSUPP
2489f03d 266# endif
b59e75b3
SH
267# define EOPNOTSUPP WSAEOPNOTSUPP
268# ifdef EPFNOSUPPORT
269# undef EPFNOSUPPORT
2489f03d 270# endif
b59e75b3
SH
271# define EPFNOSUPPORT WSAEPFNOSUPPORT
272# ifdef EAFNOSUPPORT
273# undef EAFNOSUPPORT
2489f03d 274# endif
b59e75b3
SH
275# define EAFNOSUPPORT WSAEAFNOSUPPORT
276# ifdef EADDRINUSE
277# undef EADDRINUSE
2489f03d 278# endif
b59e75b3
SH
279# define EADDRINUSE WSAEADDRINUSE
280# ifdef EADDRNOTAVAIL
281# undef EADDRNOTAVAIL
2489f03d 282# endif
b59e75b3
SH
283# define EADDRNOTAVAIL WSAEADDRNOTAVAIL
284# ifdef ENETDOWN
285# undef ENETDOWN
2489f03d 286# endif
b59e75b3
SH
287# define ENETDOWN WSAENETDOWN
288# ifdef ENETUNREACH
289# undef ENETUNREACH
2489f03d 290# endif
b59e75b3
SH
291# define ENETUNREACH WSAENETUNREACH
292# ifdef ENETRESET
293# undef ENETRESET
2489f03d 294# endif
b59e75b3
SH
295# define ENETRESET WSAENETRESET
296# ifdef ECONNABORTED
297# undef ECONNABORTED
2489f03d 298# endif
b59e75b3
SH
299# define ECONNABORTED WSAECONNABORTED
300# ifdef ECONNRESET
301# undef ECONNRESET
2489f03d 302# endif
b59e75b3
SH
303# define ECONNRESET WSAECONNRESET
304# ifdef ENOBUFS
305# undef ENOBUFS
2489f03d 306# endif
b59e75b3
SH
307# define ENOBUFS WSAENOBUFS
308# ifdef EISCONN
309# undef EISCONN
2489f03d 310# endif
b59e75b3
SH
311# define EISCONN WSAEISCONN
312# ifdef ENOTCONN
313# undef ENOTCONN
2489f03d 314# endif
b59e75b3
SH
315# define ENOTCONN WSAENOTCONN
316# ifdef ESHUTDOWN
317# undef ESHUTDOWN
2489f03d 318# endif
b59e75b3
SH
319# define ESHUTDOWN WSAESHUTDOWN
320# ifdef ETOOMANYREFS
321# undef ETOOMANYREFS
2489f03d 322# endif
b59e75b3
SH
323# define ETOOMANYREFS WSAETOOMANYREFS
324# ifdef ETIMEDOUT
325# undef ETIMEDOUT
2489f03d 326# endif
b59e75b3
SH
327# define ETIMEDOUT WSAETIMEDOUT
328# ifdef ECONNREFUSED
329# undef ECONNREFUSED
2489f03d 330# endif
b59e75b3
SH
331# define ECONNREFUSED WSAECONNREFUSED
332# ifdef ELOOP
333# undef ELOOP
2489f03d 334# endif
b59e75b3
SH
335# define ELOOP WSAELOOP
336# ifdef EHOSTDOWN
337# undef EHOSTDOWN
2489f03d 338# endif
b59e75b3
SH
339# define EHOSTDOWN WSAEHOSTDOWN
340# ifdef EHOSTUNREACH
341# undef EHOSTUNREACH
2489f03d 342# endif
b59e75b3
SH
343# define EHOSTUNREACH WSAEHOSTUNREACH
344# ifdef EPROCLIM
345# undef EPROCLIM
2489f03d 346# endif
b59e75b3
SH
347# define EPROCLIM WSAEPROCLIM
348# ifdef EUSERS
349# undef EUSERS
2489f03d 350# endif
b59e75b3
SH
351# define EUSERS WSAEUSERS
352# ifdef EDQUOT
353# undef EDQUOT
2489f03d 354# endif
b59e75b3
SH
355# define EDQUOT WSAEDQUOT
356# ifdef ESTALE
357# undef ESTALE
2489f03d 358# endif
b59e75b3
SH
359# define ESTALE WSAESTALE
360# ifdef EREMOTE
361# undef EREMOTE
2489f03d 362# endif
b59e75b3
SH
363# define EREMOTE WSAEREMOTE
364# ifdef EDISCON
365# undef EDISCON
2489f03d 366# endif
b59e75b3 367# define EDISCON WSAEDISCON
2489f03d
JD
368#endif
369
2304df62 370typedef int SysRet;
a0d0e21e 371typedef long SysRetLong;
2304df62
AD
372typedef sigset_t* POSIX__SigSet;
373typedef HV* POSIX__SigAction;
a0d0e21e
LW
374#ifdef I_TERMIOS
375typedef struct termios* POSIX__Termios;
376#else /* Define termios types to int, and call not_here for the functions.*/
377#define POSIX__Termios int
378#define speed_t int
379#define tcflag_t int
380#define cc_t int
381#define cfgetispeed(x) not_here("cfgetispeed")
382#define cfgetospeed(x) not_here("cfgetospeed")
383#define tcdrain(x) not_here("tcdrain")
384#define tcflush(x,y) not_here("tcflush")
385#define tcsendbreak(x,y) not_here("tcsendbreak")
386#define cfsetispeed(x,y) not_here("cfsetispeed")
387#define cfsetospeed(x,y) not_here("cfsetospeed")
388#define ctermid(x) (char *) not_here("ctermid")
389#define tcflow(x,y) not_here("tcflow")
390#define tcgetattr(x,y) not_here("tcgetattr")
391#define tcsetattr(x,y,z) not_here("tcsetattr")
392#endif
393
394/* Possibly needed prototypes */
6e22d046 395#ifndef WIN32
20ce7b12
GS
396double strtod (const char *, char **);
397long strtol (const char *, char **, int);
398unsigned long strtoul (const char *, char **, int);
6e22d046 399#endif
a0d0e21e 400
a0d0e21e
LW
401#ifndef HAS_DIFFTIME
402#ifndef difftime
403#define difftime(a,b) not_here("difftime")
404#endif
405#endif
406#ifndef HAS_FPATHCONF
3609ea0d 407#define fpathconf(f,n) (SysRetLong) not_here("fpathconf")
a0d0e21e
LW
408#endif
409#ifndef HAS_MKTIME
410#define mktime(a) not_here("mktime")
8990e307
LW
411#endif
412#ifndef HAS_NICE
413#define nice(a) not_here("nice")
414#endif
a0d0e21e 415#ifndef HAS_PATHCONF
3609ea0d 416#define pathconf(f,n) (SysRetLong) not_here("pathconf")
a0d0e21e
LW
417#endif
418#ifndef HAS_SYSCONF
3609ea0d 419#define sysconf(n) (SysRetLong) not_here("sysconf")
a0d0e21e 420#endif
8990e307
LW
421#ifndef HAS_READLINK
422#define readlink(a,b,c) not_here("readlink")
423#endif
424#ifndef HAS_SETPGID
425#define setpgid(a,b) not_here("setpgid")
426#endif
8990e307
LW
427#ifndef HAS_SETSID
428#define setsid() not_here("setsid")
429#endif
a0d0e21e
LW
430#ifndef HAS_STRCOLL
431#define strcoll(s1,s2) not_here("strcoll")
432#endif
a89d8a78
DH
433#ifndef HAS_STRTOD
434#define strtod(s1,s2) not_here("strtod")
435#endif
436#ifndef HAS_STRTOL
437#define strtol(s1,s2,b) not_here("strtol")
438#endif
439#ifndef HAS_STRTOUL
440#define strtoul(s1,s2,b) not_here("strtoul")
441#endif
a0d0e21e
LW
442#ifndef HAS_STRXFRM
443#define strxfrm(s1,s2,n) not_here("strxfrm")
8990e307
LW
444#endif
445#ifndef HAS_TCGETPGRP
446#define tcgetpgrp(a) not_here("tcgetpgrp")
447#endif
448#ifndef HAS_TCSETPGRP
449#define tcsetpgrp(a,b) not_here("tcsetpgrp")
450#endif
451#ifndef HAS_TIMES
2986a63f 452#ifndef NETWARE
8990e307 453#define times(a) not_here("times")
2986a63f 454#endif /* NETWARE */
8990e307
LW
455#endif
456#ifndef HAS_UNAME
457#define uname(a) not_here("uname")
458#endif
459#ifndef HAS_WAITPID
460#define waitpid(a,b,c) not_here("waitpid")
461#endif
462
a0d0e21e
LW
463#ifndef HAS_MBLEN
464#ifndef mblen
465#define mblen(a,b) not_here("mblen")
466#endif
467#endif
468#ifndef HAS_MBSTOWCS
469#define mbstowcs(s, pwcs, n) not_here("mbstowcs")
470#endif
471#ifndef HAS_MBTOWC
472#define mbtowc(pwc, s, n) not_here("mbtowc")
473#endif
474#ifndef HAS_WCSTOMBS
475#define wcstombs(s, pwcs, n) not_here("wcstombs")
476#endif
477#ifndef HAS_WCTOMB
478#define wctomb(s, wchar) not_here("wcstombs")
479#endif
480#if !defined(HAS_MBLEN) && !defined(HAS_MBSTOWCS) && !defined(HAS_MBTOWC) && !defined(HAS_WCSTOMBS) && !defined(HAS_WCTOMB)
481/* If we don't have these functions, then we wouldn't have gotten a typedef
482 for wchar_t, the wide character type. Defining wchar_t allows the
483 functions referencing it to compile. Its actual type is then meaningless,
484 since without the above functions, all sections using it end up calling
485 not_here() and croak. --Kaveh Ghazi (ghazi@noc.rutgers.edu) 9/18/94. */
486#ifndef wchar_t
487#define wchar_t char
488#endif
489#endif
490
491#ifndef HAS_LOCALECONV
492#define localeconv() not_here("localeconv")
493#endif
494
172ea7c8 495#ifdef HAS_LONG_DOUBLE
53796371 496# if LONG_DOUBLESIZE > NVSIZE
172ea7c8
JH
497# undef HAS_LONG_DOUBLE /* XXX until we figure out how to use them */
498# endif
499#endif
500
501#ifndef HAS_LONG_DOUBLE
502#ifdef LDBL_MAX
503#undef LDBL_MAX
504#endif
505#ifdef LDBL_MIN
506#undef LDBL_MIN
507#endif
508#ifdef LDBL_EPSILON
509#undef LDBL_EPSILON
510#endif
511#endif
512
ec193bec
JH
513/* Background: in most systems the low byte of the wait status
514 * is the signal (the lowest 7 bits) and the coredump flag is
515 * the eight bit, and the second lowest byte is the exit status.
516 * BeOS bucks the trend and has the bytes in different order.
517 * See beos/beos.c for how the reality is bent even in BeOS
518 * to follow the traditional. However, to make the POSIX
519 * wait W*() macros to work in BeOS, we need to unbend the
520 * reality back in place. --jhi */
17028706
IW
521/* In actual fact the code below is to blame here. Perl has an internal
522 * representation of the exit status ($?), which it re-composes from the
523 * OS's representation using the W*() POSIX macros. The code below
524 * incorrectly uses the W*() macros on the internal representation,
525 * which fails for OSs that have a different representation (namely BeOS
526 * and Haiku). WMUNGE() is a hack that converts the internal
527 * representation into the OS specific one, so that the W*() macros work
528 * as expected. The better solution would be not to use the W*() macros
529 * in the first place, though. -- Ingo Weinhold
530 */
531#if defined(__BEOS__) || defined(__HAIKU__)
ec193bec
JH
532# define WMUNGE(x) (((x) & 0xFF00) >> 8 | ((x) & 0x00FF) << 8)
533#else
534# define WMUNGE(x) (x)
535#endif
536
8990e307 537static int
4b48cf39 538not_here(const char *s)
8990e307
LW
539{
540 croak("POSIX::%s not implemented on this architecture", s);
541 return -1;
542}
463ee0b2 543
1cb0fb50 544#include "const-c.inc"
a290f238 545
1dfe7606 546static void
40b7a5f5 547restore_sigmask(pTHX_ SV *osset_sv)
1dfe7606 548{
7feb700b
JH
549 /* Fortunately, restoring the signal mask can't fail, because
550 * there's nothing we can do about it if it does -- we're not
551 * supposed to return -1 from sigaction unless the disposition
552 * was unaffected.
553 */
7feb700b
JH
554 sigset_t *ossetp = (sigset_t *) SvPV_nolen( osset_sv );
555 (void)sigprocmask(SIG_SETMASK, ossetp, (sigset_t *)0);
1dfe7606 556}
557
a2261f90
NC
558static void *
559allocate_struct(pTHX_ SV *rv, const STRLEN size, const char *packname) {
560 SV *const t = newSVrv(rv, packname);
561 void *const p = sv_grow(t, size + 1);
562
563 SvCUR_set(t, size);
564 SvPOK_on(t);
565 return p;
566}
567
81ab4c44
SH
568#ifdef WIN32
569
570/*
571 * (1) The CRT maintains its own copy of the environment, separate from
572 * the Win32API copy.
573 *
574 * (2) CRT getenv() retrieves from this copy. CRT putenv() updates this
575 * copy, and then calls SetEnvironmentVariableA() to update the Win32API
576 * copy.
577 *
578 * (3) win32_getenv() and win32_putenv() call GetEnvironmentVariableA() and
579 * SetEnvironmentVariableA() directly, bypassing the CRT copy of the
580 * environment.
581 *
582 * (4) The CRT strftime() "%Z" implementation calls __tzset(). That
583 * calls CRT tzset(), but only the first time it is called, and in turn
584 * that uses CRT getenv("TZ") to retrieve the timezone info from the CRT
585 * local copy of the environment and hence gets the original setting as
586 * perl never updates the CRT copy when assigning to $ENV{TZ}.
587 *
588 * Therefore, we need to retrieve the value of $ENV{TZ} and call CRT
589 * putenv() to update the CRT copy of the environment (if it is different)
590 * whenever we're about to call tzset().
591 *
592 * In addition to all that, when perl is built with PERL_IMPLICIT_SYS
593 * defined:
594 *
595 * (a) Each interpreter has its own copy of the environment inside the
596 * perlhost structure. That allows applications that host multiple
597 * independent Perl interpreters to isolate environment changes from
598 * each other. (This is similar to how the perlhost mechanism keeps a
599 * separate working directory for each Perl interpreter, so that calling
600 * chdir() will not affect other interpreters.)
601 *
602 * (b) Only the first Perl interpreter instantiated within a process will
603 * "write through" environment changes to the process environment.
604 *
605 * (c) Even the primary Perl interpreter won't update the CRT copy of the
606 * the environment, only the Win32API copy (it calls win32_putenv()).
607 *
608 * As with CPerlHost::Getenv() and CPerlHost::Putenv() themselves, it makes
609 * sense to only update the process environment when inside the main
610 * interpreter, but we don't have access to CPerlHost's m_bTopLevel member
611 * from here so we'll just have to check PL_curinterp instead.
612 *
613 * Therefore, we can simply #undef getenv() and putenv() so that those names
614 * always refer to the CRT functions, and explicitly call win32_getenv() to
615 * access perl's %ENV.
616 *
617 * We also #undef malloc() and free() to be sure we are using the CRT
618 * functions otherwise under PERL_IMPLICIT_SYS they are redefined to calls
619 * into VMem::Malloc() and VMem::Free() and all allocations will be freed
620 * when the Perl interpreter is being destroyed so we'd end up with a pointer
621 * into deallocated memory in environ[] if a program embedding a Perl
622 * interpreter continues to operate even after the main Perl interpreter has
623 * been destroyed.
624 *
625 * Note that we don't free() the malloc()ed memory unless and until we call
626 * malloc() again ourselves because the CRT putenv() function simply puts its
b7b1e41b 627 * pointer argument into the environ[] array (it doesn't make a copy of it)
81ab4c44
SH
628 * so this memory must otherwise be leaked.
629 */
630
631#undef getenv
632#undef putenv
633#undef malloc
634#undef free
635
636static void
637fix_win32_tzenv(void)
638{
639 static char* oldenv = NULL;
640 char* newenv;
641 const char* perl_tz_env = win32_getenv("TZ");
642 const char* crt_tz_env = getenv("TZ");
643 if (perl_tz_env == NULL)
644 perl_tz_env = "";
645 if (crt_tz_env == NULL)
646 crt_tz_env = "";
647 if (strcmp(perl_tz_env, crt_tz_env) != 0) {
648 newenv = (char*)malloc((strlen(perl_tz_env) + 4) * sizeof(char));
649 if (newenv != NULL) {
650 sprintf(newenv, "TZ=%s", perl_tz_env);
651 putenv(newenv);
652 if (oldenv != NULL)
653 free(oldenv);
654 oldenv = newenv;
655 }
656 }
657}
658
659#endif
660
661/*
662 * my_tzset - wrapper to tzset() with a fix to make it work (better) on Win32.
663 * This code is duplicated in the Time-Piece module, so any changes made here
664 * should be made there too.
665 */
666static void
667my_tzset(pTHX)
668{
669#ifdef WIN32
670#if defined(USE_ITHREADS) && defined(PERL_IMPLICIT_SYS)
671 if (PL_curinterp == aTHX)
672#endif
673 fix_win32_tzenv();
674#endif
675 tzset();
676}
677
2304df62
AD
678MODULE = SigSet PACKAGE = POSIX::SigSet PREFIX = sig
679
92b39396 680void
2304df62 681new(packname = "POSIX::SigSet", ...)
d3f5e399 682 const char * packname
2304df62
AD
683 CODE:
684 {
685 int i;
92b39396
NC
686 sigset_t *const s
687 = (sigset_t *) allocate_struct(aTHX_ (ST(0) = sv_newmortal()),
688 sizeof(sigset_t),
689 packname);
690 sigemptyset(s);
a0d0e21e 691 for (i = 1; i < items; i++)
92b39396
NC
692 sigaddset(s, SvIV(ST(i)));
693 XSRETURN(1);
2304df62 694 }
2304df62
AD
695
696SysRet
697sigaddset(sigset, sig)
698 POSIX::SigSet sigset
699 int sig
700
701SysRet
702sigdelset(sigset, sig)
703 POSIX::SigSet sigset
704 int sig
705
706SysRet
707sigemptyset(sigset)
708 POSIX::SigSet sigset
709
710SysRet
711sigfillset(sigset)
712 POSIX::SigSet sigset
713
714int
715sigismember(sigset, sig)
716 POSIX::SigSet sigset
717 int sig
718
a0d0e21e
LW
719MODULE = Termios PACKAGE = POSIX::Termios PREFIX = cf
720
11a39fe4 721void
a0d0e21e 722new(packname = "POSIX::Termios", ...)
d3f5e399 723 const char * packname
a0d0e21e
LW
724 CODE:
725 {
726#ifdef I_TERMIOS
a2261f90
NC
727 void *const p = allocate_struct(aTHX_ (ST(0) = sv_newmortal()),
728 sizeof(struct termios), packname);
11a39fe4
NC
729 /* The previous implementation stored a pointer to an uninitialised
730 struct termios. Seems safer to initialise it, particularly as
731 this implementation exposes the struct to prying from perl-space.
732 */
a2261f90 733 memset(p, 0, 1 + sizeof(struct termios));
11a39fe4 734 XSRETURN(1);
a0d0e21e
LW
735#else
736 not_here("termios");
737#endif
738 }
a0d0e21e
LW
739
740SysRet
741getattr(termios_ref, fd = 0)
742 POSIX::Termios termios_ref
743 int fd
744 CODE:
745 RETVAL = tcgetattr(fd, termios_ref);
746 OUTPUT:
747 RETVAL
748
749SysRet
750setattr(termios_ref, fd = 0, optional_actions = 0)
751 POSIX::Termios termios_ref
752 int fd
753 int optional_actions
754 CODE:
755 RETVAL = tcsetattr(fd, optional_actions, termios_ref);
756 OUTPUT:
757 RETVAL
758
759speed_t
760cfgetispeed(termios_ref)
761 POSIX::Termios termios_ref
762
763speed_t
764cfgetospeed(termios_ref)
765 POSIX::Termios termios_ref
766
767tcflag_t
768getiflag(termios_ref)
769 POSIX::Termios termios_ref
770 CODE:
771#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
772 RETVAL = termios_ref->c_iflag;
773#else
640cc986
HM
774 not_here("getiflag");
775 RETVAL = 0;
a0d0e21e
LW
776#endif
777 OUTPUT:
778 RETVAL
779
780tcflag_t
781getoflag(termios_ref)
782 POSIX::Termios termios_ref
783 CODE:
784#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
785 RETVAL = termios_ref->c_oflag;
786#else
640cc986
HM
787 not_here("getoflag");
788 RETVAL = 0;
a0d0e21e
LW
789#endif
790 OUTPUT:
791 RETVAL
792
793tcflag_t
794getcflag(termios_ref)
795 POSIX::Termios termios_ref
796 CODE:
797#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
798 RETVAL = termios_ref->c_cflag;
799#else
640cc986
HM
800 not_here("getcflag");
801 RETVAL = 0;
a0d0e21e
LW
802#endif
803 OUTPUT:
804 RETVAL
805
806tcflag_t
807getlflag(termios_ref)
808 POSIX::Termios termios_ref
809 CODE:
810#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
811 RETVAL = termios_ref->c_lflag;
812#else
640cc986
HM
813 not_here("getlflag");
814 RETVAL = 0;
a0d0e21e
LW
815#endif
816 OUTPUT:
817 RETVAL
818
819cc_t
820getcc(termios_ref, ccix)
821 POSIX::Termios termios_ref
b56fc9ec 822 unsigned int ccix
a0d0e21e
LW
823 CODE:
824#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
825 if (ccix >= NCCS)
826 croak("Bad getcc subscript");
827 RETVAL = termios_ref->c_cc[ccix];
828#else
640cc986
HM
829 not_here("getcc");
830 RETVAL = 0;
a0d0e21e
LW
831#endif
832 OUTPUT:
833 RETVAL
834
835SysRet
836cfsetispeed(termios_ref, speed)
837 POSIX::Termios termios_ref
838 speed_t speed
839
840SysRet
841cfsetospeed(termios_ref, speed)
842 POSIX::Termios termios_ref
843 speed_t speed
844
845void
846setiflag(termios_ref, iflag)
847 POSIX::Termios termios_ref
848 tcflag_t iflag
849 CODE:
850#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
851 termios_ref->c_iflag = iflag;
852#else
853 not_here("setiflag");
854#endif
855
856void
857setoflag(termios_ref, oflag)
858 POSIX::Termios termios_ref
859 tcflag_t oflag
860 CODE:
861#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
862 termios_ref->c_oflag = oflag;
863#else
864 not_here("setoflag");
865#endif
866
867void
868setcflag(termios_ref, cflag)
869 POSIX::Termios termios_ref
870 tcflag_t cflag
871 CODE:
872#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
873 termios_ref->c_cflag = cflag;
874#else
875 not_here("setcflag");
876#endif
877
878void
879setlflag(termios_ref, lflag)
880 POSIX::Termios termios_ref
881 tcflag_t lflag
882 CODE:
883#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
884 termios_ref->c_lflag = lflag;
885#else
886 not_here("setlflag");
887#endif
888
889void
890setcc(termios_ref, ccix, cc)
891 POSIX::Termios termios_ref
b56fc9ec 892 unsigned int ccix
a0d0e21e
LW
893 cc_t cc
894 CODE:
895#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
896 if (ccix >= NCCS)
897 croak("Bad setcc subscript");
898 termios_ref->c_cc[ccix] = cc;
899#else
900 not_here("setcc");
901#endif
902
903
a0d0e21e
LW
904MODULE = POSIX PACKAGE = POSIX
905
1cb0fb50 906INCLUDE: const-xs.inc
a290f238 907
e99d581a
NC
908int
909WEXITSTATUS(status)
910 int status
72bfe1b2
NC
911 ALIAS:
912 POSIX::WIFEXITED = 1
913 POSIX::WIFSIGNALED = 2
914 POSIX::WIFSTOPPED = 3
915 POSIX::WSTOPSIG = 4
916 POSIX::WTERMSIG = 5
917 CODE:
fabb67aa
SK
918#if !defined(WEXITSTATUS) || !defined(WIFEXITED) || !defined(WIFSIGNALED) \
919 || !defined(WIFSTOPPED) || !defined(WSTOPSIG) || !defined(WTERMSIG)
19c4478c
NC
920 RETVAL = 0; /* Silence compilers that notice this, but don't realise
921 that not_here() can't return. */
922#endif
72bfe1b2
NC
923 switch(ix) {
924 case 0:
d49025b7 925#ifdef WEXITSTATUS
17028706 926 RETVAL = WEXITSTATUS(WMUNGE(status));
d49025b7
NC
927#else
928 not_here("WEXITSTATUS");
929#endif
72bfe1b2
NC
930 break;
931 case 1:
d49025b7 932#ifdef WIFEXITED
17028706 933 RETVAL = WIFEXITED(WMUNGE(status));
d49025b7
NC
934#else
935 not_here("WIFEXITED");
936#endif
72bfe1b2
NC
937 break;
938 case 2:
d49025b7 939#ifdef WIFSIGNALED
17028706 940 RETVAL = WIFSIGNALED(WMUNGE(status));
d49025b7
NC
941#else
942 not_here("WIFSIGNALED");
943#endif
72bfe1b2
NC
944 break;
945 case 3:
d49025b7 946#ifdef WIFSTOPPED
17028706 947 RETVAL = WIFSTOPPED(WMUNGE(status));
d49025b7
NC
948#else
949 not_here("WIFSTOPPED");
950#endif
72bfe1b2
NC
951 break;
952 case 4:
d49025b7 953#ifdef WSTOPSIG
17028706 954 RETVAL = WSTOPSIG(WMUNGE(status));
d49025b7
NC
955#else
956 not_here("WSTOPSIG");
957#endif
72bfe1b2
NC
958 break;
959 case 5:
d49025b7 960#ifdef WTERMSIG
17028706 961 RETVAL = WTERMSIG(WMUNGE(status));
d49025b7
NC
962#else
963 not_here("WTERMSIG");
964#endif
72bfe1b2
NC
965 break;
966 default:
c33e8be1 967 Perl_croak(aTHX_ "Illegal alias %d for POSIX::W*", (int)ix);
72bfe1b2
NC
968 }
969 OUTPUT:
970 RETVAL
2304df62
AD
971
972int
973isalnum(charstring)
767bb2e0
ST
974 SV * charstring
975 PREINIT:
976 STRLEN len;
2304df62 977 CODE:
767bb2e0
ST
978 unsigned char *s = (unsigned char *) SvPV(charstring, len);
979 unsigned char *e = s + len;
5344da4e 980 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62
AD
981 if (!isalnum(*s))
982 RETVAL = 0;
983 OUTPUT:
984 RETVAL
985
986int
987isalpha(charstring)
767bb2e0
ST
988 SV * charstring
989 PREINIT:
990 STRLEN len;
2304df62 991 CODE:
767bb2e0
ST
992 unsigned char *s = (unsigned char *) SvPV(charstring, len);
993 unsigned char *e = s + len;
5344da4e 994 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62
AD
995 if (!isalpha(*s))
996 RETVAL = 0;
997 OUTPUT:
998 RETVAL
999
1000int
1001iscntrl(charstring)
767bb2e0
ST
1002 SV * charstring
1003 PREINIT:
1004 STRLEN len;
2304df62 1005 CODE:
767bb2e0
ST
1006 unsigned char *s = (unsigned char *) SvPV(charstring, len);
1007 unsigned char *e = s + len;
5344da4e 1008 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62
AD
1009 if (!iscntrl(*s))
1010 RETVAL = 0;
1011 OUTPUT:
1012 RETVAL
1013
1014int
1015isdigit(charstring)
767bb2e0
ST
1016 SV * charstring
1017 PREINIT:
1018 STRLEN len;
2304df62 1019 CODE:
767bb2e0
ST
1020 unsigned char *s = (unsigned char *) SvPV(charstring, len);
1021 unsigned char *e = s + len;
5344da4e 1022 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62
AD
1023 if (!isdigit(*s))
1024 RETVAL = 0;
1025 OUTPUT:
1026 RETVAL
1027
1028int
1029isgraph(charstring)
767bb2e0
ST
1030 SV * charstring
1031 PREINIT:
1032 STRLEN len;
2304df62 1033 CODE:
767bb2e0
ST
1034 unsigned char *s = (unsigned char *) SvPV(charstring, len);
1035 unsigned char *e = s + len;
5344da4e 1036 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62
AD
1037 if (!isgraph(*s))
1038 RETVAL = 0;
1039 OUTPUT:
1040 RETVAL
1041
1042int
1043islower(charstring)
767bb2e0
ST
1044 SV * charstring
1045 PREINIT:
1046 STRLEN len;
2304df62 1047 CODE:
767bb2e0
ST
1048 unsigned char *s = (unsigned char *) SvPV(charstring, len);
1049 unsigned char *e = s + len;
5344da4e 1050 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62
AD
1051 if (!islower(*s))
1052 RETVAL = 0;
1053 OUTPUT:
1054 RETVAL
1055
1056int
1057isprint(charstring)
767bb2e0
ST
1058 SV * charstring
1059 PREINIT:
1060 STRLEN len;
2304df62 1061 CODE:
767bb2e0
ST
1062 unsigned char *s = (unsigned char *) SvPV(charstring, len);
1063 unsigned char *e = s + len;
5344da4e 1064 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62
AD
1065 if (!isprint(*s))
1066 RETVAL = 0;
1067 OUTPUT:
1068 RETVAL
1069
1070int
1071ispunct(charstring)
767bb2e0
ST
1072 SV * charstring
1073 PREINIT:
1074 STRLEN len;
2304df62 1075 CODE:
767bb2e0
ST
1076 unsigned char *s = (unsigned char *) SvPV(charstring, len);
1077 unsigned char *e = s + len;
5344da4e 1078 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62
AD
1079 if (!ispunct(*s))
1080 RETVAL = 0;
1081 OUTPUT:
1082 RETVAL
1083
1084int
1085isspace(charstring)
767bb2e0
ST
1086 SV * charstring
1087 PREINIT:
1088 STRLEN len;
2304df62 1089 CODE:
767bb2e0
ST
1090 unsigned char *s = (unsigned char *) SvPV(charstring, len);
1091 unsigned char *e = s + len;
5344da4e 1092 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62
AD
1093 if (!isspace(*s))
1094 RETVAL = 0;
1095 OUTPUT:
1096 RETVAL
8990e307
LW
1097
1098int
2304df62 1099isupper(charstring)
767bb2e0
ST
1100 SV * charstring
1101 PREINIT:
1102 STRLEN len;
2304df62 1103 CODE:
767bb2e0
ST
1104 unsigned char *s = (unsigned char *) SvPV(charstring, len);
1105 unsigned char *e = s + len;
5344da4e 1106 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62
AD
1107 if (!isupper(*s))
1108 RETVAL = 0;
1109 OUTPUT:
1110 RETVAL
8990e307
LW
1111
1112int
2304df62 1113isxdigit(charstring)
767bb2e0
ST
1114 SV * charstring
1115 PREINIT:
1116 STRLEN len;
2304df62 1117 CODE:
767bb2e0
ST
1118 unsigned char *s = (unsigned char *) SvPV(charstring, len);
1119 unsigned char *e = s + len;
5344da4e 1120 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62
AD
1121 if (!isxdigit(*s))
1122 RETVAL = 0;
1123 OUTPUT:
1124 RETVAL
1125
1126SysRet
1127open(filename, flags = O_RDONLY, mode = 0666)
1128 char * filename
1129 int flags
a0d0e21e 1130 Mode_t mode
748a9306
LW
1131 CODE:
1132 if (flags & (O_APPEND|O_CREAT|O_TRUNC|O_RDWR|O_WRONLY|O_EXCL))
1133 TAINT_PROPER("open");
1134 RETVAL = open(filename, flags, mode);
1135 OUTPUT:
1136 RETVAL
1137
2304df62
AD
1138
1139HV *
1140localeconv()
1141 CODE:
a0d0e21e 1142#ifdef HAS_LOCALECONV
2304df62
AD
1143 struct lconv *lcbuf;
1144 RETVAL = newHV();
c4e79b56 1145 sv_2mortal((SV*)RETVAL);
8063af02 1146 if ((lcbuf = localeconv())) {
2304df62
AD
1147 /* the strings */
1148 if (lcbuf->decimal_point && *lcbuf->decimal_point)
c33e8be1 1149 (void) hv_store(RETVAL, "decimal_point", 13,
2304df62
AD
1150 newSVpv(lcbuf->decimal_point, 0), 0);
1151 if (lcbuf->thousands_sep && *lcbuf->thousands_sep)
c33e8be1 1152 (void) hv_store(RETVAL, "thousands_sep", 13,
2304df62 1153 newSVpv(lcbuf->thousands_sep, 0), 0);
28e8609d 1154#ifndef NO_LOCALECONV_GROUPING
2304df62 1155 if (lcbuf->grouping && *lcbuf->grouping)
c33e8be1 1156 (void) hv_store(RETVAL, "grouping", 8,
2304df62 1157 newSVpv(lcbuf->grouping, 0), 0);
28e8609d 1158#endif
2304df62 1159 if (lcbuf->int_curr_symbol && *lcbuf->int_curr_symbol)
c33e8be1 1160 (void) hv_store(RETVAL, "int_curr_symbol", 15,
2304df62
AD
1161 newSVpv(lcbuf->int_curr_symbol, 0), 0);
1162 if (lcbuf->currency_symbol && *lcbuf->currency_symbol)
c33e8be1 1163 (void) hv_store(RETVAL, "currency_symbol", 15,
2304df62
AD
1164 newSVpv(lcbuf->currency_symbol, 0), 0);
1165 if (lcbuf->mon_decimal_point && *lcbuf->mon_decimal_point)
c33e8be1 1166 (void) hv_store(RETVAL, "mon_decimal_point", 17,
2304df62 1167 newSVpv(lcbuf->mon_decimal_point, 0), 0);
39e571d4 1168#ifndef NO_LOCALECONV_MON_THOUSANDS_SEP
2304df62 1169 if (lcbuf->mon_thousands_sep && *lcbuf->mon_thousands_sep)
c33e8be1 1170 (void) hv_store(RETVAL, "mon_thousands_sep", 17,
2304df62 1171 newSVpv(lcbuf->mon_thousands_sep, 0), 0);
3609ea0d 1172#endif
28e8609d 1173#ifndef NO_LOCALECONV_MON_GROUPING
2304df62 1174 if (lcbuf->mon_grouping && *lcbuf->mon_grouping)
c33e8be1 1175 (void) hv_store(RETVAL, "mon_grouping", 12,
2304df62 1176 newSVpv(lcbuf->mon_grouping, 0), 0);
28e8609d 1177#endif
2304df62 1178 if (lcbuf->positive_sign && *lcbuf->positive_sign)
c33e8be1 1179 (void) hv_store(RETVAL, "positive_sign", 13,
2304df62
AD
1180 newSVpv(lcbuf->positive_sign, 0), 0);
1181 if (lcbuf->negative_sign && *lcbuf->negative_sign)
c33e8be1 1182 (void) hv_store(RETVAL, "negative_sign", 13,
2304df62
AD
1183 newSVpv(lcbuf->negative_sign, 0), 0);
1184 /* the integers */
1185 if (lcbuf->int_frac_digits != CHAR_MAX)
c33e8be1 1186 (void) hv_store(RETVAL, "int_frac_digits", 15,
2304df62
AD
1187 newSViv(lcbuf->int_frac_digits), 0);
1188 if (lcbuf->frac_digits != CHAR_MAX)
c33e8be1 1189 (void) hv_store(RETVAL, "frac_digits", 11,
2304df62
AD
1190 newSViv(lcbuf->frac_digits), 0);
1191 if (lcbuf->p_cs_precedes != CHAR_MAX)
c33e8be1 1192 (void) hv_store(RETVAL, "p_cs_precedes", 13,
2304df62
AD
1193 newSViv(lcbuf->p_cs_precedes), 0);
1194 if (lcbuf->p_sep_by_space != CHAR_MAX)
c33e8be1 1195 (void) hv_store(RETVAL, "p_sep_by_space", 14,
2304df62
AD
1196 newSViv(lcbuf->p_sep_by_space), 0);
1197 if (lcbuf->n_cs_precedes != CHAR_MAX)
c33e8be1 1198 (void) hv_store(RETVAL, "n_cs_precedes", 13,
2304df62
AD
1199 newSViv(lcbuf->n_cs_precedes), 0);
1200 if (lcbuf->n_sep_by_space != CHAR_MAX)
c33e8be1 1201 (void) hv_store(RETVAL, "n_sep_by_space", 14,
2304df62
AD
1202 newSViv(lcbuf->n_sep_by_space), 0);
1203 if (lcbuf->p_sign_posn != CHAR_MAX)
c33e8be1 1204 (void) hv_store(RETVAL, "p_sign_posn", 11,
2304df62
AD
1205 newSViv(lcbuf->p_sign_posn), 0);
1206 if (lcbuf->n_sign_posn != CHAR_MAX)
c33e8be1 1207 (void) hv_store(RETVAL, "n_sign_posn", 11,
2304df62
AD
1208 newSViv(lcbuf->n_sign_posn), 0);
1209 }
a0d0e21e
LW
1210#else
1211 localeconv(); /* A stub to call not_here(). */
1212#endif
2304df62
AD
1213 OUTPUT:
1214 RETVAL
1215
1216char *
c28ee57b 1217setlocale(category, locale = 0)
2304df62
AD
1218 int category
1219 char * locale
1ba01ae3
SH
1220 PREINIT:
1221 char * retval;
c28ee57b 1222 CODE:
1ba01ae3
SH
1223 retval = setlocale(category, locale);
1224 if (retval) {
1225 /* Save retval since subsequent setlocale() calls
1226 * may overwrite it. */
1227 RETVAL = savepv(retval);
36477c24 1228#ifdef USE_LOCALE_CTYPE
bbce6d69
PP
1229 if (category == LC_CTYPE
1230#ifdef LC_ALL
1231 || category == LC_ALL
1232#endif
1233 )
1234 {
1235 char *newctype;
1236#ifdef LC_ALL
1237 if (category == LC_ALL)
1238 newctype = setlocale(LC_CTYPE, NULL);
1239 else
1240#endif
1241 newctype = RETVAL;
864dbfa3 1242 new_ctype(newctype);
bbce6d69 1243 }
36477c24
PP
1244#endif /* USE_LOCALE_CTYPE */
1245#ifdef USE_LOCALE_COLLATE
bbce6d69
PP
1246 if (category == LC_COLLATE
1247#ifdef LC_ALL
1248 || category == LC_ALL
1249#endif
1250 )
1251 {
1252 char *newcoll;
1253#ifdef LC_ALL
1254 if (category == LC_ALL)
1255 newcoll = setlocale(LC_COLLATE, NULL);
1256 else
1257#endif
1258 newcoll = RETVAL;
864dbfa3 1259 new_collate(newcoll);
bbce6d69 1260 }
36477c24
PP
1261#endif /* USE_LOCALE_COLLATE */
1262#ifdef USE_LOCALE_NUMERIC
bbce6d69
PP
1263 if (category == LC_NUMERIC
1264#ifdef LC_ALL
1265 || category == LC_ALL
1266#endif
1267 )
1268 {
1269 char *newnum;
1270#ifdef LC_ALL
1271 if (category == LC_ALL)
1272 newnum = setlocale(LC_NUMERIC, NULL);
1273 else
1274#endif
1275 newnum = RETVAL;
864dbfa3 1276 new_numeric(newnum);
bbce6d69 1277 }
36477c24 1278#endif /* USE_LOCALE_NUMERIC */
bbce6d69 1279 }
1ba01ae3
SH
1280 else
1281 RETVAL = NULL;
c28ee57b
JH
1282 OUTPUT:
1283 RETVAL
1ba01ae3
SH
1284 CLEANUP:
1285 if (RETVAL)
1286 Safefree(RETVAL);
2304df62 1287
e1ca407b 1288NV
2304df62 1289acos(x)
e1ca407b 1290 NV x
2304df62 1291
e1ca407b 1292NV
2304df62 1293asin(x)
e1ca407b 1294 NV x
2304df62 1295
e1ca407b 1296NV
2304df62 1297atan(x)
e1ca407b 1298 NV x
2304df62 1299
e1ca407b 1300NV
2304df62 1301ceil(x)
e1ca407b 1302 NV x
2304df62 1303
e1ca407b 1304NV
2304df62 1305cosh(x)
e1ca407b 1306 NV x
2304df62 1307
e1ca407b 1308NV
2304df62 1309floor(x)
e1ca407b 1310 NV x
2304df62 1311
e1ca407b 1312NV
2304df62 1313fmod(x,y)
e1ca407b
A
1314 NV x
1315 NV y
2304df62
AD
1316
1317void
1318frexp(x)
e1ca407b 1319 NV x
2304df62
AD
1320 PPCODE:
1321 int expvar;
2304df62
AD
1322 /* (We already know stack is long enough.) */
1323 PUSHs(sv_2mortal(newSVnv(frexp(x,&expvar))));
1324 PUSHs(sv_2mortal(newSViv(expvar)));
1325
e1ca407b 1326NV
2304df62 1327ldexp(x,exp)
e1ca407b 1328 NV x
2304df62
AD
1329 int exp
1330
e1ca407b 1331NV
2304df62 1332log10(x)
e1ca407b 1333 NV x
2304df62
AD
1334
1335void
1336modf(x)
e1ca407b 1337 NV x
2304df62 1338 PPCODE:
e1ca407b 1339 NV intvar;
2304df62 1340 /* (We already know stack is long enough.) */
bf4acbe4 1341 PUSHs(sv_2mortal(newSVnv(Perl_modf(x,&intvar))));
2304df62
AD
1342 PUSHs(sv_2mortal(newSVnv(intvar)));
1343
e1ca407b 1344NV
2304df62 1345sinh(x)
e1ca407b 1346 NV x
2304df62 1347
e1ca407b 1348NV
3b35bae3 1349tan(x)
e1ca407b 1350 NV x
3b35bae3 1351
e1ca407b 1352NV
2304df62 1353tanh(x)
e1ca407b 1354 NV x
2304df62
AD
1355
1356SysRet
1dfe7606 1357sigaction(sig, optaction, oldaction = 0)
2304df62 1358 int sig
1dfe7606 1359 SV * optaction
2304df62
AD
1360 POSIX::SigAction oldaction
1361 CODE:
2986a63f 1362#if defined(WIN32) || defined(NETWARE)
6dead956
GS
1363 RETVAL = not_here("sigaction");
1364#else
2304df62
AD
1365# This code is really grody because we're trying to make the signal
1366# interface look beautiful, which is hard.
1367
2304df62 1368 {
27da23d5 1369 dVAR;
1dfe7606 1370 POSIX__SigAction action;
f584eb2d 1371 GV *siggv = gv_fetchpvs("SIG", GV_ADD, SVt_PVHV);
2304df62
AD
1372 struct sigaction act;
1373 struct sigaction oact;
1dfe7606 1374 sigset_t sset;
183bde56 1375 SV *osset_sv;
27c1a449 1376 sigset_t osset;
2304df62
AD
1377 POSIX__SigSet sigset;
1378 SV** svp;
1d81eac9 1379 SV** sigsvp;
3609ea0d 1380
516d25e8
SP
1381 if (sig < 0) {
1382 croak("Negative signals are not allowed");
1383 }
1384
1d81eac9 1385 if (sig == 0 && SvPOK(ST(0))) {
aa07b2f6 1386 const char *s = SvPVX_const(ST(0));
1d81eac9
JH
1387 int i = whichsig(s);
1388
1389 if (i < 0 && memEQ(s, "SIG", 3))
1390 i = whichsig(s + 3);
1391 if (i < 0) {
1392 if (ckWARN(WARN_SIGNAL))
1393 Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
1394 "No such signal: SIG%s", s);
1395 XSRETURN_UNDEF;
1396 }
1397 else
1398 sig = i;
1399 }
3609ea0d
JH
1400#ifdef NSIG
1401 if (sig > NSIG) { /* NSIG - 1 is still okay. */
1402 Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
1403 "No such signal: %d", sig);
1404 XSRETURN_UNDEF;
1405 }
1406#endif
1d81eac9
JH
1407 sigsvp = hv_fetch(GvHVn(siggv),
1408 PL_sig_name[sig],
1409 strlen(PL_sig_name[sig]),
1410 TRUE);
2304df62 1411
1dfe7606 1412 /* Check optaction and set action */
1413 if(SvTRUE(optaction)) {
1414 if(sv_isa(optaction, "POSIX::SigAction"))
1415 action = (HV*)SvRV(optaction);
1416 else
1417 croak("action is not of type POSIX::SigAction");
1418 }
1419 else {
1420 action=0;
1421 }
1422
1423 /* sigaction() is supposed to look atomic. In particular, any
1424 * signal handler invoked during a sigaction() call should
1425 * see either the old or the new disposition, and not something
1426 * in between. We use sigprocmask() to make it so.
1427 */
1428 sigfillset(&sset);
1429 RETVAL=sigprocmask(SIG_BLOCK, &sset, &osset);
1430 if(RETVAL == -1)
15c0d34a 1431 XSRETURN_UNDEF;
1dfe7606 1432 ENTER;
1433 /* Restore signal mask no matter how we exit this block. */
f584eb2d 1434 osset_sv = newSVpvn((char *)(&osset), sizeof(sigset_t));
183bde56 1435 SAVEFREESV( osset_sv );
40b7a5f5 1436 SAVEDESTRUCTOR_X(restore_sigmask, osset_sv);
1dfe7606 1437
1438 RETVAL=-1; /* In case both oldaction and action are 0. */
1439
1440 /* Remember old disposition if desired. */
2304df62 1441 if (oldaction) {
017a3ce5 1442 svp = hv_fetchs(oldaction, "HANDLER", TRUE);
1dfe7606 1443 if(!svp)
1444 croak("Can't supply an oldaction without a HANDLER");
1445 if(SvTRUE(*sigsvp)) { /* TBD: what if "0"? */
1446 sv_setsv(*svp, *sigsvp);
1447 }
1448 else {
f584eb2d 1449 sv_setpvs(*svp, "DEFAULT");
1dfe7606 1450 }
1451 RETVAL = sigaction(sig, (struct sigaction *)0, & oact);
6ca4bbc9
GG
1452 if(RETVAL == -1) {
1453 LEAVE;
15c0d34a 1454 XSRETURN_UNDEF;
6ca4bbc9 1455 }
1dfe7606 1456 /* Get back the mask. */
017a3ce5 1457 svp = hv_fetchs(oldaction, "MASK", TRUE);
1dfe7606 1458 if (sv_isa(*svp, "POSIX::SigSet")) {
92b39396 1459 sigset = (sigset_t *) SvPV_nolen(SvRV(*svp));
1dfe7606 1460 }
1461 else {
92b39396
NC
1462 sigset = (sigset_t *) allocate_struct(aTHX_ *svp,
1463 sizeof(sigset_t),
1464 "POSIX::SigSet");
1dfe7606 1465 }
1466 *sigset = oact.sa_mask;
1467
1468 /* Get back the flags. */
017a3ce5 1469 svp = hv_fetchs(oldaction, "FLAGS", TRUE);
1dfe7606 1470 sv_setiv(*svp, oact.sa_flags);
d36b6582
CS
1471
1472 /* Get back whether the old handler used safe signals. */
017a3ce5 1473 svp = hv_fetchs(oldaction, "SAFE", TRUE);
e91e3b10
RB
1474 sv_setiv(*svp,
1475 /* compare incompatible pointers by casting to integer */
1476 PTR2nat(oact.sa_handler) == PTR2nat(PL_csighandlerp));
2304df62
AD
1477 }
1478
1479 if (action) {
d36b6582
CS
1480 /* Safe signals use "csighandler", which vectors through the
1481 PL_sighandlerp pointer when it's safe to do so.
1482 (BTW, "csighandler" is very different from "sighandler".) */
017a3ce5 1483 svp = hv_fetchs(action, "SAFE", FALSE);
e91e3b10
RB
1484 act.sa_handler =
1485 DPTR2FPTR(
87d46f97 1486 void (*)(int),
e91e3b10
RB
1487 (*svp && SvTRUE(*svp))
1488 ? PL_csighandlerp : PL_sighandlerp
1489 );
d36b6582
CS
1490
1491 /* Vector new Perl handler through %SIG.
1492 (The core signal handlers read %SIG to dispatch.) */
017a3ce5 1493 svp = hv_fetchs(action, "HANDLER", FALSE);
2304df62
AD
1494 if (!svp)
1495 croak("Can't supply an action without a HANDLER");
1dfe7606 1496 sv_setsv(*sigsvp, *svp);
d36b6582
CS
1497
1498 /* This call actually calls sigaction() with almost the
1499 right settings, including appropriate interpretation
1500 of DEFAULT and IGNORE. However, why are we doing
1501 this when we're about to do it again just below? XXX */
17cffb37 1502 SvSETMAGIC(*sigsvp);
d36b6582
CS
1503
1504 /* And here again we duplicate -- DEFAULT/IGNORE checking. */
1dfe7606 1505 if(SvPOK(*svp)) {
aa07b2f6 1506 const char *s=SvPVX_const(*svp);
1dfe7606 1507 if(strEQ(s,"IGNORE")) {
1508 act.sa_handler = SIG_IGN;
1509 }
1510 else if(strEQ(s,"DEFAULT")) {
1511 act.sa_handler = SIG_DFL;
1512 }
1dfe7606 1513 }
2304df62
AD
1514
1515 /* Set up any desired mask. */
017a3ce5 1516 svp = hv_fetchs(action, "MASK", FALSE);
2304df62 1517 if (svp && sv_isa(*svp, "POSIX::SigSet")) {
92b39396 1518 sigset = (sigset_t *) SvPV_nolen(SvRV(*svp));
2304df62
AD
1519 act.sa_mask = *sigset;
1520 }
1521 else
85e6fe83 1522 sigemptyset(& act.sa_mask);
2304df62
AD
1523
1524 /* Set up any desired flags. */
017a3ce5 1525 svp = hv_fetchs(action, "FLAGS", FALSE);
2304df62 1526 act.sa_flags = svp ? SvIV(*svp) : 0;
2304df62 1527
1dfe7606 1528 /* Don't worry about cleaning up *sigsvp if this fails,
1529 * because that means we tried to disposition a
1530 * nonblockable signal, in which case *sigsvp is
1531 * essentially meaningless anyway.
1532 */
6c418a22 1533 RETVAL = sigaction(sig, & act, (struct sigaction *)0);
6ca4bbc9
GG
1534 if(RETVAL == -1) {
1535 LEAVE;
a7aad5de 1536 XSRETURN_UNDEF;
6ca4bbc9 1537 }
2304df62 1538 }
1dfe7606 1539
1540 LEAVE;
2304df62 1541 }
6dead956 1542#endif
2304df62
AD
1543 OUTPUT:
1544 RETVAL
1545
1546SysRet
1547sigpending(sigset)
1548 POSIX::SigSet sigset
1549
1550SysRet
1551sigprocmask(how, sigset, oldsigset = 0)
1552 int how
b13bbac7 1553 POSIX::SigSet sigset = NO_INIT
33c27489
GS
1554 POSIX::SigSet oldsigset = NO_INIT
1555INIT:
a3b811a7 1556 if (! SvOK(ST(1))) {
b13bbac7 1557 sigset = NULL;
a3b811a7 1558 } else if (sv_isa(ST(1), "POSIX::SigSet")) {
92b39396 1559 sigset = (sigset_t *) SvPV_nolen(SvRV(ST(1)));
b13bbac7
AB
1560 } else {
1561 croak("sigset is not of type POSIX::SigSet");
33c27489 1562 }
b13bbac7 1563
194cfca0 1564 if (items < 3 || ! SvOK(ST(2))) {
b13bbac7 1565 oldsigset = NULL;
a3b811a7 1566 } else if (sv_isa(ST(2), "POSIX::SigSet")) {
92b39396 1567 oldsigset = (sigset_t *) SvPV_nolen(SvRV(ST(2)));
b13bbac7
AB
1568 } else {
1569 croak("oldsigset is not of type POSIX::SigSet");
33c27489 1570 }
2304df62
AD
1571
1572SysRet
1573sigsuspend(signal_mask)
1574 POSIX::SigSet signal_mask
1575
2304df62
AD
1576void
1577_exit(status)
1578 int status
8990e307 1579
85e6fe83 1580SysRet
8990e307
LW
1581close(fd)
1582 int fd
1583
85e6fe83 1584SysRet
8990e307
LW
1585dup(fd)
1586 int fd
1587
85e6fe83 1588SysRet
8990e307
LW
1589dup2(fd1, fd2)
1590 int fd1
1591 int fd2
1592
4a9d6100 1593SV *
a0d0e21e 1594lseek(fd, offset, whence)
85e6fe83
LW
1595 int fd
1596 Off_t offset
1597 int whence
4a9d6100
GS
1598 CODE:
1599 Off_t pos = PerlLIO_lseek(fd, offset, whence);
1600 RETVAL = sizeof(Off_t) > sizeof(IV)
1601 ? newSVnv((NV)pos) : newSViv((IV)pos);
1602 OUTPUT:
1603 RETVAL
8990e307 1604
c5661c80 1605void
8990e307
LW
1606nice(incr)
1607 int incr
15f0f28a
AE
1608 PPCODE:
1609 errno = 0;
1610 if ((incr = nice(incr)) != -1 || errno == 0) {
1611 if (incr == 0)
d3d34884 1612 XPUSHs(newSVpvs_flags("0 but true", SVs_TEMP));
15f0f28a
AE
1613 else
1614 XPUSHs(sv_2mortal(newSViv(incr)));
1615 }
8990e307 1616
8063af02 1617void
8990e307 1618pipe()
85e6fe83
LW
1619 PPCODE:
1620 int fds[2];
85e6fe83 1621 if (pipe(fds) != -1) {
924508f0 1622 EXTEND(SP,2);
85e6fe83
LW
1623 PUSHs(sv_2mortal(newSViv(fds[0])));
1624 PUSHs(sv_2mortal(newSViv(fds[1])));
1625 }
8990e307 1626
85e6fe83 1627SysRet
a0d0e21e 1628read(fd, buffer, nbytes)
7747499c
TB
1629 PREINIT:
1630 SV *sv_buffer = SvROK(ST(1)) ? SvRV(ST(1)) : ST(1);
1631 INPUT:
1632 int fd
1633 size_t nbytes
1634 char * buffer = sv_grow( sv_buffer, nbytes+1 );
a0d0e21e 1635 CLEANUP:
7747499c 1636 if (RETVAL >= 0) {
b162af07 1637 SvCUR_set(sv_buffer, RETVAL);
7747499c
TB
1638 SvPOK_only(sv_buffer);
1639 *SvEND(sv_buffer) = '\0';
bbce6d69 1640 SvTAINTED_on(sv_buffer);
7747499c 1641 }
8990e307 1642
85e6fe83 1643SysRet
8990e307 1644setpgid(pid, pgid)
86200d5c
JH
1645 pid_t pid
1646 pid_t pgid
8990e307 1647
86200d5c 1648pid_t
8990e307
LW
1649setsid()
1650
86200d5c 1651pid_t
8990e307
LW
1652tcgetpgrp(fd)
1653 int fd
1654
85e6fe83 1655SysRet
8990e307
LW
1656tcsetpgrp(fd, pgrp_id)
1657 int fd
86200d5c 1658 pid_t pgrp_id
8990e307 1659
8063af02 1660void
8990e307 1661uname()
2304df62 1662 PPCODE:
a0d0e21e 1663#ifdef HAS_UNAME
85e6fe83 1664 struct utsname buf;
85e6fe83 1665 if (uname(&buf) >= 0) {
924508f0 1666 EXTEND(SP, 5);
d3d34884
NC
1667 PUSHs(newSVpvn_flags(buf.sysname, strlen(buf.sysname), SVs_TEMP));
1668 PUSHs(newSVpvn_flags(buf.nodename, strlen(buf.nodename), SVs_TEMP));
1669 PUSHs(newSVpvn_flags(buf.release, strlen(buf.release), SVs_TEMP));
1670 PUSHs(newSVpvn_flags(buf.version, strlen(buf.version), SVs_TEMP));
1671 PUSHs(newSVpvn_flags(buf.machine, strlen(buf.machine), SVs_TEMP));
8990e307 1672 }
a0d0e21e
LW
1673#else
1674 uname((char *) 0); /* A stub to call not_here(). */
1675#endif
8990e307 1676
85e6fe83 1677SysRet
a0d0e21e
LW
1678write(fd, buffer, nbytes)
1679 int fd
1680 char * buffer
1681 size_t nbytes
1682
33f01dd1
SH
1683SV *
1684tmpnam()
1685 PREINIT:
1686 STRLEN i;
1687 int len;
1688 CODE:
1689 RETVAL = newSVpvn("", 0);
1690 SvGROW(RETVAL, L_tmpnam);
1691 len = strlen(tmpnam(SvPV(RETVAL, i)));
1692 SvCUR_set(RETVAL, len);
1693 OUTPUT:
1694 RETVAL
a0d0e21e
LW
1695
1696void
1697abort()
1698
1699int
1700mblen(s, n)
1701 char * s
1702 size_t n
1703
1704size_t
1705mbstowcs(s, pwcs, n)
1706 wchar_t * s
1707 char * pwcs
1708 size_t n
1709
1710int
1711mbtowc(pwc, s, n)
1712 wchar_t * pwc
1713 char * s
1714 size_t n
1715
1716int
1717wcstombs(s, pwcs, n)
1718 char * s
1719 wchar_t * pwcs
1720 size_t n
1721
1722int
1723wctomb(s, wchar)
1724 char * s
1725 wchar_t wchar
1726
1727int
1728strcoll(s1, s2)
1729 char * s1
1730 char * s2
1731
a89d8a78
DH
1732void
1733strtod(str)
1734 char * str
1735 PREINIT:
1736 double num;
1737 char *unparsed;
1738 PPCODE:
36477c24 1739 SET_NUMERIC_LOCAL();
a89d8a78
DH
1740 num = strtod(str, &unparsed);
1741 PUSHs(sv_2mortal(newSVnv(num)));
1742 if (GIMME == G_ARRAY) {
924508f0 1743 EXTEND(SP, 1);
a89d8a78
DH
1744 if (unparsed)
1745 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1746 else
6b88bc9c 1747 PUSHs(&PL_sv_undef);
a89d8a78
DH
1748 }
1749
1750void
1751strtol(str, base = 0)
1752 char * str
1753 int base
1754 PREINIT:
1755 long num;
1756 char *unparsed;
1757 PPCODE:
1758 num = strtol(str, &unparsed, base);
42718184
RB
1759#if IVSIZE <= LONGSIZE
1760 if (num < IV_MIN || num > IV_MAX)
a89d8a78 1761 PUSHs(sv_2mortal(newSVnv((double)num)));
42718184
RB
1762 else
1763#endif
1764 PUSHs(sv_2mortal(newSViv((IV)num)));
a89d8a78 1765 if (GIMME == G_ARRAY) {
924508f0 1766 EXTEND(SP, 1);
a89d8a78
DH
1767 if (unparsed)
1768 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1769 else
6b88bc9c 1770 PUSHs(&PL_sv_undef);
a89d8a78
DH
1771 }
1772
1773void
1774strtoul(str, base = 0)
4b48cf39 1775 const char * str
a89d8a78
DH
1776 int base
1777 PREINIT:
1778 unsigned long num;
1779 char *unparsed;
1780 PPCODE:
1781 num = strtoul(str, &unparsed, base);
84c133a0
RB
1782#if IVSIZE <= LONGSIZE
1783 if (num > IV_MAX)
a89d8a78 1784 PUSHs(sv_2mortal(newSVnv((double)num)));
84c133a0
RB
1785 else
1786#endif
1787 PUSHs(sv_2mortal(newSViv((IV)num)));
a89d8a78 1788 if (GIMME == G_ARRAY) {
924508f0 1789 EXTEND(SP, 1);
a89d8a78
DH
1790 if (unparsed)
1791 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1792 else
6b88bc9c 1793 PUSHs(&PL_sv_undef);
a89d8a78
DH
1794 }
1795
8063af02 1796void
a0d0e21e
LW
1797strxfrm(src)
1798 SV * src
85e6fe83 1799 CODE:
a0d0e21e
LW
1800 {
1801 STRLEN srclen;
1802 STRLEN dstlen;
1803 char *p = SvPV(src,srclen);
1804 srclen++;
561b68a9 1805 ST(0) = sv_2mortal(newSV(srclen*4+1));
a0d0e21e
LW
1806 dstlen = strxfrm(SvPVX(ST(0)), p, (size_t)srclen);
1807 if (dstlen > srclen) {
1808 dstlen++;
1809 SvGROW(ST(0), dstlen);
1810 strxfrm(SvPVX(ST(0)), p, (size_t)dstlen);
1811 dstlen--;
1812 }
b162af07 1813 SvCUR_set(ST(0), dstlen);
a0d0e21e
LW
1814 SvPOK_only(ST(0));
1815 }
1816
1817SysRet
1818mkfifo(filename, mode)
1819 char * filename
1820 Mode_t mode
748a9306
LW
1821 CODE:
1822 TAINT_PROPER("mkfifo");
1823 RETVAL = mkfifo(filename, mode);
1824 OUTPUT:
1825 RETVAL
a0d0e21e
LW
1826
1827SysRet
1828tcdrain(fd)
1829 int fd
1830
1831
1832SysRet
1833tcflow(fd, action)
1834 int fd
1835 int action
1836
1837
1838SysRet
1839tcflush(fd, queue_selector)
1840 int fd
1841 int queue_selector
1842
1843SysRet
1844tcsendbreak(fd, duration)
1845 int fd
1846 int duration
1847
1848char *
c1646883 1849asctime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = -1)
a0d0e21e
LW
1850 int sec
1851 int min
1852 int hour
1853 int mday
1854 int mon
1855 int year
1856 int wday
1857 int yday
1858 int isdst
1859 CODE:
1860 {
1861 struct tm mytm;
7747499c 1862 init_tm(&mytm); /* XXX workaround - see init_tm() above */
a0d0e21e
LW
1863 mytm.tm_sec = sec;
1864 mytm.tm_min = min;
1865 mytm.tm_hour = hour;
1866 mytm.tm_mday = mday;
1867 mytm.tm_mon = mon;
1868 mytm.tm_year = year;
1869 mytm.tm_wday = wday;
1870 mytm.tm_yday = yday;
1871 mytm.tm_isdst = isdst;
1872 RETVAL = asctime(&mytm);
1873 }
1874 OUTPUT:
1875 RETVAL
1876
1877long
1878clock()
1879
1880char *
1881ctime(time)
748a9306 1882 Time_t &time
8990e307 1883
37120919
AD
1884void
1885times()
1886 PPCODE:
1887 struct tms tms;
1888 clock_t realtime;
1889 realtime = times( &tms );
924508f0 1890 EXTEND(SP,5);
9607fc9c
PP
1891 PUSHs( sv_2mortal( newSViv( (IV) realtime ) ) );
1892 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_utime ) ) );
1893 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_stime ) ) );
1894 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cutime ) ) );
1895 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cstime ) ) );
37120919 1896
a0d0e21e
LW
1897double
1898difftime(time1, time2)
1899 Time_t time1
1900 Time_t time2
1901
1902SysRetLong
c1646883 1903mktime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = -1)
a0d0e21e
LW
1904 int sec
1905 int min
1906 int hour
1907 int mday
1908 int mon
1909 int year
1910 int wday
1911 int yday
1912 int isdst
1913 CODE:
1914 {
1915 struct tm mytm;
7747499c 1916 init_tm(&mytm); /* XXX workaround - see init_tm() above */
a0d0e21e
LW
1917 mytm.tm_sec = sec;
1918 mytm.tm_min = min;
1919 mytm.tm_hour = hour;
1920 mytm.tm_mday = mday;
1921 mytm.tm_mon = mon;
1922 mytm.tm_year = year;
1923 mytm.tm_wday = wday;
1924 mytm.tm_yday = yday;
1925 mytm.tm_isdst = isdst;
aebaba0b 1926 RETVAL = (SysRetLong) mktime(&mytm);
a0d0e21e 1927 }
85e6fe83
LW
1928 OUTPUT:
1929 RETVAL
a0d0e21e 1930
8063af02
DM
1931#XXX: if $xsubpp::WantOptimize is always the default
1932# sv_setpv(TARG, ...) could be used rather than
1933# ST(0) = sv_2mortal(newSVpv(...))
1934void
e44f695e 1935strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1)
dc57de01 1936 SV * fmt
a0d0e21e
LW
1937 int sec
1938 int min
1939 int hour
1940 int mday
1941 int mon
1942 int year
1943 int wday
1944 int yday
1945 int isdst
1946 CODE:
1947 {
dc57de01 1948 char *buf = my_strftime(SvPV_nolen(fmt), sec, min, hour, mday, mon, year, wday, yday, isdst);
2a74cb2d 1949 if (buf) {
8dbe7cf7
NC
1950 SV *const sv = sv_newmortal();
1951 sv_usepvn_flags(sv, buf, strlen(buf), SV_HAS_TRAILING_NUL);
1952 if (SvUTF8(fmt)) {
1953 SvUTF8_on(sv);
1954 }
1955 ST(0) = sv;
2a74cb2d 1956 }
a0d0e21e
LW
1957 }
1958
1959void
1960tzset()
81ab4c44
SH
1961 PPCODE:
1962 my_tzset(aTHX);
a0d0e21e
LW
1963
1964void
1965tzname()
1966 PPCODE:
924508f0 1967 EXTEND(SP,2);
d3d34884
NC
1968 PUSHs(newSVpvn_flags(tzname[0], strlen(tzname[0]), SVs_TEMP));
1969 PUSHs(newSVpvn_flags(tzname[1], strlen(tzname[1]), SVs_TEMP));
a0d0e21e
LW
1970
1971SysRet
1972access(filename, mode)
1973 char * filename
1974 Mode_t mode
1975
1976char *
1977ctermid(s = 0)
3ab23a19
RGS
1978 char * s = 0;
1979 CODE:
1980#ifdef HAS_CTERMID_R
e02b9112 1981 s = (char *) safemalloc((size_t) L_ctermid);
3ab23a19
RGS
1982#endif
1983 RETVAL = ctermid(s);
1984 OUTPUT:
1985 RETVAL
d1fd7089 1986 CLEANUP:
3ab23a19 1987#ifdef HAS_CTERMID_R
d1fd7089 1988 Safefree(s);
3ab23a19 1989#endif
a0d0e21e
LW
1990
1991char *
1992cuserid(s = 0)
1993 char * s = 0;
56f4542c
TJ
1994 CODE:
1995#ifdef HAS_CUSERID
1996 RETVAL = cuserid(s);
1997#else
1998 RETVAL = 0;
1999 not_here("cuserid");
2000#endif
2001 OUTPUT:
2002 RETVAL
a0d0e21e
LW
2003
2004SysRetLong
2005fpathconf(fd, name)
2006 int fd
2007 int name
2008
2009SysRetLong
2010pathconf(filename, name)
2011 char * filename
2012 int name
2013
2014SysRet
2015pause()
2016
a043a685
GW
2017SysRet
2018setgid(gid)
2019 Gid_t gid
13ec70af 2020 CLEANUP:
e9df3e1a 2021#ifndef WIN32
13ec70af
RGS
2022 if (RETVAL >= 0) {
2023 PL_gid = getgid();
2024 PL_egid = getegid();
2025 }
e9df3e1a 2026#endif
a043a685
GW
2027
2028SysRet
2029setuid(uid)
2030 Uid_t uid
13ec70af 2031 CLEANUP:
e9df3e1a 2032#ifndef WIN32
13ec70af
RGS
2033 if (RETVAL >= 0) {
2034 PL_uid = getuid();
2035 PL_euid = geteuid();
2036 }
e9df3e1a 2037#endif
a043a685 2038
a0d0e21e
LW
2039SysRetLong
2040sysconf(name)
2041 int name
2042
2043char *
2044ttyname(fd)
2045 int fd
a043a685 2046
c6c619a9 2047void
b5846a0b 2048getcwd()
8f95b30d
JH
2049 PPCODE:
2050 {
2051 dXSTARG;
89423764 2052 getcwd_sv(TARG);
8f95b30d
JH
2053 XSprePUSH; PUSHTARG;
2054 }
2055
0d7021f5
RGS
2056SysRet
2057lchown(uid, gid, path)
2058 Uid_t uid
2059 Gid_t gid
2060 char * path
2061 CODE:
2062#ifdef HAS_LCHOWN
2063 /* yes, the order of arguments is different,
2064 * but consistent with CORE::chown() */
2065 RETVAL = lchown(path, uid, gid);
2066#else
2067 RETVAL = not_here("lchown");
2068#endif
2069 OUTPUT:
2070 RETVAL