allow POSIX SIGRTMIN...SIGRTMAX signals (and plug a core dump)
[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
3609ea0d 54/* XXX This comment is just to make I_TERMIO and I_SGTTY visible to
a0d0e21e 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")
3609ea0d 201# else /* !( defined OS2 ) */
d6a255e6 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
3609ea0d 268#define fpathconf(f,n) (SysRetLong) not_here("fpathconf")
a0d0e21e 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
3609ea0d 277#define pathconf(f,n) (SysRetLong) not_here("pathconf")
a0d0e21e 278#endif
279#ifndef HAS_SYSCONF
3609ea0d 280#define sysconf(n) (SysRetLong) not_here("sysconf")
a0d0e21e 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);
a290f238 416 */
417
418 switch (len) {
419 case 7:
420 /* Names all of length 7. */
421 /* S_ISBLK S_ISCHR S_ISDIR S_ISREG */
422 /* Offset 5 gives the best switch position. */
423 switch (name[5]) {
424 case 'E':
425 if (memEQ(name, "S_ISREG", 7)) {
426 /* ^ */
427#ifdef S_ISREG
428 *arg_result = S_ISREG(*arg_result);
429 return PERL_constant_ISIV;
2304df62 430#else
a290f238 431 return PERL_constant_NOTDEF;
2304df62 432#endif
a290f238 433 }
434 break;
435 case 'H':
436 if (memEQ(name, "S_ISCHR", 7)) {
437 /* ^ */
438#ifdef S_ISCHR
439 *arg_result = S_ISCHR(*arg_result);
440 return PERL_constant_ISIV;
2304df62 441#else
a290f238 442 return PERL_constant_NOTDEF;
2304df62 443#endif
a290f238 444 }
445 break;
446 case 'I':
447 if (memEQ(name, "S_ISDIR", 7)) {
448 /* ^ */
449#ifdef S_ISDIR
450 *arg_result = S_ISDIR(*arg_result);
451 return PERL_constant_ISIV;
2304df62 452#else
a290f238 453 return PERL_constant_NOTDEF;
2304df62 454#endif
a290f238 455 }
456 break;
457 case 'L':
458 if (memEQ(name, "S_ISBLK", 7)) {
459 /* ^ */
460#ifdef S_ISBLK
461 *arg_result = S_ISBLK(*arg_result);
462 return PERL_constant_ISIV;
2304df62 463#else
a290f238 464 return PERL_constant_NOTDEF;
2304df62 465#endif
a290f238 466 }
467 break;
468 }
469 break;
470 case 8:
471 /* Names all of length 8. */
472 /* S_ISFIFO WSTOPSIG WTERMSIG */
473 /* Offset 3 gives the best switch position. */
474 switch (name[3]) {
475 case 'O':
476 if (memEQ(name, "WSTOPSIG", 8)) {
477 /* ^ */
478#ifdef WSTOPSIG
bfbc3223 479 int i = *arg_result;
480 *arg_result = WSTOPSIG(WMUNGE(i));
a290f238 481 return PERL_constant_ISIV;
2304df62 482#else
a290f238 483 return PERL_constant_NOTDEF;
2304df62 484#endif
a290f238 485 }
486 break;
487 case 'R':
488 if (memEQ(name, "WTERMSIG", 8)) {
489 /* ^ */
490#ifdef WTERMSIG
bfbc3223 491 int i = *arg_result;
492 *arg_result = WTERMSIG(WMUNGE(i));
a290f238 493 return PERL_constant_ISIV;
2304df62 494#else
a290f238 495 return PERL_constant_NOTDEF;
2304df62 496#endif
a290f238 497 }
498 break;
499 case 'S':
500 if (memEQ(name, "S_ISFIFO", 8)) {
501 /* ^ */
502#ifdef S_ISFIFO
503 *arg_result = S_ISFIFO(*arg_result);
504 return PERL_constant_ISIV;
2304df62 505#else
a290f238 506 return PERL_constant_NOTDEF;
2304df62 507#endif
a290f238 508 }
509 break;
510 }
511 break;
512 case 9:
513 if (memEQ(name, "WIFEXITED", 9)) {
514#ifdef WIFEXITED
bfbc3223 515 int i = *arg_result;
516 *arg_result = WIFEXITED(WMUNGE(i));
a290f238 517 return PERL_constant_ISIV;
2304df62 518#else
a290f238 519 return PERL_constant_NOTDEF;
2304df62 520#endif
a290f238 521 }
522 break;
523 case 10:
524 if (memEQ(name, "WIFSTOPPED", 10)) {
525#ifdef WIFSTOPPED
bfbc3223 526 int i = *arg_result;
527 *arg_result = WIFSTOPPED(WMUNGE(i));
a290f238 528 return PERL_constant_ISIV;
2304df62 529#else
a290f238 530 return PERL_constant_NOTDEF;
2304df62 531#endif
a290f238 532 }
533 break;
534 case 11:
535 /* Names all of length 11. */
536 /* WEXITSTATUS WIFSIGNALED */
537 /* Offset 1 gives the best switch position. */
538 switch (name[1]) {
539 case 'E':
540 if (memEQ(name, "WEXITSTATUS", 11)) {
541 /* ^ */
542#ifdef WEXITSTATUS
bfbc3223 543 int i = *arg_result;
544 *arg_result = WEXITSTATUS(WMUNGE(i));
a290f238 545 return PERL_constant_ISIV;
2304df62 546#else
a290f238 547 return PERL_constant_NOTDEF;
2304df62 548#endif
a290f238 549 }
550 break;
551 case 'I':
552 if (memEQ(name, "WIFSIGNALED", 11)) {
553 /* ^ */
554#ifdef WIFSIGNALED
bfbc3223 555 int i = *arg_result;
556 *arg_result = WIFSIGNALED(WMUNGE(i));
a290f238 557 return PERL_constant_ISIV;
2304df62 558#else
a290f238 559 return PERL_constant_NOTDEF;
2304df62 560#endif
a290f238 561 }
562 break;
563 }
564 break;
565 }
566 return PERL_constant_NOTFOUND;
567}
568
1dfe7606 569static void
40b7a5f5 570restore_sigmask(pTHX_ SV *osset_sv)
1dfe7606 571{
7feb700b 572 /* Fortunately, restoring the signal mask can't fail, because
573 * there's nothing we can do about it if it does -- we're not
574 * supposed to return -1 from sigaction unless the disposition
575 * was unaffected.
576 */
7feb700b 577 sigset_t *ossetp = (sigset_t *) SvPV_nolen( osset_sv );
578 (void)sigprocmask(SIG_SETMASK, ossetp, (sigset_t *)0);
1dfe7606 579}
580
2304df62 581MODULE = SigSet PACKAGE = POSIX::SigSet PREFIX = sig
582
583POSIX::SigSet
584new(packname = "POSIX::SigSet", ...)
585 char * packname
586 CODE:
587 {
588 int i;
a02a5408 589 Newx(RETVAL, 1, sigset_t);
2304df62 590 sigemptyset(RETVAL);
a0d0e21e 591 for (i = 1; i < items; i++)
2304df62 592 sigaddset(RETVAL, SvIV(ST(i)));
593 }
594 OUTPUT:
595 RETVAL
463ee0b2 596
8990e307 597void
2304df62 598DESTROY(sigset)
599 POSIX::SigSet sigset
600 CODE:
01667c76 601 Safefree(sigset);
2304df62 602
603SysRet
604sigaddset(sigset, sig)
605 POSIX::SigSet sigset
606 int sig
607
608SysRet
609sigdelset(sigset, sig)
610 POSIX::SigSet sigset
611 int sig
612
613SysRet
614sigemptyset(sigset)
615 POSIX::SigSet sigset
616
617SysRet
618sigfillset(sigset)
619 POSIX::SigSet sigset
620
621int
622sigismember(sigset, sig)
623 POSIX::SigSet sigset
624 int sig
625
a0d0e21e 626MODULE = Termios PACKAGE = POSIX::Termios PREFIX = cf
627
628POSIX::Termios
629new(packname = "POSIX::Termios", ...)
630 char * packname
631 CODE:
632 {
633#ifdef I_TERMIOS
a02a5408 634 Newx(RETVAL, 1, struct termios);
a0d0e21e 635#else
636 not_here("termios");
640cc986 637 RETVAL = 0;
a0d0e21e 638#endif
639 }
640 OUTPUT:
641 RETVAL
642
643void
644DESTROY(termios_ref)
645 POSIX::Termios termios_ref
646 CODE:
647#ifdef I_TERMIOS
01667c76 648 Safefree(termios_ref);
a0d0e21e 649#else
650 not_here("termios");
651#endif
652
653SysRet
654getattr(termios_ref, fd = 0)
655 POSIX::Termios termios_ref
656 int fd
657 CODE:
658 RETVAL = tcgetattr(fd, termios_ref);
659 OUTPUT:
660 RETVAL
661
662SysRet
663setattr(termios_ref, fd = 0, optional_actions = 0)
664 POSIX::Termios termios_ref
665 int fd
666 int optional_actions
667 CODE:
668 RETVAL = tcsetattr(fd, optional_actions, termios_ref);
669 OUTPUT:
670 RETVAL
671
672speed_t
673cfgetispeed(termios_ref)
674 POSIX::Termios termios_ref
675
676speed_t
677cfgetospeed(termios_ref)
678 POSIX::Termios termios_ref
679
680tcflag_t
681getiflag(termios_ref)
682 POSIX::Termios termios_ref
683 CODE:
684#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
685 RETVAL = termios_ref->c_iflag;
686#else
640cc986 687 not_here("getiflag");
688 RETVAL = 0;
a0d0e21e 689#endif
690 OUTPUT:
691 RETVAL
692
693tcflag_t
694getoflag(termios_ref)
695 POSIX::Termios termios_ref
696 CODE:
697#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
698 RETVAL = termios_ref->c_oflag;
699#else
640cc986 700 not_here("getoflag");
701 RETVAL = 0;
a0d0e21e 702#endif
703 OUTPUT:
704 RETVAL
705
706tcflag_t
707getcflag(termios_ref)
708 POSIX::Termios termios_ref
709 CODE:
710#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
711 RETVAL = termios_ref->c_cflag;
712#else
640cc986 713 not_here("getcflag");
714 RETVAL = 0;
a0d0e21e 715#endif
716 OUTPUT:
717 RETVAL
718
719tcflag_t
720getlflag(termios_ref)
721 POSIX::Termios termios_ref
722 CODE:
723#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
724 RETVAL = termios_ref->c_lflag;
725#else
640cc986 726 not_here("getlflag");
727 RETVAL = 0;
a0d0e21e 728#endif
729 OUTPUT:
730 RETVAL
731
732cc_t
733getcc(termios_ref, ccix)
734 POSIX::Termios termios_ref
735 int ccix
736 CODE:
737#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
738 if (ccix >= NCCS)
739 croak("Bad getcc subscript");
740 RETVAL = termios_ref->c_cc[ccix];
741#else
640cc986 742 not_here("getcc");
743 RETVAL = 0;
a0d0e21e 744#endif
745 OUTPUT:
746 RETVAL
747
748SysRet
749cfsetispeed(termios_ref, speed)
750 POSIX::Termios termios_ref
751 speed_t speed
752
753SysRet
754cfsetospeed(termios_ref, speed)
755 POSIX::Termios termios_ref
756 speed_t speed
757
758void
759setiflag(termios_ref, iflag)
760 POSIX::Termios termios_ref
761 tcflag_t iflag
762 CODE:
763#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
764 termios_ref->c_iflag = iflag;
765#else
766 not_here("setiflag");
767#endif
768
769void
770setoflag(termios_ref, oflag)
771 POSIX::Termios termios_ref
772 tcflag_t oflag
773 CODE:
774#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
775 termios_ref->c_oflag = oflag;
776#else
777 not_here("setoflag");
778#endif
779
780void
781setcflag(termios_ref, cflag)
782 POSIX::Termios termios_ref
783 tcflag_t cflag
784 CODE:
785#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
786 termios_ref->c_cflag = cflag;
787#else
788 not_here("setcflag");
789#endif
790
791void
792setlflag(termios_ref, lflag)
793 POSIX::Termios termios_ref
794 tcflag_t lflag
795 CODE:
796#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
797 termios_ref->c_lflag = lflag;
798#else
799 not_here("setlflag");
800#endif
801
802void
803setcc(termios_ref, ccix, cc)
804 POSIX::Termios termios_ref
805 int ccix
806 cc_t cc
807 CODE:
808#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
809 if (ccix >= NCCS)
810 croak("Bad setcc subscript");
811 termios_ref->c_cc[ccix] = cc;
812#else
813 not_here("setcc");
814#endif
815
816
a0d0e21e 817MODULE = POSIX PACKAGE = POSIX
818
1cb0fb50 819INCLUDE: const-xs.inc
a290f238 820
821void
822int_macro_int(sv, iv)
823 PREINIT:
824 dXSTARG;
825 STRLEN len;
826 int type;
827 INPUT:
828 SV * sv;
829 const char * s = SvPV(sv, len);
830 IV iv;
831 PPCODE:
832 /* Change this to int_macro_int(s, len, &iv, &nv);
833 if you need to return both NVs and IVs */
834 type = int_macro_int(s, len, &iv);
835 /* Return 1 or 2 items. First is error message, or undef if no error.
836 Second, if present, is found value */
837 switch (type) {
838 case PERL_constant_NOTFOUND:
839 sv = sv_2mortal(newSVpvf("%s is not a valid POSIX macro", s));
840 EXTEND(SP, 1);
841 PUSHs(&PL_sv_undef);
842 PUSHs(sv);
843 break;
844 case PERL_constant_NOTDEF:
845 sv = sv_2mortal(newSVpvf(
846 "Your vendor has not defined POSIX macro %s, used", s));
847 EXTEND(SP, 1);
848 PUSHs(&PL_sv_undef);
849 PUSHs(sv);
850 break;
851 case PERL_constant_ISIV:
852 PUSHi(iv);
853 break;
854 default:
855 sv = sv_2mortal(newSVpvf(
856 "Unexpected return type %d while processing POSIX macro %s, used",
857 type, s));
858 EXTEND(SP, 1);
859 PUSHs(&PL_sv_undef);
860 PUSHs(sv);
861 }
2304df62 862
863int
864isalnum(charstring)
767bb2e0 865 SV * charstring
866 PREINIT:
867 STRLEN len;
2304df62 868 CODE:
767bb2e0 869 unsigned char *s = (unsigned char *) SvPV(charstring, len);
870 unsigned char *e = s + len;
5344da4e 871 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 872 if (!isalnum(*s))
873 RETVAL = 0;
874 OUTPUT:
875 RETVAL
876
877int
878isalpha(charstring)
767bb2e0 879 SV * charstring
880 PREINIT:
881 STRLEN len;
2304df62 882 CODE:
767bb2e0 883 unsigned char *s = (unsigned char *) SvPV(charstring, len);
884 unsigned char *e = s + len;
5344da4e 885 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 886 if (!isalpha(*s))
887 RETVAL = 0;
888 OUTPUT:
889 RETVAL
890
891int
892iscntrl(charstring)
767bb2e0 893 SV * charstring
894 PREINIT:
895 STRLEN len;
2304df62 896 CODE:
767bb2e0 897 unsigned char *s = (unsigned char *) SvPV(charstring, len);
898 unsigned char *e = s + len;
5344da4e 899 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 900 if (!iscntrl(*s))
901 RETVAL = 0;
902 OUTPUT:
903 RETVAL
904
905int
906isdigit(charstring)
767bb2e0 907 SV * charstring
908 PREINIT:
909 STRLEN len;
2304df62 910 CODE:
767bb2e0 911 unsigned char *s = (unsigned char *) SvPV(charstring, len);
912 unsigned char *e = s + len;
5344da4e 913 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 914 if (!isdigit(*s))
915 RETVAL = 0;
916 OUTPUT:
917 RETVAL
918
919int
920isgraph(charstring)
767bb2e0 921 SV * charstring
922 PREINIT:
923 STRLEN len;
2304df62 924 CODE:
767bb2e0 925 unsigned char *s = (unsigned char *) SvPV(charstring, len);
926 unsigned char *e = s + len;
5344da4e 927 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 928 if (!isgraph(*s))
929 RETVAL = 0;
930 OUTPUT:
931 RETVAL
932
933int
934islower(charstring)
767bb2e0 935 SV * charstring
936 PREINIT:
937 STRLEN len;
2304df62 938 CODE:
767bb2e0 939 unsigned char *s = (unsigned char *) SvPV(charstring, len);
940 unsigned char *e = s + len;
5344da4e 941 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 942 if (!islower(*s))
943 RETVAL = 0;
944 OUTPUT:
945 RETVAL
946
947int
948isprint(charstring)
767bb2e0 949 SV * charstring
950 PREINIT:
951 STRLEN len;
2304df62 952 CODE:
767bb2e0 953 unsigned char *s = (unsigned char *) SvPV(charstring, len);
954 unsigned char *e = s + len;
5344da4e 955 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 956 if (!isprint(*s))
957 RETVAL = 0;
958 OUTPUT:
959 RETVAL
960
961int
962ispunct(charstring)
767bb2e0 963 SV * charstring
964 PREINIT:
965 STRLEN len;
2304df62 966 CODE:
767bb2e0 967 unsigned char *s = (unsigned char *) SvPV(charstring, len);
968 unsigned char *e = s + len;
5344da4e 969 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 970 if (!ispunct(*s))
971 RETVAL = 0;
972 OUTPUT:
973 RETVAL
974
975int
976isspace(charstring)
767bb2e0 977 SV * charstring
978 PREINIT:
979 STRLEN len;
2304df62 980 CODE:
767bb2e0 981 unsigned char *s = (unsigned char *) SvPV(charstring, len);
982 unsigned char *e = s + len;
5344da4e 983 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 984 if (!isspace(*s))
985 RETVAL = 0;
986 OUTPUT:
987 RETVAL
8990e307 988
989int
2304df62 990isupper(charstring)
767bb2e0 991 SV * charstring
992 PREINIT:
993 STRLEN len;
2304df62 994 CODE:
767bb2e0 995 unsigned char *s = (unsigned char *) SvPV(charstring, len);
996 unsigned char *e = s + len;
5344da4e 997 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 998 if (!isupper(*s))
999 RETVAL = 0;
1000 OUTPUT:
1001 RETVAL
8990e307 1002
1003int
2304df62 1004isxdigit(charstring)
767bb2e0 1005 SV * charstring
1006 PREINIT:
1007 STRLEN len;
2304df62 1008 CODE:
767bb2e0 1009 unsigned char *s = (unsigned char *) SvPV(charstring, len);
1010 unsigned char *e = s + len;
5344da4e 1011 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 1012 if (!isxdigit(*s))
1013 RETVAL = 0;
1014 OUTPUT:
1015 RETVAL
1016
1017SysRet
1018open(filename, flags = O_RDONLY, mode = 0666)
1019 char * filename
1020 int flags
a0d0e21e 1021 Mode_t mode
748a9306 1022 CODE:
1023 if (flags & (O_APPEND|O_CREAT|O_TRUNC|O_RDWR|O_WRONLY|O_EXCL))
1024 TAINT_PROPER("open");
1025 RETVAL = open(filename, flags, mode);
1026 OUTPUT:
1027 RETVAL
1028
2304df62 1029
1030HV *
1031localeconv()
1032 CODE:
a0d0e21e 1033#ifdef HAS_LOCALECONV
2304df62 1034 struct lconv *lcbuf;
1035 RETVAL = newHV();
c4e79b56 1036 sv_2mortal((SV*)RETVAL);
8063af02 1037 if ((lcbuf = localeconv())) {
2304df62 1038 /* the strings */
1039 if (lcbuf->decimal_point && *lcbuf->decimal_point)
1040 hv_store(RETVAL, "decimal_point", 13,
1041 newSVpv(lcbuf->decimal_point, 0), 0);
1042 if (lcbuf->thousands_sep && *lcbuf->thousands_sep)
1043 hv_store(RETVAL, "thousands_sep", 13,
1044 newSVpv(lcbuf->thousands_sep, 0), 0);
28e8609d 1045#ifndef NO_LOCALECONV_GROUPING
2304df62 1046 if (lcbuf->grouping && *lcbuf->grouping)
1047 hv_store(RETVAL, "grouping", 8,
1048 newSVpv(lcbuf->grouping, 0), 0);
28e8609d 1049#endif
2304df62 1050 if (lcbuf->int_curr_symbol && *lcbuf->int_curr_symbol)
1051 hv_store(RETVAL, "int_curr_symbol", 15,
1052 newSVpv(lcbuf->int_curr_symbol, 0), 0);
1053 if (lcbuf->currency_symbol && *lcbuf->currency_symbol)
1054 hv_store(RETVAL, "currency_symbol", 15,
1055 newSVpv(lcbuf->currency_symbol, 0), 0);
1056 if (lcbuf->mon_decimal_point && *lcbuf->mon_decimal_point)
1057 hv_store(RETVAL, "mon_decimal_point", 17,
1058 newSVpv(lcbuf->mon_decimal_point, 0), 0);
39e571d4 1059#ifndef NO_LOCALECONV_MON_THOUSANDS_SEP
2304df62 1060 if (lcbuf->mon_thousands_sep && *lcbuf->mon_thousands_sep)
1061 hv_store(RETVAL, "mon_thousands_sep", 17,
1062 newSVpv(lcbuf->mon_thousands_sep, 0), 0);
3609ea0d 1063#endif
28e8609d 1064#ifndef NO_LOCALECONV_MON_GROUPING
2304df62 1065 if (lcbuf->mon_grouping && *lcbuf->mon_grouping)
1066 hv_store(RETVAL, "mon_grouping", 12,
1067 newSVpv(lcbuf->mon_grouping, 0), 0);
28e8609d 1068#endif
2304df62 1069 if (lcbuf->positive_sign && *lcbuf->positive_sign)
1070 hv_store(RETVAL, "positive_sign", 13,
1071 newSVpv(lcbuf->positive_sign, 0), 0);
1072 if (lcbuf->negative_sign && *lcbuf->negative_sign)
1073 hv_store(RETVAL, "negative_sign", 13,
1074 newSVpv(lcbuf->negative_sign, 0), 0);
1075 /* the integers */
1076 if (lcbuf->int_frac_digits != CHAR_MAX)
1077 hv_store(RETVAL, "int_frac_digits", 15,
1078 newSViv(lcbuf->int_frac_digits), 0);
1079 if (lcbuf->frac_digits != CHAR_MAX)
1080 hv_store(RETVAL, "frac_digits", 11,
1081 newSViv(lcbuf->frac_digits), 0);
1082 if (lcbuf->p_cs_precedes != CHAR_MAX)
1083 hv_store(RETVAL, "p_cs_precedes", 13,
1084 newSViv(lcbuf->p_cs_precedes), 0);
1085 if (lcbuf->p_sep_by_space != CHAR_MAX)
1086 hv_store(RETVAL, "p_sep_by_space", 14,
1087 newSViv(lcbuf->p_sep_by_space), 0);
1088 if (lcbuf->n_cs_precedes != CHAR_MAX)
1089 hv_store(RETVAL, "n_cs_precedes", 13,
1090 newSViv(lcbuf->n_cs_precedes), 0);
1091 if (lcbuf->n_sep_by_space != CHAR_MAX)
1092 hv_store(RETVAL, "n_sep_by_space", 14,
1093 newSViv(lcbuf->n_sep_by_space), 0);
1094 if (lcbuf->p_sign_posn != CHAR_MAX)
1095 hv_store(RETVAL, "p_sign_posn", 11,
1096 newSViv(lcbuf->p_sign_posn), 0);
1097 if (lcbuf->n_sign_posn != CHAR_MAX)
1098 hv_store(RETVAL, "n_sign_posn", 11,
1099 newSViv(lcbuf->n_sign_posn), 0);
1100 }
a0d0e21e 1101#else
1102 localeconv(); /* A stub to call not_here(). */
1103#endif
2304df62 1104 OUTPUT:
1105 RETVAL
1106
1107char *
c28ee57b 1108setlocale(category, locale = 0)
2304df62 1109 int category
1110 char * locale
c28ee57b 1111 CODE:
1112 RETVAL = setlocale(category, locale);
bbce6d69 1113 if (RETVAL) {
36477c24 1114#ifdef USE_LOCALE_CTYPE
bbce6d69 1115 if (category == LC_CTYPE
1116#ifdef LC_ALL
1117 || category == LC_ALL
1118#endif
1119 )
1120 {
1121 char *newctype;
1122#ifdef LC_ALL
1123 if (category == LC_ALL)
1124 newctype = setlocale(LC_CTYPE, NULL);
1125 else
1126#endif
1127 newctype = RETVAL;
864dbfa3 1128 new_ctype(newctype);
bbce6d69 1129 }
36477c24 1130#endif /* USE_LOCALE_CTYPE */
1131#ifdef USE_LOCALE_COLLATE
bbce6d69 1132 if (category == LC_COLLATE
1133#ifdef LC_ALL
1134 || category == LC_ALL
1135#endif
1136 )
1137 {
1138 char *newcoll;
1139#ifdef LC_ALL
1140 if (category == LC_ALL)
1141 newcoll = setlocale(LC_COLLATE, NULL);
1142 else
1143#endif
1144 newcoll = RETVAL;
864dbfa3 1145 new_collate(newcoll);
bbce6d69 1146 }
36477c24 1147#endif /* USE_LOCALE_COLLATE */
1148#ifdef USE_LOCALE_NUMERIC
bbce6d69 1149 if (category == LC_NUMERIC
1150#ifdef LC_ALL
1151 || category == LC_ALL
1152#endif
1153 )
1154 {
1155 char *newnum;
1156#ifdef LC_ALL
1157 if (category == LC_ALL)
1158 newnum = setlocale(LC_NUMERIC, NULL);
1159 else
1160#endif
1161 newnum = RETVAL;
864dbfa3 1162 new_numeric(newnum);
bbce6d69 1163 }
36477c24 1164#endif /* USE_LOCALE_NUMERIC */
bbce6d69 1165 }
c28ee57b 1166 OUTPUT:
1167 RETVAL
1168
2304df62 1169
e1ca407b 1170NV
2304df62 1171acos(x)
e1ca407b 1172 NV x
2304df62 1173
e1ca407b 1174NV
2304df62 1175asin(x)
e1ca407b 1176 NV x
2304df62 1177
e1ca407b 1178NV
2304df62 1179atan(x)
e1ca407b 1180 NV x
2304df62 1181
e1ca407b 1182NV
2304df62 1183ceil(x)
e1ca407b 1184 NV x
2304df62 1185
e1ca407b 1186NV
2304df62 1187cosh(x)
e1ca407b 1188 NV x
2304df62 1189
e1ca407b 1190NV
2304df62 1191floor(x)
e1ca407b 1192 NV x
2304df62 1193
e1ca407b 1194NV
2304df62 1195fmod(x,y)
e1ca407b 1196 NV x
1197 NV y
2304df62 1198
1199void
1200frexp(x)
e1ca407b 1201 NV x
2304df62 1202 PPCODE:
1203 int expvar;
2304df62 1204 /* (We already know stack is long enough.) */
1205 PUSHs(sv_2mortal(newSVnv(frexp(x,&expvar))));
1206 PUSHs(sv_2mortal(newSViv(expvar)));
1207
e1ca407b 1208NV
2304df62 1209ldexp(x,exp)
e1ca407b 1210 NV x
2304df62 1211 int exp
1212
e1ca407b 1213NV
2304df62 1214log10(x)
e1ca407b 1215 NV x
2304df62 1216
1217void
1218modf(x)
e1ca407b 1219 NV x
2304df62 1220 PPCODE:
e1ca407b 1221 NV intvar;
2304df62 1222 /* (We already know stack is long enough.) */
bf4acbe4 1223 PUSHs(sv_2mortal(newSVnv(Perl_modf(x,&intvar))));
2304df62 1224 PUSHs(sv_2mortal(newSVnv(intvar)));
1225
e1ca407b 1226NV
2304df62 1227sinh(x)
e1ca407b 1228 NV x
2304df62 1229
e1ca407b 1230NV
3b35bae3 1231tan(x)
e1ca407b 1232 NV x
3b35bae3 1233
e1ca407b 1234NV
2304df62 1235tanh(x)
e1ca407b 1236 NV x
2304df62 1237
1238SysRet
1dfe7606 1239sigaction(sig, optaction, oldaction = 0)
2304df62 1240 int sig
1dfe7606 1241 SV * optaction
2304df62 1242 POSIX::SigAction oldaction
1243 CODE:
2986a63f 1244#if defined(WIN32) || defined(NETWARE)
6dead956 1245 RETVAL = not_here("sigaction");
1246#else
2304df62 1247# This code is really grody because we're trying to make the signal
1248# interface look beautiful, which is hard.
1249
2304df62 1250 {
27da23d5 1251 dVAR;
1dfe7606 1252 POSIX__SigAction action;
f4c556ac 1253 GV *siggv = gv_fetchpv("SIG", TRUE, SVt_PVHV);
2304df62 1254 struct sigaction act;
1255 struct sigaction oact;
1dfe7606 1256 sigset_t sset;
183bde56 1257 SV *osset_sv;
27c1a449 1258 sigset_t osset;
2304df62 1259 POSIX__SigSet sigset;
1260 SV** svp;
1d81eac9 1261 SV** sigsvp;
3609ea0d 1262
1d81eac9 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 }
3609ea0d 1278#ifdef NSIG
1279 if (sig > NSIG) { /* NSIG - 1 is still okay. */
1280 Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
1281 "No such signal: %d", sig);
1282 XSRETURN_UNDEF;
1283 }
1284#endif
1d81eac9 1285 sigsvp = hv_fetch(GvHVn(siggv),
1286 PL_sig_name[sig],
1287 strlen(PL_sig_name[sig]),
1288 TRUE);
2304df62 1289
1dfe7606 1290 /* Check optaction and set action */
1291 if(SvTRUE(optaction)) {
1292 if(sv_isa(optaction, "POSIX::SigAction"))
1293 action = (HV*)SvRV(optaction);
1294 else
1295 croak("action is not of type POSIX::SigAction");
1296 }
1297 else {
1298 action=0;
1299 }
1300
1301 /* sigaction() is supposed to look atomic. In particular, any
1302 * signal handler invoked during a sigaction() call should
1303 * see either the old or the new disposition, and not something
1304 * in between. We use sigprocmask() to make it so.
1305 */
1306 sigfillset(&sset);
1307 RETVAL=sigprocmask(SIG_BLOCK, &sset, &osset);
1308 if(RETVAL == -1)
15c0d34a 1309 XSRETURN_UNDEF;
1dfe7606 1310 ENTER;
1311 /* Restore signal mask no matter how we exit this block. */
183bde56 1312 osset_sv = newSVpv((char *)(&osset), sizeof(sigset_t));
1313 SAVEFREESV( osset_sv );
40b7a5f5 1314 SAVEDESTRUCTOR_X(restore_sigmask, osset_sv);
1dfe7606 1315
1316 RETVAL=-1; /* In case both oldaction and action are 0. */
1317
1318 /* Remember old disposition if desired. */
2304df62 1319 if (oldaction) {
2304df62 1320 svp = hv_fetch(oldaction, "HANDLER", 7, TRUE);
1dfe7606 1321 if(!svp)
1322 croak("Can't supply an oldaction without a HANDLER");
1323 if(SvTRUE(*sigsvp)) { /* TBD: what if "0"? */
1324 sv_setsv(*svp, *sigsvp);
1325 }
1326 else {
1327 sv_setpv(*svp, "DEFAULT");
1328 }
1329 RETVAL = sigaction(sig, (struct sigaction *)0, & oact);
1330 if(RETVAL == -1)
15c0d34a 1331 XSRETURN_UNDEF;
1dfe7606 1332 /* Get back the mask. */
1333 svp = hv_fetch(oldaction, "MASK", 4, TRUE);
1334 if (sv_isa(*svp, "POSIX::SigSet")) {
1335 IV tmp = SvIV((SV*)SvRV(*svp));
1336 sigset = INT2PTR(sigset_t*, tmp);
1337 }
1338 else {
a02a5408 1339 Newx(sigset, 1, sigset_t);
1dfe7606 1340 sv_setptrobj(*svp, sigset, "POSIX::SigSet");
1341 }
1342 *sigset = oact.sa_mask;
1343
1344 /* Get back the flags. */
1345 svp = hv_fetch(oldaction, "FLAGS", 5, TRUE);
1346 sv_setiv(*svp, oact.sa_flags);
d36b6582 1347
1348 /* Get back whether the old handler used safe signals. */
1349 svp = hv_fetch(oldaction, "SAFE", 4, TRUE);
5c1546dc 1350 sv_setiv(*svp, oact.sa_handler == PL_csighandlerp);
2304df62 1351 }
1352
1353 if (action) {
d36b6582 1354 /* Safe signals use "csighandler", which vectors through the
1355 PL_sighandlerp pointer when it's safe to do so.
1356 (BTW, "csighandler" is very different from "sighandler".) */
1357 svp = hv_fetch(action, "SAFE", 4, FALSE);
1358 act.sa_handler = (*svp && SvTRUE(*svp))
b4ed63f0 1359 ? PL_csighandlerp : PL_sighandlerp;
d36b6582 1360
1361 /* Vector new Perl handler through %SIG.
1362 (The core signal handlers read %SIG to dispatch.) */
2304df62 1363 svp = hv_fetch(action, "HANDLER", 7, FALSE);
1364 if (!svp)
1365 croak("Can't supply an action without a HANDLER");
1dfe7606 1366 sv_setsv(*sigsvp, *svp);
d36b6582 1367
1368 /* This call actually calls sigaction() with almost the
1369 right settings, including appropriate interpretation
1370 of DEFAULT and IGNORE. However, why are we doing
1371 this when we're about to do it again just below? XXX */
1372 mg_set(*sigsvp);
1373
1374 /* And here again we duplicate -- DEFAULT/IGNORE checking. */
1dfe7606 1375 if(SvPOK(*svp)) {
aa07b2f6 1376 const char *s=SvPVX_const(*svp);
1dfe7606 1377 if(strEQ(s,"IGNORE")) {
1378 act.sa_handler = SIG_IGN;
1379 }
1380 else if(strEQ(s,"DEFAULT")) {
1381 act.sa_handler = SIG_DFL;
1382 }
1dfe7606 1383 }
2304df62 1384
1385 /* Set up any desired mask. */
1386 svp = hv_fetch(action, "MASK", 4, FALSE);
1387 if (svp && sv_isa(*svp, "POSIX::SigSet")) {
ac634a9a 1388 IV tmp = SvIV((SV*)SvRV(*svp));
1dfe7606 1389 sigset = INT2PTR(sigset_t*, tmp);
2304df62 1390 act.sa_mask = *sigset;
1391 }
1392 else
85e6fe83 1393 sigemptyset(& act.sa_mask);
2304df62 1394
1395 /* Set up any desired flags. */
1396 svp = hv_fetch(action, "FLAGS", 5, FALSE);
1397 act.sa_flags = svp ? SvIV(*svp) : 0;
2304df62 1398
1dfe7606 1399 /* Don't worry about cleaning up *sigsvp if this fails,
1400 * because that means we tried to disposition a
1401 * nonblockable signal, in which case *sigsvp is
1402 * essentially meaningless anyway.
1403 */
6c418a22 1404 RETVAL = sigaction(sig, & act, (struct sigaction *)0);
15c0d34a 1405 if(RETVAL == -1)
1406 XSRETURN_UNDEF;
2304df62 1407 }
1dfe7606 1408
1409 LEAVE;
2304df62 1410 }
6dead956 1411#endif
2304df62 1412 OUTPUT:
1413 RETVAL
1414
1415SysRet
1416sigpending(sigset)
1417 POSIX::SigSet sigset
1418
1419SysRet
1420sigprocmask(how, sigset, oldsigset = 0)
1421 int how
b13bbac7 1422 POSIX::SigSet sigset = NO_INIT
33c27489 1423 POSIX::SigSet oldsigset = NO_INIT
1424INIT:
a3b811a7 1425 if (! SvOK(ST(1))) {
b13bbac7 1426 sigset = NULL;
a3b811a7 1427 } else if (sv_isa(ST(1), "POSIX::SigSet")) {
b13bbac7 1428 IV tmp = SvIV((SV*)SvRV(ST(1)));
1429 sigset = INT2PTR(POSIX__SigSet,tmp);
1430 } else {
1431 croak("sigset is not of type POSIX::SigSet");
33c27489 1432 }
b13bbac7 1433
194cfca0 1434 if (items < 3 || ! SvOK(ST(2))) {
b13bbac7 1435 oldsigset = NULL;
a3b811a7 1436 } else if (sv_isa(ST(2), "POSIX::SigSet")) {
33c27489 1437 IV tmp = SvIV((SV*)SvRV(ST(2)));
56431972 1438 oldsigset = INT2PTR(POSIX__SigSet,tmp);
b13bbac7 1439 } else {
1440 croak("oldsigset is not of type POSIX::SigSet");
33c27489 1441 }
2304df62 1442
1443SysRet
1444sigsuspend(signal_mask)
1445 POSIX::SigSet signal_mask
1446
2304df62 1447void
1448_exit(status)
1449 int status
8990e307 1450
85e6fe83 1451SysRet
8990e307 1452close(fd)
1453 int fd
1454
85e6fe83 1455SysRet
8990e307 1456dup(fd)
1457 int fd
1458
85e6fe83 1459SysRet
8990e307 1460dup2(fd1, fd2)
1461 int fd1
1462 int fd2
1463
4a9d6100 1464SV *
a0d0e21e 1465lseek(fd, offset, whence)
85e6fe83 1466 int fd
1467 Off_t offset
1468 int whence
4a9d6100 1469 CODE:
1470 Off_t pos = PerlLIO_lseek(fd, offset, whence);
1471 RETVAL = sizeof(Off_t) > sizeof(IV)
1472 ? newSVnv((NV)pos) : newSViv((IV)pos);
1473 OUTPUT:
1474 RETVAL
8990e307 1475
c5661c80 1476void
8990e307 1477nice(incr)
1478 int incr
15f0f28a 1479 PPCODE:
1480 errno = 0;
1481 if ((incr = nice(incr)) != -1 || errno == 0) {
1482 if (incr == 0)
1483 XPUSHs(sv_2mortal(newSVpvn("0 but true", 10)));
1484 else
1485 XPUSHs(sv_2mortal(newSViv(incr)));
1486 }
8990e307 1487
8063af02 1488void
8990e307 1489pipe()
85e6fe83 1490 PPCODE:
1491 int fds[2];
85e6fe83 1492 if (pipe(fds) != -1) {
924508f0 1493 EXTEND(SP,2);
85e6fe83 1494 PUSHs(sv_2mortal(newSViv(fds[0])));
1495 PUSHs(sv_2mortal(newSViv(fds[1])));
1496 }
8990e307 1497
85e6fe83 1498SysRet
a0d0e21e 1499read(fd, buffer, nbytes)
7747499c 1500 PREINIT:
1501 SV *sv_buffer = SvROK(ST(1)) ? SvRV(ST(1)) : ST(1);
1502 INPUT:
1503 int fd
1504 size_t nbytes
1505 char * buffer = sv_grow( sv_buffer, nbytes+1 );
a0d0e21e 1506 CLEANUP:
7747499c 1507 if (RETVAL >= 0) {
b162af07 1508 SvCUR_set(sv_buffer, RETVAL);
7747499c 1509 SvPOK_only(sv_buffer);
1510 *SvEND(sv_buffer) = '\0';
bbce6d69 1511 SvTAINTED_on(sv_buffer);
7747499c 1512 }
8990e307 1513
85e6fe83 1514SysRet
8990e307 1515setpgid(pid, pgid)
86200d5c 1516 pid_t pid
1517 pid_t pgid
8990e307 1518
86200d5c 1519pid_t
8990e307 1520setsid()
1521
86200d5c 1522pid_t
8990e307 1523tcgetpgrp(fd)
1524 int fd
1525
85e6fe83 1526SysRet
8990e307 1527tcsetpgrp(fd, pgrp_id)
1528 int fd
86200d5c 1529 pid_t pgrp_id
8990e307 1530
8063af02 1531void
8990e307 1532uname()
2304df62 1533 PPCODE:
a0d0e21e 1534#ifdef HAS_UNAME
85e6fe83 1535 struct utsname buf;
85e6fe83 1536 if (uname(&buf) >= 0) {
924508f0 1537 EXTEND(SP, 5);
85e6fe83 1538 PUSHs(sv_2mortal(newSVpv(buf.sysname, 0)));
1539 PUSHs(sv_2mortal(newSVpv(buf.nodename, 0)));
1540 PUSHs(sv_2mortal(newSVpv(buf.release, 0)));
1541 PUSHs(sv_2mortal(newSVpv(buf.version, 0)));
1542 PUSHs(sv_2mortal(newSVpv(buf.machine, 0)));
8990e307 1543 }
a0d0e21e 1544#else
1545 uname((char *) 0); /* A stub to call not_here(). */
1546#endif
8990e307 1547
85e6fe83 1548SysRet
a0d0e21e 1549write(fd, buffer, nbytes)
1550 int fd
1551 char * buffer
1552 size_t nbytes
1553
33f01dd1 1554SV *
1555tmpnam()
1556 PREINIT:
1557 STRLEN i;
1558 int len;
1559 CODE:
1560 RETVAL = newSVpvn("", 0);
1561 SvGROW(RETVAL, L_tmpnam);
1562 len = strlen(tmpnam(SvPV(RETVAL, i)));
1563 SvCUR_set(RETVAL, len);
1564 OUTPUT:
1565 RETVAL
a0d0e21e 1566
1567void
1568abort()
1569
1570int
1571mblen(s, n)
1572 char * s
1573 size_t n
1574
1575size_t
1576mbstowcs(s, pwcs, n)
1577 wchar_t * s
1578 char * pwcs
1579 size_t n
1580
1581int
1582mbtowc(pwc, s, n)
1583 wchar_t * pwc
1584 char * s
1585 size_t n
1586
1587int
1588wcstombs(s, pwcs, n)
1589 char * s
1590 wchar_t * pwcs
1591 size_t n
1592
1593int
1594wctomb(s, wchar)
1595 char * s
1596 wchar_t wchar
1597
1598int
1599strcoll(s1, s2)
1600 char * s1
1601 char * s2
1602
a89d8a78 1603void
1604strtod(str)
1605 char * str
1606 PREINIT:
1607 double num;
1608 char *unparsed;
1609 PPCODE:
36477c24 1610 SET_NUMERIC_LOCAL();
a89d8a78 1611 num = strtod(str, &unparsed);
1612 PUSHs(sv_2mortal(newSVnv(num)));
1613 if (GIMME == G_ARRAY) {
924508f0 1614 EXTEND(SP, 1);
a89d8a78 1615 if (unparsed)
1616 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1617 else
6b88bc9c 1618 PUSHs(&PL_sv_undef);
a89d8a78 1619 }
1620
1621void
1622strtol(str, base = 0)
1623 char * str
1624 int base
1625 PREINIT:
1626 long num;
1627 char *unparsed;
1628 PPCODE:
1629 num = strtol(str, &unparsed, base);
42718184 1630#if IVSIZE <= LONGSIZE
1631 if (num < IV_MIN || num > IV_MAX)
a89d8a78 1632 PUSHs(sv_2mortal(newSVnv((double)num)));
42718184 1633 else
1634#endif
1635 PUSHs(sv_2mortal(newSViv((IV)num)));
a89d8a78 1636 if (GIMME == G_ARRAY) {
924508f0 1637 EXTEND(SP, 1);
a89d8a78 1638 if (unparsed)
1639 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1640 else
6b88bc9c 1641 PUSHs(&PL_sv_undef);
a89d8a78 1642 }
1643
1644void
1645strtoul(str, base = 0)
1646 char * str
1647 int base
1648 PREINIT:
1649 unsigned long num;
1650 char *unparsed;
1651 PPCODE:
1652 num = strtoul(str, &unparsed, base);
84c133a0 1653#if IVSIZE <= LONGSIZE
1654 if (num > IV_MAX)
a89d8a78 1655 PUSHs(sv_2mortal(newSVnv((double)num)));
84c133a0 1656 else
1657#endif
1658 PUSHs(sv_2mortal(newSViv((IV)num)));
a89d8a78 1659 if (GIMME == G_ARRAY) {
924508f0 1660 EXTEND(SP, 1);
a89d8a78 1661 if (unparsed)
1662 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1663 else
6b88bc9c 1664 PUSHs(&PL_sv_undef);
a89d8a78 1665 }
1666
8063af02 1667void
a0d0e21e 1668strxfrm(src)
1669 SV * src
85e6fe83 1670 CODE:
a0d0e21e 1671 {
1672 STRLEN srclen;
1673 STRLEN dstlen;
1674 char *p = SvPV(src,srclen);
1675 srclen++;
37cda61e 1676 ST(0) = sv_2mortal(NEWSV(800,srclen*4+1));
a0d0e21e 1677 dstlen = strxfrm(SvPVX(ST(0)), p, (size_t)srclen);
1678 if (dstlen > srclen) {
1679 dstlen++;
1680 SvGROW(ST(0), dstlen);
1681 strxfrm(SvPVX(ST(0)), p, (size_t)dstlen);
1682 dstlen--;
1683 }
b162af07 1684 SvCUR_set(ST(0), dstlen);
a0d0e21e 1685 SvPOK_only(ST(0));
1686 }
1687
1688SysRet
1689mkfifo(filename, mode)
1690 char * filename
1691 Mode_t mode
748a9306 1692 CODE:
1693 TAINT_PROPER("mkfifo");
1694 RETVAL = mkfifo(filename, mode);
1695 OUTPUT:
1696 RETVAL
a0d0e21e 1697
1698SysRet
1699tcdrain(fd)
1700 int fd
1701
1702
1703SysRet
1704tcflow(fd, action)
1705 int fd
1706 int action
1707
1708
1709SysRet
1710tcflush(fd, queue_selector)
1711 int fd
1712 int queue_selector
1713
1714SysRet
1715tcsendbreak(fd, duration)
1716 int fd
1717 int duration
1718
1719char *
1720asctime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = 0)
1721 int sec
1722 int min
1723 int hour
1724 int mday
1725 int mon
1726 int year
1727 int wday
1728 int yday
1729 int isdst
1730 CODE:
1731 {
1732 struct tm mytm;
7747499c 1733 init_tm(&mytm); /* XXX workaround - see init_tm() above */
a0d0e21e 1734 mytm.tm_sec = sec;
1735 mytm.tm_min = min;
1736 mytm.tm_hour = hour;
1737 mytm.tm_mday = mday;
1738 mytm.tm_mon = mon;
1739 mytm.tm_year = year;
1740 mytm.tm_wday = wday;
1741 mytm.tm_yday = yday;
1742 mytm.tm_isdst = isdst;
1743 RETVAL = asctime(&mytm);
1744 }
1745 OUTPUT:
1746 RETVAL
1747
1748long
1749clock()
1750
1751char *
1752ctime(time)
748a9306 1753 Time_t &time
8990e307 1754
37120919 1755void
1756times()
1757 PPCODE:
1758 struct tms tms;
1759 clock_t realtime;
1760 realtime = times( &tms );
924508f0 1761 EXTEND(SP,5);
9607fc9c 1762 PUSHs( sv_2mortal( newSViv( (IV) realtime ) ) );
1763 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_utime ) ) );
1764 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_stime ) ) );
1765 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cutime ) ) );
1766 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cstime ) ) );
37120919 1767
a0d0e21e 1768double
1769difftime(time1, time2)
1770 Time_t time1
1771 Time_t time2
1772
1773SysRetLong
1774mktime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = 0)
1775 int sec
1776 int min
1777 int hour
1778 int mday
1779 int mon
1780 int year
1781 int wday
1782 int yday
1783 int isdst
1784 CODE:
1785 {
1786 struct tm mytm;
7747499c 1787 init_tm(&mytm); /* XXX workaround - see init_tm() above */
a0d0e21e 1788 mytm.tm_sec = sec;
1789 mytm.tm_min = min;
1790 mytm.tm_hour = hour;
1791 mytm.tm_mday = mday;
1792 mytm.tm_mon = mon;
1793 mytm.tm_year = year;
1794 mytm.tm_wday = wday;
1795 mytm.tm_yday = yday;
1796 mytm.tm_isdst = isdst;
1797 RETVAL = mktime(&mytm);
1798 }
85e6fe83 1799 OUTPUT:
1800 RETVAL
a0d0e21e 1801
8063af02 1802#XXX: if $xsubpp::WantOptimize is always the default
1803# sv_setpv(TARG, ...) could be used rather than
1804# ST(0) = sv_2mortal(newSVpv(...))
1805void
e44f695e 1806strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1)
a0d0e21e 1807 char * fmt
1808 int sec
1809 int min
1810 int hour
1811 int mday
1812 int mon
1813 int year
1814 int wday
1815 int yday
1816 int isdst
1817 CODE:
1818 {
b3c85772 1819 char *buf = my_strftime(fmt, sec, min, hour, mday, mon, year, wday, yday, isdst);
2a74cb2d 1820 if (buf) {
1821 ST(0) = sv_2mortal(newSVpv(buf, 0));
bf8afc63 1822 Safefree(buf);
2a74cb2d 1823 }
a0d0e21e 1824 }
1825
1826void
1827tzset()
1828
1829void
1830tzname()
1831 PPCODE:
924508f0 1832 EXTEND(SP,2);
79cb57f6 1833 PUSHs(sv_2mortal(newSVpvn(tzname[0],strlen(tzname[0]))));
1834 PUSHs(sv_2mortal(newSVpvn(tzname[1],strlen(tzname[1]))));
a0d0e21e 1835
1836SysRet
1837access(filename, mode)
1838 char * filename
1839 Mode_t mode
1840
1841char *
1842ctermid(s = 0)
3ab23a19 1843 char * s = 0;
1844 CODE:
1845#ifdef HAS_CTERMID_R
1846 s = safemalloc((size_t) L_ctermid);
1847#endif
1848 RETVAL = ctermid(s);
1849 OUTPUT:
1850 RETVAL
d1fd7089 1851 CLEANUP:
3ab23a19 1852#ifdef HAS_CTERMID_R
d1fd7089 1853 Safefree(s);
3ab23a19 1854#endif
a0d0e21e 1855
1856char *
1857cuserid(s = 0)
1858 char * s = 0;
1859
1860SysRetLong
1861fpathconf(fd, name)
1862 int fd
1863 int name
1864
1865SysRetLong
1866pathconf(filename, name)
1867 char * filename
1868 int name
1869
1870SysRet
1871pause()
1872
a043a685 1873SysRet
1874setgid(gid)
1875 Gid_t gid
13ec70af 1876 CLEANUP:
e9df3e1a 1877#ifndef WIN32
13ec70af 1878 if (RETVAL >= 0) {
1879 PL_gid = getgid();
1880 PL_egid = getegid();
1881 }
e9df3e1a 1882#endif
a043a685 1883
1884SysRet
1885setuid(uid)
1886 Uid_t uid
13ec70af 1887 CLEANUP:
e9df3e1a 1888#ifndef WIN32
13ec70af 1889 if (RETVAL >= 0) {
1890 PL_uid = getuid();
1891 PL_euid = geteuid();
1892 }
e9df3e1a 1893#endif
a043a685 1894
a0d0e21e 1895SysRetLong
1896sysconf(name)
1897 int name
1898
1899char *
1900ttyname(fd)
1901 int fd
a043a685 1902
c6c619a9 1903void
b5846a0b 1904getcwd()
8f95b30d 1905 PPCODE:
1906 {
1907 dXSTARG;
89423764 1908 getcwd_sv(TARG);
8f95b30d 1909 XSprePUSH; PUSHTARG;
1910 }
1911
0d7021f5 1912SysRet
1913lchown(uid, gid, path)
1914 Uid_t uid
1915 Gid_t gid
1916 char * path
1917 CODE:
1918#ifdef HAS_LCHOWN
1919 /* yes, the order of arguments is different,
1920 * but consistent with CORE::chown() */
1921 RETVAL = lchown(path, uid, gid);
1922#else
1923 RETVAL = not_here("lchown");
1924#endif
1925 OUTPUT:
1926 RETVAL