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