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