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