Explicitly load PerlIO::encoding when testing it.
[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
b56fc9ec 735 unsigned int ccix
a0d0e21e 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
b56fc9ec 805 unsigned int ccix
a0d0e21e 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
516d25e8 1263 if (sig < 0) {
1264 croak("Negative signals are not allowed");
1265 }
1266
1d81eac9 1267 if (sig == 0 && SvPOK(ST(0))) {
aa07b2f6 1268 const char *s = SvPVX_const(ST(0));
1d81eac9 1269 int i = whichsig(s);
1270
1271 if (i < 0 && memEQ(s, "SIG", 3))
1272 i = whichsig(s + 3);
1273 if (i < 0) {
1274 if (ckWARN(WARN_SIGNAL))
1275 Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
1276 "No such signal: SIG%s", s);
1277 XSRETURN_UNDEF;
1278 }
1279 else
1280 sig = i;
1281 }
3609ea0d 1282#ifdef NSIG
1283 if (sig > NSIG) { /* NSIG - 1 is still okay. */
1284 Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
1285 "No such signal: %d", sig);
1286 XSRETURN_UNDEF;
1287 }
1288#endif
1d81eac9 1289 sigsvp = hv_fetch(GvHVn(siggv),
1290 PL_sig_name[sig],
1291 strlen(PL_sig_name[sig]),
1292 TRUE);
2304df62 1293
1dfe7606 1294 /* Check optaction and set action */
1295 if(SvTRUE(optaction)) {
1296 if(sv_isa(optaction, "POSIX::SigAction"))
1297 action = (HV*)SvRV(optaction);
1298 else
1299 croak("action is not of type POSIX::SigAction");
1300 }
1301 else {
1302 action=0;
1303 }
1304
1305 /* sigaction() is supposed to look atomic. In particular, any
1306 * signal handler invoked during a sigaction() call should
1307 * see either the old or the new disposition, and not something
1308 * in between. We use sigprocmask() to make it so.
1309 */
1310 sigfillset(&sset);
1311 RETVAL=sigprocmask(SIG_BLOCK, &sset, &osset);
1312 if(RETVAL == -1)
15c0d34a 1313 XSRETURN_UNDEF;
1dfe7606 1314 ENTER;
1315 /* Restore signal mask no matter how we exit this block. */
183bde56 1316 osset_sv = newSVpv((char *)(&osset), sizeof(sigset_t));
1317 SAVEFREESV( osset_sv );
40b7a5f5 1318 SAVEDESTRUCTOR_X(restore_sigmask, osset_sv);
1dfe7606 1319
1320 RETVAL=-1; /* In case both oldaction and action are 0. */
1321
1322 /* Remember old disposition if desired. */
2304df62 1323 if (oldaction) {
017a3ce5 1324 svp = hv_fetchs(oldaction, "HANDLER", TRUE);
1dfe7606 1325 if(!svp)
1326 croak("Can't supply an oldaction without a HANDLER");
1327 if(SvTRUE(*sigsvp)) { /* TBD: what if "0"? */
1328 sv_setsv(*svp, *sigsvp);
1329 }
1330 else {
1331 sv_setpv(*svp, "DEFAULT");
1332 }
1333 RETVAL = sigaction(sig, (struct sigaction *)0, & oact);
1334 if(RETVAL == -1)
15c0d34a 1335 XSRETURN_UNDEF;
1dfe7606 1336 /* Get back the mask. */
017a3ce5 1337 svp = hv_fetchs(oldaction, "MASK", TRUE);
1dfe7606 1338 if (sv_isa(*svp, "POSIX::SigSet")) {
1339 IV tmp = SvIV((SV*)SvRV(*svp));
1340 sigset = INT2PTR(sigset_t*, tmp);
1341 }
1342 else {
a02a5408 1343 Newx(sigset, 1, sigset_t);
1dfe7606 1344 sv_setptrobj(*svp, sigset, "POSIX::SigSet");
1345 }
1346 *sigset = oact.sa_mask;
1347
1348 /* Get back the flags. */
017a3ce5 1349 svp = hv_fetchs(oldaction, "FLAGS", TRUE);
1dfe7606 1350 sv_setiv(*svp, oact.sa_flags);
d36b6582 1351
1352 /* Get back whether the old handler used safe signals. */
017a3ce5 1353 svp = hv_fetchs(oldaction, "SAFE", TRUE);
e91e3b10 1354 sv_setiv(*svp,
1355 /* compare incompatible pointers by casting to integer */
1356 PTR2nat(oact.sa_handler) == PTR2nat(PL_csighandlerp));
2304df62 1357 }
1358
1359 if (action) {
d36b6582 1360 /* Safe signals use "csighandler", which vectors through the
1361 PL_sighandlerp pointer when it's safe to do so.
1362 (BTW, "csighandler" is very different from "sighandler".) */
017a3ce5 1363 svp = hv_fetchs(action, "SAFE", FALSE);
e91e3b10 1364 act.sa_handler =
1365 DPTR2FPTR(
87d46f97 1366 void (*)(int),
e91e3b10 1367 (*svp && SvTRUE(*svp))
1368 ? PL_csighandlerp : PL_sighandlerp
1369 );
d36b6582 1370
1371 /* Vector new Perl handler through %SIG.
1372 (The core signal handlers read %SIG to dispatch.) */
017a3ce5 1373 svp = hv_fetchs(action, "HANDLER", FALSE);
2304df62 1374 if (!svp)
1375 croak("Can't supply an action without a HANDLER");
1dfe7606 1376 sv_setsv(*sigsvp, *svp);
d36b6582 1377
1378 /* This call actually calls sigaction() with almost the
1379 right settings, including appropriate interpretation
1380 of DEFAULT and IGNORE. However, why are we doing
1381 this when we're about to do it again just below? XXX */
1382 mg_set(*sigsvp);
1383
1384 /* And here again we duplicate -- DEFAULT/IGNORE checking. */
1dfe7606 1385 if(SvPOK(*svp)) {
aa07b2f6 1386 const char *s=SvPVX_const(*svp);
1dfe7606 1387 if(strEQ(s,"IGNORE")) {
1388 act.sa_handler = SIG_IGN;
1389 }
1390 else if(strEQ(s,"DEFAULT")) {
1391 act.sa_handler = SIG_DFL;
1392 }
1dfe7606 1393 }
2304df62 1394
1395 /* Set up any desired mask. */
017a3ce5 1396 svp = hv_fetchs(action, "MASK", FALSE);
2304df62 1397 if (svp && sv_isa(*svp, "POSIX::SigSet")) {
ac634a9a 1398 IV tmp = SvIV((SV*)SvRV(*svp));
1dfe7606 1399 sigset = INT2PTR(sigset_t*, tmp);
2304df62 1400 act.sa_mask = *sigset;
1401 }
1402 else
85e6fe83 1403 sigemptyset(& act.sa_mask);
2304df62 1404
1405 /* Set up any desired flags. */
017a3ce5 1406 svp = hv_fetchs(action, "FLAGS", FALSE);
2304df62 1407 act.sa_flags = svp ? SvIV(*svp) : 0;
2304df62 1408
1dfe7606 1409 /* Don't worry about cleaning up *sigsvp if this fails,
1410 * because that means we tried to disposition a
1411 * nonblockable signal, in which case *sigsvp is
1412 * essentially meaningless anyway.
1413 */
6c418a22 1414 RETVAL = sigaction(sig, & act, (struct sigaction *)0);
a7aad5de 1415 if(RETVAL == -1)
1416 XSRETURN_UNDEF;
2304df62 1417 }
1dfe7606 1418
1419 LEAVE;
2304df62 1420 }
6dead956 1421#endif
2304df62 1422 OUTPUT:
1423 RETVAL
1424
1425SysRet
1426sigpending(sigset)
1427 POSIX::SigSet sigset
1428
1429SysRet
1430sigprocmask(how, sigset, oldsigset = 0)
1431 int how
b13bbac7 1432 POSIX::SigSet sigset = NO_INIT
33c27489 1433 POSIX::SigSet oldsigset = NO_INIT
1434INIT:
a3b811a7 1435 if (! SvOK(ST(1))) {
b13bbac7 1436 sigset = NULL;
a3b811a7 1437 } else if (sv_isa(ST(1), "POSIX::SigSet")) {
b13bbac7 1438 IV tmp = SvIV((SV*)SvRV(ST(1)));
1439 sigset = INT2PTR(POSIX__SigSet,tmp);
1440 } else {
1441 croak("sigset is not of type POSIX::SigSet");
33c27489 1442 }
b13bbac7 1443
194cfca0 1444 if (items < 3 || ! SvOK(ST(2))) {
b13bbac7 1445 oldsigset = NULL;
a3b811a7 1446 } else if (sv_isa(ST(2), "POSIX::SigSet")) {
33c27489 1447 IV tmp = SvIV((SV*)SvRV(ST(2)));
56431972 1448 oldsigset = INT2PTR(POSIX__SigSet,tmp);
b13bbac7 1449 } else {
1450 croak("oldsigset is not of type POSIX::SigSet");
33c27489 1451 }
2304df62 1452
1453SysRet
1454sigsuspend(signal_mask)
1455 POSIX::SigSet signal_mask
1456
2304df62 1457void
1458_exit(status)
1459 int status
8990e307 1460
85e6fe83 1461SysRet
8990e307 1462close(fd)
1463 int fd
1464
85e6fe83 1465SysRet
8990e307 1466dup(fd)
1467 int fd
1468
85e6fe83 1469SysRet
8990e307 1470dup2(fd1, fd2)
1471 int fd1
1472 int fd2
1473
4a9d6100 1474SV *
a0d0e21e 1475lseek(fd, offset, whence)
85e6fe83 1476 int fd
1477 Off_t offset
1478 int whence
4a9d6100 1479 CODE:
1480 Off_t pos = PerlLIO_lseek(fd, offset, whence);
1481 RETVAL = sizeof(Off_t) > sizeof(IV)
1482 ? newSVnv((NV)pos) : newSViv((IV)pos);
1483 OUTPUT:
1484 RETVAL
8990e307 1485
c5661c80 1486void
8990e307 1487nice(incr)
1488 int incr
15f0f28a 1489 PPCODE:
1490 errno = 0;
1491 if ((incr = nice(incr)) != -1 || errno == 0) {
1492 if (incr == 0)
1493 XPUSHs(sv_2mortal(newSVpvn("0 but true", 10)));
1494 else
1495 XPUSHs(sv_2mortal(newSViv(incr)));
1496 }
8990e307 1497
8063af02 1498void
8990e307 1499pipe()
85e6fe83 1500 PPCODE:
1501 int fds[2];
85e6fe83 1502 if (pipe(fds) != -1) {
924508f0 1503 EXTEND(SP,2);
85e6fe83 1504 PUSHs(sv_2mortal(newSViv(fds[0])));
1505 PUSHs(sv_2mortal(newSViv(fds[1])));
1506 }
8990e307 1507
85e6fe83 1508SysRet
a0d0e21e 1509read(fd, buffer, nbytes)
7747499c 1510 PREINIT:
1511 SV *sv_buffer = SvROK(ST(1)) ? SvRV(ST(1)) : ST(1);
1512 INPUT:
1513 int fd
1514 size_t nbytes
1515 char * buffer = sv_grow( sv_buffer, nbytes+1 );
a0d0e21e 1516 CLEANUP:
7747499c 1517 if (RETVAL >= 0) {
b162af07 1518 SvCUR_set(sv_buffer, RETVAL);
7747499c 1519 SvPOK_only(sv_buffer);
1520 *SvEND(sv_buffer) = '\0';
bbce6d69 1521 SvTAINTED_on(sv_buffer);
7747499c 1522 }
8990e307 1523
85e6fe83 1524SysRet
8990e307 1525setpgid(pid, pgid)
86200d5c 1526 pid_t pid
1527 pid_t pgid
8990e307 1528
86200d5c 1529pid_t
8990e307 1530setsid()
1531
86200d5c 1532pid_t
8990e307 1533tcgetpgrp(fd)
1534 int fd
1535
85e6fe83 1536SysRet
8990e307 1537tcsetpgrp(fd, pgrp_id)
1538 int fd
86200d5c 1539 pid_t pgrp_id
8990e307 1540
8063af02 1541void
8990e307 1542uname()
2304df62 1543 PPCODE:
a0d0e21e 1544#ifdef HAS_UNAME
85e6fe83 1545 struct utsname buf;
85e6fe83 1546 if (uname(&buf) >= 0) {
924508f0 1547 EXTEND(SP, 5);
85e6fe83 1548 PUSHs(sv_2mortal(newSVpv(buf.sysname, 0)));
1549 PUSHs(sv_2mortal(newSVpv(buf.nodename, 0)));
1550 PUSHs(sv_2mortal(newSVpv(buf.release, 0)));
1551 PUSHs(sv_2mortal(newSVpv(buf.version, 0)));
1552 PUSHs(sv_2mortal(newSVpv(buf.machine, 0)));
8990e307 1553 }
a0d0e21e 1554#else
1555 uname((char *) 0); /* A stub to call not_here(). */
1556#endif
8990e307 1557
85e6fe83 1558SysRet
a0d0e21e 1559write(fd, buffer, nbytes)
1560 int fd
1561 char * buffer
1562 size_t nbytes
1563
33f01dd1 1564SV *
1565tmpnam()
1566 PREINIT:
1567 STRLEN i;
1568 int len;
1569 CODE:
1570 RETVAL = newSVpvn("", 0);
1571 SvGROW(RETVAL, L_tmpnam);
1572 len = strlen(tmpnam(SvPV(RETVAL, i)));
1573 SvCUR_set(RETVAL, len);
1574 OUTPUT:
1575 RETVAL
a0d0e21e 1576
1577void
1578abort()
1579
1580int
1581mblen(s, n)
1582 char * s
1583 size_t n
1584
1585size_t
1586mbstowcs(s, pwcs, n)
1587 wchar_t * s
1588 char * pwcs
1589 size_t n
1590
1591int
1592mbtowc(pwc, s, n)
1593 wchar_t * pwc
1594 char * s
1595 size_t n
1596
1597int
1598wcstombs(s, pwcs, n)
1599 char * s
1600 wchar_t * pwcs
1601 size_t n
1602
1603int
1604wctomb(s, wchar)
1605 char * s
1606 wchar_t wchar
1607
1608int
1609strcoll(s1, s2)
1610 char * s1
1611 char * s2
1612
a89d8a78 1613void
1614strtod(str)
1615 char * str
1616 PREINIT:
1617 double num;
1618 char *unparsed;
1619 PPCODE:
36477c24 1620 SET_NUMERIC_LOCAL();
a89d8a78 1621 num = strtod(str, &unparsed);
1622 PUSHs(sv_2mortal(newSVnv(num)));
1623 if (GIMME == G_ARRAY) {
924508f0 1624 EXTEND(SP, 1);
a89d8a78 1625 if (unparsed)
1626 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1627 else
6b88bc9c 1628 PUSHs(&PL_sv_undef);
a89d8a78 1629 }
1630
1631void
1632strtol(str, base = 0)
1633 char * str
1634 int base
1635 PREINIT:
1636 long num;
1637 char *unparsed;
1638 PPCODE:
1639 num = strtol(str, &unparsed, base);
42718184 1640#if IVSIZE <= LONGSIZE
1641 if (num < IV_MIN || num > IV_MAX)
a89d8a78 1642 PUSHs(sv_2mortal(newSVnv((double)num)));
42718184 1643 else
1644#endif
1645 PUSHs(sv_2mortal(newSViv((IV)num)));
a89d8a78 1646 if (GIMME == G_ARRAY) {
924508f0 1647 EXTEND(SP, 1);
a89d8a78 1648 if (unparsed)
1649 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1650 else
6b88bc9c 1651 PUSHs(&PL_sv_undef);
a89d8a78 1652 }
1653
1654void
1655strtoul(str, base = 0)
1656 char * str
1657 int base
1658 PREINIT:
1659 unsigned long num;
1660 char *unparsed;
1661 PPCODE:
1662 num = strtoul(str, &unparsed, base);
84c133a0 1663#if IVSIZE <= LONGSIZE
1664 if (num > IV_MAX)
a89d8a78 1665 PUSHs(sv_2mortal(newSVnv((double)num)));
84c133a0 1666 else
1667#endif
1668 PUSHs(sv_2mortal(newSViv((IV)num)));
a89d8a78 1669 if (GIMME == G_ARRAY) {
924508f0 1670 EXTEND(SP, 1);
a89d8a78 1671 if (unparsed)
1672 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1673 else
6b88bc9c 1674 PUSHs(&PL_sv_undef);
a89d8a78 1675 }
1676
8063af02 1677void
a0d0e21e 1678strxfrm(src)
1679 SV * src
85e6fe83 1680 CODE:
a0d0e21e 1681 {
1682 STRLEN srclen;
1683 STRLEN dstlen;
1684 char *p = SvPV(src,srclen);
1685 srclen++;
561b68a9 1686 ST(0) = sv_2mortal(newSV(srclen*4+1));
a0d0e21e 1687 dstlen = strxfrm(SvPVX(ST(0)), p, (size_t)srclen);
1688 if (dstlen > srclen) {
1689 dstlen++;
1690 SvGROW(ST(0), dstlen);
1691 strxfrm(SvPVX(ST(0)), p, (size_t)dstlen);
1692 dstlen--;
1693 }
b162af07 1694 SvCUR_set(ST(0), dstlen);
a0d0e21e 1695 SvPOK_only(ST(0));
1696 }
1697
1698SysRet
1699mkfifo(filename, mode)
1700 char * filename
1701 Mode_t mode
748a9306 1702 CODE:
1703 TAINT_PROPER("mkfifo");
1704 RETVAL = mkfifo(filename, mode);
1705 OUTPUT:
1706 RETVAL
a0d0e21e 1707
1708SysRet
1709tcdrain(fd)
1710 int fd
1711
1712
1713SysRet
1714tcflow(fd, action)
1715 int fd
1716 int action
1717
1718
1719SysRet
1720tcflush(fd, queue_selector)
1721 int fd
1722 int queue_selector
1723
1724SysRet
1725tcsendbreak(fd, duration)
1726 int fd
1727 int duration
1728
1729char *
1730asctime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = 0)
1731 int sec
1732 int min
1733 int hour
1734 int mday
1735 int mon
1736 int year
1737 int wday
1738 int yday
1739 int isdst
1740 CODE:
1741 {
1742 struct tm mytm;
7747499c 1743 init_tm(&mytm); /* XXX workaround - see init_tm() above */
a0d0e21e 1744 mytm.tm_sec = sec;
1745 mytm.tm_min = min;
1746 mytm.tm_hour = hour;
1747 mytm.tm_mday = mday;
1748 mytm.tm_mon = mon;
1749 mytm.tm_year = year;
1750 mytm.tm_wday = wday;
1751 mytm.tm_yday = yday;
1752 mytm.tm_isdst = isdst;
1753 RETVAL = asctime(&mytm);
1754 }
1755 OUTPUT:
1756 RETVAL
1757
1758long
1759clock()
1760
1761char *
1762ctime(time)
748a9306 1763 Time_t &time
8990e307 1764
37120919 1765void
1766times()
1767 PPCODE:
1768 struct tms tms;
1769 clock_t realtime;
1770 realtime = times( &tms );
924508f0 1771 EXTEND(SP,5);
9607fc9c 1772 PUSHs( sv_2mortal( newSViv( (IV) realtime ) ) );
1773 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_utime ) ) );
1774 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_stime ) ) );
1775 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cutime ) ) );
1776 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cstime ) ) );
37120919 1777
a0d0e21e 1778double
1779difftime(time1, time2)
1780 Time_t time1
1781 Time_t time2
1782
1783SysRetLong
1784mktime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = 0)
1785 int sec
1786 int min
1787 int hour
1788 int mday
1789 int mon
1790 int year
1791 int wday
1792 int yday
1793 int isdst
1794 CODE:
1795 {
1796 struct tm mytm;
7747499c 1797 init_tm(&mytm); /* XXX workaround - see init_tm() above */
a0d0e21e 1798 mytm.tm_sec = sec;
1799 mytm.tm_min = min;
1800 mytm.tm_hour = hour;
1801 mytm.tm_mday = mday;
1802 mytm.tm_mon = mon;
1803 mytm.tm_year = year;
1804 mytm.tm_wday = wday;
1805 mytm.tm_yday = yday;
1806 mytm.tm_isdst = isdst;
aebaba0b 1807 RETVAL = (SysRetLong) mktime(&mytm);
a0d0e21e 1808 }
85e6fe83 1809 OUTPUT:
1810 RETVAL
a0d0e21e 1811
8063af02 1812#XXX: if $xsubpp::WantOptimize is always the default
1813# sv_setpv(TARG, ...) could be used rather than
1814# ST(0) = sv_2mortal(newSVpv(...))
1815void
e44f695e 1816strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1)
a0d0e21e 1817 char * fmt
1818 int sec
1819 int min
1820 int hour
1821 int mday
1822 int mon
1823 int year
1824 int wday
1825 int yday
1826 int isdst
1827 CODE:
1828 {
b3c85772 1829 char *buf = my_strftime(fmt, sec, min, hour, mday, mon, year, wday, yday, isdst);
2a74cb2d 1830 if (buf) {
1831 ST(0) = sv_2mortal(newSVpv(buf, 0));
bf8afc63 1832 Safefree(buf);
2a74cb2d 1833 }
a0d0e21e 1834 }
1835
1836void
1837tzset()
1838
1839void
1840tzname()
1841 PPCODE:
924508f0 1842 EXTEND(SP,2);
79cb57f6 1843 PUSHs(sv_2mortal(newSVpvn(tzname[0],strlen(tzname[0]))));
1844 PUSHs(sv_2mortal(newSVpvn(tzname[1],strlen(tzname[1]))));
a0d0e21e 1845
1846SysRet
1847access(filename, mode)
1848 char * filename
1849 Mode_t mode
1850
1851char *
1852ctermid(s = 0)
3ab23a19 1853 char * s = 0;
1854 CODE:
1855#ifdef HAS_CTERMID_R
1856 s = safemalloc((size_t) L_ctermid);
1857#endif
1858 RETVAL = ctermid(s);
1859 OUTPUT:
1860 RETVAL
d1fd7089 1861 CLEANUP:
3ab23a19 1862#ifdef HAS_CTERMID_R
d1fd7089 1863 Safefree(s);
3ab23a19 1864#endif
a0d0e21e 1865
1866char *
1867cuserid(s = 0)
1868 char * s = 0;
1869
1870SysRetLong
1871fpathconf(fd, name)
1872 int fd
1873 int name
1874
1875SysRetLong
1876pathconf(filename, name)
1877 char * filename
1878 int name
1879
1880SysRet
1881pause()
1882
a043a685 1883SysRet
1884setgid(gid)
1885 Gid_t gid
13ec70af 1886 CLEANUP:
e9df3e1a 1887#ifndef WIN32
13ec70af 1888 if (RETVAL >= 0) {
1889 PL_gid = getgid();
1890 PL_egid = getegid();
1891 }
e9df3e1a 1892#endif
a043a685 1893
1894SysRet
1895setuid(uid)
1896 Uid_t uid
13ec70af 1897 CLEANUP:
e9df3e1a 1898#ifndef WIN32
13ec70af 1899 if (RETVAL >= 0) {
1900 PL_uid = getuid();
1901 PL_euid = geteuid();
1902 }
e9df3e1a 1903#endif
a043a685 1904
a0d0e21e 1905SysRetLong
1906sysconf(name)
1907 int name
1908
1909char *
1910ttyname(fd)
1911 int fd
a043a685 1912
c6c619a9 1913void
b5846a0b 1914getcwd()
8f95b30d 1915 PPCODE:
1916 {
1917 dXSTARG;
89423764 1918 getcwd_sv(TARG);
8f95b30d 1919 XSprePUSH; PUSHTARG;
1920 }
1921
0d7021f5 1922SysRet
1923lchown(uid, gid, path)
1924 Uid_t uid
1925 Gid_t gid
1926 char * path
1927 CODE:
1928#ifdef HAS_LCHOWN
1929 /* yes, the order of arguments is different,
1930 * but consistent with CORE::chown() */
1931 RETVAL = lchown(path, uid, gid);
1932#else
1933 RETVAL = not_here("lchown");
1934#endif
1935 OUTPUT:
1936 RETVAL