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