This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Integrate:
[perl5.git] / ext / POSIX / POSIX.xs
CommitLineData
6e22d046
JH
1#define PERL_EXT_POSIX
2
2986a63f
JH
3#ifdef NETWARE
4 #define _POSIX_
4efcf9a2
SB
5 /*
6 * Ideally this should be somewhere down in the includes
7 * but putting it in other places is giving compiler errors.
8 * Also here I am unable to check for HAS_UNAME since it wouldn't have
9 * yet come into the file at this stage - sgp 18th Oct 2000
10 */
2986a63f
JH
11 #include <sys/utsname.h>
12#endif /* NETWARE */
13
c5be433b
GS
14#define PERL_NO_GET_CONTEXT
15
463ee0b2 16#include "EXTERN.h"
760ac839 17#define PERLIO_NOT_STDIO 1
463ee0b2
LW
18#include "perl.h"
19#include "XSUB.h"
acfe0abc 20#if defined(PERL_IMPLICIT_SYS)
873ef191
GS
21# undef signal
22# undef open
cd661bb6 23# undef setmode
35ff7856 24# define open PerlLIO_open3
873ef191 25#endif
2304df62 26#include <ctype.h>
a0d0e21e 27#ifdef I_DIRENT /* XXX maybe better to just rely on perl.h? */
2304df62 28#include <dirent.h>
a0d0e21e 29#endif
2304df62 30#include <errno.h>
2304df62
AD
31#ifdef I_FLOAT
32#include <float.h>
33#endif
a0d0e21e 34#ifdef I_LIMITS
2304df62 35#include <limits.h>
a0d0e21e 36#endif
2304df62
AD
37#include <locale.h>
38#include <math.h>
85e6fe83 39#ifdef I_PWD
2304df62 40#include <pwd.h>
85e6fe83 41#endif
2304df62
AD
42#include <setjmp.h>
43#include <signal.h>
2304df62 44#include <stdarg.h>
17c3b450 45
2304df62
AD
46#ifdef I_STDDEF
47#include <stddef.h>
48#endif
6990d991 49
b5846a0b
BS
50#ifdef I_UNISTD
51#include <unistd.h>
52#endif
53
a0d0e21e
LW
54/* XXX This comment is just to make I_TERMIO and I_SGTTY visible to
55 metaconfig for future extension writers. We don't use them in POSIX.
56 (This is really sneaky :-) --AD
57*/
58#if defined(I_TERMIOS)
59#include <termios.h>
60#endif
a0d0e21e 61#ifdef I_STDLIB
2304df62 62#include <stdlib.h>
a0d0e21e 63#endif
89e79dea 64#ifndef __ultrix__
2304df62 65#include <string.h>
89e79dea 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
GS
73#ifdef MACOS_TRADITIONAL
74#undef fdopen
75#endif
71be2cbc 76#include <fcntl.h>
77
e2465f50 78#ifdef HAS_TZNAME
16c773f9 79# if !defined(WIN32) && !defined(__CYGWIN__) && !defined(NETWARE) && !defined(__UWIN__)
e2465f50
JH
80extern char *tzname[];
81# endif
82#else
16c773f9 83#if !defined(WIN32) && !defined(__UWIN__) || (defined(__MINGW32__) && !defined(tzname))
e2465f50
JH
84char *tzname[] = { "" , "" };
85#endif
cb2479a8
JH
86#endif
87
24c2fff4
NC
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
95# else
96# define PERL_UNUSED_DECL
97# endif
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
DS
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
EF
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
GS
166# ifdef __BORLANDC__
167# define tzname _tzname
168# endif
169# ifdef _MSC_VER
170# define mode_t short
171# endif
62520c91
GS
172# ifdef __MINGW32__
173# define mode_t short
f6c6487a
GS
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
GS
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
JH
191# undef setuid
192# undef setgid
2986a63f
JH
193# define setuid(a) not_here("setuid")
194# define setgid(a) not_here("setgid")
195#endif /* NETWARE */
6dead956 196#else
6990d991
JH
197
198# ifndef HAS_MKFIFO
bf4acbe4 199# if defined(OS2) || defined(MACOS_TRADITIONAL)
d6a255e6
IZ
200# define mkfifo(a,b) not_here("mkfifo")
201# else /* !( defined OS2 ) */
202# ifndef mkfifo
203# define mkfifo(path, mode) (mknod((path), (mode) | S_IFIFO, 0))
204# endif
6990d991
JH
205# endif
206# endif /* !HAS_MKFIFO */
207
bf4acbe4 208# ifdef MACOS_TRADITIONAL
bf4acbe4
GS
209# define ttyname(a) (char*)not_here("ttyname")
210# define tzset() not_here("tzset")
211# else
212# include <grp.h>
213# include <sys/times.h>
214# ifdef HAS_UNAME
215# include <sys/utsname.h>
216# endif
217# include <sys/wait.h>
6c418a22 218# endif
6c418a22 219# ifdef I_UTIME
220# include <utime.h>
221# endif
2986a63f 222#endif /* WIN32 || NETWARE */
6dead956 223#endif /* __VMS */
2304df62
AD
224
225typedef int SysRet;
a0d0e21e 226typedef long SysRetLong;
2304df62
AD
227typedef sigset_t* POSIX__SigSet;
228typedef HV* POSIX__SigAction;
a0d0e21e
LW
229#ifdef I_TERMIOS
230typedef struct termios* POSIX__Termios;
231#else /* Define termios types to int, and call not_here for the functions.*/
232#define POSIX__Termios int
233#define speed_t int
234#define tcflag_t int
235#define cc_t int
236#define cfgetispeed(x) not_here("cfgetispeed")
237#define cfgetospeed(x) not_here("cfgetospeed")
238#define tcdrain(x) not_here("tcdrain")
239#define tcflush(x,y) not_here("tcflush")
240#define tcsendbreak(x,y) not_here("tcsendbreak")
241#define cfsetispeed(x,y) not_here("cfsetispeed")
242#define cfsetospeed(x,y) not_here("cfsetospeed")
243#define ctermid(x) (char *) not_here("ctermid")
244#define tcflow(x,y) not_here("tcflow")
245#define tcgetattr(x,y) not_here("tcgetattr")
246#define tcsetattr(x,y,z) not_here("tcsetattr")
247#endif
248
249/* Possibly needed prototypes */
20ce7b12 250char *cuserid (char *);
6e22d046 251#ifndef WIN32
20ce7b12
GS
252double strtod (const char *, char **);
253long strtol (const char *, char **, int);
254unsigned long strtoul (const char *, char **, int);
6e22d046 255#endif
a0d0e21e
LW
256
257#ifndef HAS_CUSERID
258#define cuserid(a) (char *) not_here("cuserid")
259#endif
260#ifndef HAS_DIFFTIME
261#ifndef difftime
262#define difftime(a,b) not_here("difftime")
263#endif
264#endif
265#ifndef HAS_FPATHCONF
266#define fpathconf(f,n) (SysRetLong) not_here("fpathconf")
267#endif
268#ifndef HAS_MKTIME
269#define mktime(a) not_here("mktime")
8990e307
LW
270#endif
271#ifndef HAS_NICE
272#define nice(a) not_here("nice")
273#endif
a0d0e21e
LW
274#ifndef HAS_PATHCONF
275#define pathconf(f,n) (SysRetLong) not_here("pathconf")
276#endif
277#ifndef HAS_SYSCONF
278#define sysconf(n) (SysRetLong) not_here("sysconf")
279#endif
8990e307
LW
280#ifndef HAS_READLINK
281#define readlink(a,b,c) not_here("readlink")
282#endif
283#ifndef HAS_SETPGID
284#define setpgid(a,b) not_here("setpgid")
285#endif
8990e307
LW
286#ifndef HAS_SETSID
287#define setsid() not_here("setsid")
288#endif
a0d0e21e
LW
289#ifndef HAS_STRCOLL
290#define strcoll(s1,s2) not_here("strcoll")
291#endif
a89d8a78
DH
292#ifndef HAS_STRTOD
293#define strtod(s1,s2) not_here("strtod")
294#endif
295#ifndef HAS_STRTOL
296#define strtol(s1,s2,b) not_here("strtol")
297#endif
298#ifndef HAS_STRTOUL
299#define strtoul(s1,s2,b) not_here("strtoul")
300#endif
a0d0e21e
LW
301#ifndef HAS_STRXFRM
302#define strxfrm(s1,s2,n) not_here("strxfrm")
8990e307
LW
303#endif
304#ifndef HAS_TCGETPGRP
305#define tcgetpgrp(a) not_here("tcgetpgrp")
306#endif
307#ifndef HAS_TCSETPGRP
308#define tcsetpgrp(a,b) not_here("tcsetpgrp")
309#endif
310#ifndef HAS_TIMES
2986a63f 311#ifndef NETWARE
8990e307 312#define times(a) not_here("times")
2986a63f 313#endif /* NETWARE */
8990e307
LW
314#endif
315#ifndef HAS_UNAME
316#define uname(a) not_here("uname")
317#endif
318#ifndef HAS_WAITPID
319#define waitpid(a,b,c) not_here("waitpid")
320#endif
321
a0d0e21e
LW
322#ifndef HAS_MBLEN
323#ifndef mblen
324#define mblen(a,b) not_here("mblen")
325#endif
326#endif
327#ifndef HAS_MBSTOWCS
328#define mbstowcs(s, pwcs, n) not_here("mbstowcs")
329#endif
330#ifndef HAS_MBTOWC
331#define mbtowc(pwc, s, n) not_here("mbtowc")
332#endif
333#ifndef HAS_WCSTOMBS
334#define wcstombs(s, pwcs, n) not_here("wcstombs")
335#endif
336#ifndef HAS_WCTOMB
337#define wctomb(s, wchar) not_here("wcstombs")
338#endif
339#if !defined(HAS_MBLEN) && !defined(HAS_MBSTOWCS) && !defined(HAS_MBTOWC) && !defined(HAS_WCSTOMBS) && !defined(HAS_WCTOMB)
340/* If we don't have these functions, then we wouldn't have gotten a typedef
341 for wchar_t, the wide character type. Defining wchar_t allows the
342 functions referencing it to compile. Its actual type is then meaningless,
343 since without the above functions, all sections using it end up calling
344 not_here() and croak. --Kaveh Ghazi (ghazi@noc.rutgers.edu) 9/18/94. */
345#ifndef wchar_t
346#define wchar_t char
347#endif
348#endif
349
350#ifndef HAS_LOCALECONV
351#define localeconv() not_here("localeconv")
352#endif
353
172ea7c8 354#ifdef HAS_LONG_DOUBLE
53796371 355# if LONG_DOUBLESIZE > NVSIZE
172ea7c8
JH
356# undef HAS_LONG_DOUBLE /* XXX until we figure out how to use them */
357# endif
358#endif
359
360#ifndef HAS_LONG_DOUBLE
361#ifdef LDBL_MAX
362#undef LDBL_MAX
363#endif
364#ifdef LDBL_MIN
365#undef LDBL_MIN
366#endif
367#ifdef LDBL_EPSILON
368#undef LDBL_EPSILON
369#endif
370#endif
371
ec193bec
JH
372/* Background: in most systems the low byte of the wait status
373 * is the signal (the lowest 7 bits) and the coredump flag is
374 * the eight bit, and the second lowest byte is the exit status.
375 * BeOS bucks the trend and has the bytes in different order.
376 * See beos/beos.c for how the reality is bent even in BeOS
377 * to follow the traditional. However, to make the POSIX
378 * wait W*() macros to work in BeOS, we need to unbend the
379 * reality back in place. --jhi */
380#ifdef __BEOS__
381# define WMUNGE(x) (((x) & 0xFF00) >> 8 | ((x) & 0x00FF) << 8)
382#else
383# define WMUNGE(x) (x)
384#endif
385
8990e307 386static int
f0f333f4 387not_here(char *s)
8990e307
LW
388{
389 croak("POSIX::%s not implemented on this architecture", s);
390 return -1;
391}
463ee0b2 392
1cb0fb50 393#include "const-c.inc"
a290f238
NC
394
395/* These were implemented in the old "constant" subroutine. They are actually
396 macros that take an integer argument and return an integer result. */
397static int
398int_macro_int (const char *name, STRLEN len, IV *arg_result) {
399 /* Initially switch on the length of the name. */
400 /* This code has been edited from a "constant" function generated by:
401
402use ExtUtils::Constant qw (constant_types C_constant XS_constant);
403
404my $types = {map {($_, 1)} qw(IV)};
405my @names = (qw(S_ISBLK S_ISCHR S_ISDIR S_ISFIFO S_ISREG WEXITSTATUS WIFEXITED
406 WIFSIGNALED WIFSTOPPED WSTOPSIG WTERMSIG));
407
408print constant_types(); # macro defs
409foreach (C_constant ("POSIX", 'int_macro_int', 'IV', $types, undef, 5, @names) ) {
410 print $_, "\n"; # C constant subs
411}
412print "#### XS Section:\n";
413print XS_constant ("POSIX", $types);
414__END__
415 */
416
417 switch (len) {
418 case 7:
419 /* Names all of length 7. */
420 /* S_ISBLK S_ISCHR S_ISDIR S_ISREG */
421 /* Offset 5 gives the best switch position. */
422 switch (name[5]) {
423 case 'E':
424 if (memEQ(name, "S_ISREG", 7)) {
425 /* ^ */
426#ifdef S_ISREG
427 *arg_result = S_ISREG(*arg_result);
428 return PERL_constant_ISIV;
2304df62 429#else
a290f238 430 return PERL_constant_NOTDEF;
2304df62 431#endif
a290f238
NC
432 }
433 break;
434 case 'H':
435 if (memEQ(name, "S_ISCHR", 7)) {
436 /* ^ */
437#ifdef S_ISCHR
438 *arg_result = S_ISCHR(*arg_result);
439 return PERL_constant_ISIV;
2304df62 440#else
a290f238 441 return PERL_constant_NOTDEF;
2304df62 442#endif
a290f238
NC
443 }
444 break;
445 case 'I':
446 if (memEQ(name, "S_ISDIR", 7)) {
447 /* ^ */
448#ifdef S_ISDIR
449 *arg_result = S_ISDIR(*arg_result);
450 return PERL_constant_ISIV;
2304df62 451#else
a290f238 452 return PERL_constant_NOTDEF;
2304df62 453#endif
a290f238
NC
454 }
455 break;
456 case 'L':
457 if (memEQ(name, "S_ISBLK", 7)) {
458 /* ^ */
459#ifdef S_ISBLK
460 *arg_result = S_ISBLK(*arg_result);
461 return PERL_constant_ISIV;
2304df62 462#else
a290f238 463 return PERL_constant_NOTDEF;
2304df62 464#endif
a290f238
NC
465 }
466 break;
467 }
468 break;
469 case 8:
470 /* Names all of length 8. */
471 /* S_ISFIFO WSTOPSIG WTERMSIG */
472 /* Offset 3 gives the best switch position. */
473 switch (name[3]) {
474 case 'O':
475 if (memEQ(name, "WSTOPSIG", 8)) {
476 /* ^ */
477#ifdef WSTOPSIG
bfbc3223
JH
478 int i = *arg_result;
479 *arg_result = WSTOPSIG(WMUNGE(i));
a290f238 480 return PERL_constant_ISIV;
2304df62 481#else
a290f238 482 return PERL_constant_NOTDEF;
2304df62 483#endif
a290f238
NC
484 }
485 break;
486 case 'R':
487 if (memEQ(name, "WTERMSIG", 8)) {
488 /* ^ */
489#ifdef WTERMSIG
bfbc3223
JH
490 int i = *arg_result;
491 *arg_result = WTERMSIG(WMUNGE(i));
a290f238 492 return PERL_constant_ISIV;
2304df62 493#else
a290f238 494 return PERL_constant_NOTDEF;
2304df62 495#endif
a290f238
NC
496 }
497 break;
498 case 'S':
499 if (memEQ(name, "S_ISFIFO", 8)) {
500 /* ^ */
501#ifdef S_ISFIFO
502 *arg_result = S_ISFIFO(*arg_result);
503 return PERL_constant_ISIV;
2304df62 504#else
a290f238 505 return PERL_constant_NOTDEF;
2304df62 506#endif
a290f238
NC
507 }
508 break;
509 }
510 break;
511 case 9:
512 if (memEQ(name, "WIFEXITED", 9)) {
513#ifdef WIFEXITED
bfbc3223
JH
514 int i = *arg_result;
515 *arg_result = WIFEXITED(WMUNGE(i));
a290f238 516 return PERL_constant_ISIV;
2304df62 517#else
a290f238 518 return PERL_constant_NOTDEF;
2304df62 519#endif
a290f238
NC
520 }
521 break;
522 case 10:
523 if (memEQ(name, "WIFSTOPPED", 10)) {
524#ifdef WIFSTOPPED
bfbc3223
JH
525 int i = *arg_result;
526 *arg_result = WIFSTOPPED(WMUNGE(i));
a290f238 527 return PERL_constant_ISIV;
2304df62 528#else
a290f238 529 return PERL_constant_NOTDEF;
2304df62 530#endif
a290f238
NC
531 }
532 break;
533 case 11:
534 /* Names all of length 11. */
535 /* WEXITSTATUS WIFSIGNALED */
536 /* Offset 1 gives the best switch position. */
537 switch (name[1]) {
538 case 'E':
539 if (memEQ(name, "WEXITSTATUS", 11)) {
540 /* ^ */
541#ifdef WEXITSTATUS
bfbc3223
JH
542 int i = *arg_result;
543 *arg_result = WEXITSTATUS(WMUNGE(i));
a290f238 544 return PERL_constant_ISIV;
2304df62 545#else
a290f238 546 return PERL_constant_NOTDEF;
2304df62 547#endif
a290f238
NC
548 }
549 break;
550 case 'I':
551 if (memEQ(name, "WIFSIGNALED", 11)) {
552 /* ^ */
553#ifdef WIFSIGNALED
bfbc3223
JH
554 int i = *arg_result;
555 *arg_result = WIFSIGNALED(WMUNGE(i));
a290f238 556 return PERL_constant_ISIV;
2304df62 557#else
a290f238 558 return PERL_constant_NOTDEF;
2304df62 559#endif
a290f238
NC
560 }
561 break;
562 }
563 break;
564 }
565 return PERL_constant_NOTFOUND;
566}
567
1dfe7606 568static void
40b7a5f5 569restore_sigmask(pTHX_ SV *osset_sv)
1dfe7606 570{
7feb700b
JH
571 /* Fortunately, restoring the signal mask can't fail, because
572 * there's nothing we can do about it if it does -- we're not
573 * supposed to return -1 from sigaction unless the disposition
574 * was unaffected.
575 */
7feb700b
JH
576 sigset_t *ossetp = (sigset_t *) SvPV_nolen( osset_sv );
577 (void)sigprocmask(SIG_SETMASK, ossetp, (sigset_t *)0);
1dfe7606
AJ
578}
579
2304df62
AD
580MODULE = SigSet PACKAGE = POSIX::SigSet PREFIX = sig
581
582POSIX::SigSet
583new(packname = "POSIX::SigSet", ...)
584 char * packname
585 CODE:
586 {
587 int i;
01667c76 588 New(0, RETVAL, 1, sigset_t);
2304df62 589 sigemptyset(RETVAL);
a0d0e21e 590 for (i = 1; i < items; i++)
2304df62
AD
591 sigaddset(RETVAL, SvIV(ST(i)));
592 }
593 OUTPUT:
594 RETVAL
463ee0b2 595
8990e307 596void
2304df62
AD
597DESTROY(sigset)
598 POSIX::SigSet sigset
599 CODE:
01667c76 600 Safefree(sigset);
2304df62
AD
601
602SysRet
603sigaddset(sigset, sig)
604 POSIX::SigSet sigset
605 int sig
606
607SysRet
608sigdelset(sigset, sig)
609 POSIX::SigSet sigset
610 int sig
611
612SysRet
613sigemptyset(sigset)
614 POSIX::SigSet sigset
615
616SysRet
617sigfillset(sigset)
618 POSIX::SigSet sigset
619
620int
621sigismember(sigset, sig)
622 POSIX::SigSet sigset
623 int sig
624
625
a0d0e21e
LW
626MODULE = Termios PACKAGE = POSIX::Termios PREFIX = cf
627
628POSIX::Termios
629new(packname = "POSIX::Termios", ...)
630 char * packname
631 CODE:
632 {
633#ifdef I_TERMIOS
01667c76 634 New(0, RETVAL, 1, struct termios);
a0d0e21e
LW
635#else
636 not_here("termios");
640cc986 637 RETVAL = 0;
a0d0e21e
LW
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
LW
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
HM
687 not_here("getiflag");
688 RETVAL = 0;
a0d0e21e
LW
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
HM
700 not_here("getoflag");
701 RETVAL = 0;
a0d0e21e
LW
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
HM
713 not_here("getcflag");
714 RETVAL = 0;
a0d0e21e
LW
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
HM
726 not_here("getlflag");
727 RETVAL = 0;
a0d0e21e
LW
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
HM
742 not_here("getcc");
743 RETVAL = 0;
a0d0e21e
LW
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
LW
817MODULE = POSIX PACKAGE = POSIX
818
1cb0fb50 819INCLUDE: const-xs.inc
a290f238
NC
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
AD
862
863int
864isalnum(charstring)
28418ee0
TS
865 SV * charstring
866 PREINIT:
867 STRLEN len;
2304df62 868 CODE:
28418ee0
TS
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
AD
872 if (!isalnum(*s))
873 RETVAL = 0;
874 OUTPUT:
875 RETVAL
876
877int
878isalpha(charstring)
28418ee0
TS
879 SV * charstring
880 PREINIT:
881 STRLEN len;
2304df62 882 CODE:
28418ee0
TS
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
AD
886 if (!isalpha(*s))
887 RETVAL = 0;
888 OUTPUT:
889 RETVAL
890
891int
892iscntrl(charstring)
28418ee0
TS
893 SV * charstring
894 PREINIT:
895 STRLEN len;
2304df62 896 CODE:
28418ee0
TS
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
AD
900 if (!iscntrl(*s))
901 RETVAL = 0;
902 OUTPUT:
903 RETVAL
904
905int
906isdigit(charstring)
28418ee0
TS
907 SV * charstring
908 PREINIT:
909 STRLEN len;
2304df62 910 CODE:
28418ee0
TS
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
AD
914 if (!isdigit(*s))
915 RETVAL = 0;
916 OUTPUT:
917 RETVAL
918
919int
920isgraph(charstring)
28418ee0
TS
921 SV * charstring
922 PREINIT:
923 STRLEN len;
2304df62 924 CODE:
28418ee0
TS
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
AD
928 if (!isgraph(*s))
929 RETVAL = 0;
930 OUTPUT:
931 RETVAL
932
933int
934islower(charstring)
28418ee0
TS
935 SV * charstring
936 PREINIT:
937 STRLEN len;
2304df62 938 CODE:
28418ee0
TS
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
AD
942 if (!islower(*s))
943 RETVAL = 0;
944 OUTPUT:
945 RETVAL
946
947int
948isprint(charstring)
28418ee0
TS
949 SV * charstring
950 PREINIT:
951 STRLEN len;
2304df62 952 CODE:
28418ee0
TS
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
AD
956 if (!isprint(*s))
957 RETVAL = 0;
958 OUTPUT:
959 RETVAL
960
961int
962ispunct(charstring)
28418ee0
TS
963 SV * charstring
964 PREINIT:
965 STRLEN len;
2304df62 966 CODE:
28418ee0
TS
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
AD
970 if (!ispunct(*s))
971 RETVAL = 0;
972 OUTPUT:
973 RETVAL
974
975int
976isspace(charstring)
28418ee0
TS
977 SV * charstring
978 PREINIT:
979 STRLEN len;
2304df62 980 CODE:
28418ee0
TS
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
AD
984 if (!isspace(*s))
985 RETVAL = 0;
986 OUTPUT:
987 RETVAL
8990e307
LW
988
989int
2304df62 990isupper(charstring)
28418ee0
TS
991 SV * charstring
992 PREINIT:
993 STRLEN len;
2304df62 994 CODE:
28418ee0
TS
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
AD
998 if (!isupper(*s))
999 RETVAL = 0;
1000 OUTPUT:
1001 RETVAL
8990e307
LW
1002
1003int
2304df62 1004isxdigit(charstring)
28418ee0
TS
1005 SV * charstring
1006 PREINIT:
1007 STRLEN len;
2304df62 1008 CODE:
28418ee0
TS
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
AD
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
LW
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
AD
1029
1030HV *
1031localeconv()
1032 CODE:
a0d0e21e 1033#ifdef HAS_LOCALECONV
2304df62
AD
1034 struct lconv *lcbuf;
1035 RETVAL = newHV();
2ef4a045 1036 sv_2mortal((SV*)RETVAL);
8063af02 1037 if ((lcbuf = localeconv())) {
2304df62
AD
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
AD
1046 if (lcbuf->grouping && *lcbuf->grouping)
1047 hv_store(RETVAL, "grouping", 8,
1048 newSVpv(lcbuf->grouping, 0), 0);
28e8609d 1049#endif
2304df62
AD
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
AD
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);
39e571d4 1063#endif
28e8609d 1064#ifndef NO_LOCALECONV_MON_GROUPING
2304df62
AD
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
AD
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
LW
1101#else
1102 localeconv(); /* A stub to call not_here(). */
1103#endif
2304df62
AD
1104 OUTPUT:
1105 RETVAL
1106
1107char *
c28ee57b 1108setlocale(category, locale = 0)
2304df62
AD
1109 int category
1110 char * locale
c28ee57b
JH
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
JH
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
A
1196 NV x
1197 NV y
2304df62
AD
1198
1199void
1200frexp(x)
e1ca407b 1201 NV x
2304df62
AD
1202 PPCODE:
1203 int expvar;
2304df62
AD
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
AD
1211 int exp
1212
e1ca407b 1213NV
2304df62 1214log10(x)
e1ca407b 1215 NV x
2304df62
AD
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
AD
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
AD
1237
1238SysRet
1dfe7606 1239sigaction(sig, optaction, oldaction = 0)
2304df62 1240 int sig
1dfe7606 1241 SV * optaction
2304df62
AD
1242 POSIX::SigAction oldaction
1243 CODE:
2986a63f 1244#if defined(WIN32) || defined(NETWARE)
6dead956
GS
1245 RETVAL = not_here("sigaction");
1246#else
2304df62
AD
1247# This code is really grody because we're trying to make the signal
1248# interface look beautiful, which is hard.
1249
2304df62 1250 {
1dfe7606 1251 POSIX__SigAction action;
f4c556ac 1252 GV *siggv = gv_fetchpv("SIG", TRUE, SVt_PVHV);
2304df62
AD
1253 struct sigaction act;
1254 struct sigaction oact;
1dfe7606 1255 sigset_t sset;
183bde56 1256 SV *osset_sv;
27c1a449 1257 sigset_t osset;
2304df62
AD
1258 POSIX__SigSet sigset;
1259 SV** svp;
9b8ea7f3
JH
1260 SV** sigsvp;
1261 if (sig == 0 && SvPOK(ST(0))) {
fdac8c4b 1262 const char *s = SvPVX_const(ST(0));
9b8ea7f3
JH
1263 int i = whichsig(s);
1264
1265 if (i < 0 && memEQ(s, "SIG", 3))
1266 i = whichsig(s + 3);
1267 if (i < 0) {
1268 if (ckWARN(WARN_SIGNAL))
1269 Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
1270 "No such signal: SIG%s", s);
1271 XSRETURN_UNDEF;
1272 }
1273 else
1274 sig = i;
1275 }
1276 sigsvp = hv_fetch(GvHVn(siggv),
1277 PL_sig_name[sig],
1278 strlen(PL_sig_name[sig]),
1279 TRUE);
2304df62 1280
1dfe7606
AJ
1281 /* Check optaction and set action */
1282 if(SvTRUE(optaction)) {
1283 if(sv_isa(optaction, "POSIX::SigAction"))
1284 action = (HV*)SvRV(optaction);
1285 else
1286 croak("action is not of type POSIX::SigAction");
1287 }
1288 else {
1289 action=0;
1290 }
1291
1292 /* sigaction() is supposed to look atomic. In particular, any
1293 * signal handler invoked during a sigaction() call should
1294 * see either the old or the new disposition, and not something
1295 * in between. We use sigprocmask() to make it so.
1296 */
1297 sigfillset(&sset);
1298 RETVAL=sigprocmask(SIG_BLOCK, &sset, &osset);
1299 if(RETVAL == -1)
15c0d34a 1300 XSRETURN_UNDEF;
1dfe7606
AJ
1301 ENTER;
1302 /* Restore signal mask no matter how we exit this block. */
183bde56
NA
1303 osset_sv = newSVpv((char *)(&osset), sizeof(sigset_t));
1304 SAVEFREESV( osset_sv );
40b7a5f5 1305 SAVEDESTRUCTOR_X(restore_sigmask, osset_sv);
1dfe7606
AJ
1306
1307 RETVAL=-1; /* In case both oldaction and action are 0. */
1308
1309 /* Remember old disposition if desired. */
2304df62 1310 if (oldaction) {
2304df62 1311 svp = hv_fetch(oldaction, "HANDLER", 7, TRUE);
1dfe7606
AJ
1312 if(!svp)
1313 croak("Can't supply an oldaction without a HANDLER");
1314 if(SvTRUE(*sigsvp)) { /* TBD: what if "0"? */
1315 sv_setsv(*svp, *sigsvp);
1316 }
1317 else {
1318 sv_setpv(*svp, "DEFAULT");
1319 }
1320 RETVAL = sigaction(sig, (struct sigaction *)0, & oact);
1321 if(RETVAL == -1)
15c0d34a 1322 XSRETURN_UNDEF;
1dfe7606
AJ
1323 /* Get back the mask. */
1324 svp = hv_fetch(oldaction, "MASK", 4, TRUE);
1325 if (sv_isa(*svp, "POSIX::SigSet")) {
1326 IV tmp = SvIV((SV*)SvRV(*svp));
1327 sigset = INT2PTR(sigset_t*, tmp);
1328 }
1329 else {
1330 New(0, sigset, 1, sigset_t);
1331 sv_setptrobj(*svp, sigset, "POSIX::SigSet");
1332 }
1333 *sigset = oact.sa_mask;
1334
1335 /* Get back the flags. */
1336 svp = hv_fetch(oldaction, "FLAGS", 5, TRUE);
1337 sv_setiv(*svp, oact.sa_flags);
676a8eb5
JH
1338
1339 /* Get back whether the old handler used safe signals. */
1340 svp = hv_fetch(oldaction, "SAFE", 4, TRUE);
71b97453 1341 sv_setiv(*svp, oact.sa_handler == PL_csighandlerp);
2304df62
AD
1342 }
1343
1344 if (action) {
676a8eb5
JH
1345 /* Safe signals use "csighandler", which vectors through the
1346 PL_sighandlerp pointer when it's safe to do so.
1347 (BTW, "csighandler" is very different from "sighandler".) */
1348 svp = hv_fetch(action, "SAFE", 4, FALSE);
1349 act.sa_handler = (*svp && SvTRUE(*svp))
bb25ec9b 1350 ? PL_csighandlerp : PL_sighandlerp;
676a8eb5
JH
1351
1352 /* Vector new Perl handler through %SIG.
1353 (The core signal handlers read %SIG to dispatch.) */
2304df62
AD
1354 svp = hv_fetch(action, "HANDLER", 7, FALSE);
1355 if (!svp)
1356 croak("Can't supply an action without a HANDLER");
1dfe7606 1357 sv_setsv(*sigsvp, *svp);
676a8eb5
JH
1358
1359 /* This call actually calls sigaction() with almost the
1360 right settings, including appropriate interpretation
1361 of DEFAULT and IGNORE. However, why are we doing
1362 this when we're about to do it again just below? XXX */
1363 mg_set(*sigsvp);
1364
1365 /* And here again we duplicate -- DEFAULT/IGNORE checking. */
1dfe7606 1366 if(SvPOK(*svp)) {
fdac8c4b 1367 const char *s=SvPVX_const(*svp);
1dfe7606
AJ
1368 if(strEQ(s,"IGNORE")) {
1369 act.sa_handler = SIG_IGN;
1370 }
1371 else if(strEQ(s,"DEFAULT")) {
1372 act.sa_handler = SIG_DFL;
1373 }
1dfe7606 1374 }
2304df62
AD
1375
1376 /* Set up any desired mask. */
1377 svp = hv_fetch(action, "MASK", 4, FALSE);
1378 if (svp && sv_isa(*svp, "POSIX::SigSet")) {
ac634a9a 1379 IV tmp = SvIV((SV*)SvRV(*svp));
1dfe7606 1380 sigset = INT2PTR(sigset_t*, tmp);
2304df62
AD
1381 act.sa_mask = *sigset;
1382 }
1383 else
85e6fe83 1384 sigemptyset(& act.sa_mask);
2304df62
AD
1385
1386 /* Set up any desired flags. */
1387 svp = hv_fetch(action, "FLAGS", 5, FALSE);
1388 act.sa_flags = svp ? SvIV(*svp) : 0;
2304df62 1389
1dfe7606
AJ
1390 /* Don't worry about cleaning up *sigsvp if this fails,
1391 * because that means we tried to disposition a
1392 * nonblockable signal, in which case *sigsvp is
1393 * essentially meaningless anyway.
1394 */
6c418a22 1395 RETVAL = sigaction(sig, & act, (struct sigaction *)0);
15c0d34a
CB
1396 if(RETVAL == -1)
1397 XSRETURN_UNDEF;
2304df62 1398 }
1dfe7606
AJ
1399
1400 LEAVE;
2304df62 1401 }
6dead956 1402#endif
2304df62
AD
1403 OUTPUT:
1404 RETVAL
1405
1406SysRet
1407sigpending(sigset)
1408 POSIX::SigSet sigset
1409
1410SysRet
1411sigprocmask(how, sigset, oldsigset = 0)
1412 int how
77253bbf 1413 POSIX::SigSet sigset = NO_INIT
33c27489
GS
1414 POSIX::SigSet oldsigset = NO_INIT
1415INIT:
77253bbf
AB
1416 if (! SvOK(ST(1))) {
1417 sigset = NULL;
1418 } else if (sv_isa(ST(1), "POSIX::SigSet")) {
1419 IV tmp = SvIV((SV*)SvRV(ST(1)));
1420 sigset = INT2PTR(POSIX__SigSet,tmp);
1421 } else {
1422 croak("sigset is not of type POSIX::SigSet");
33c27489 1423 }
77253bbf
AB
1424
1425 if (items < 3 || ! SvOK(ST(2))) {
1426 oldsigset = NULL;
1427 } else if (sv_isa(ST(2), "POSIX::SigSet")) {
33c27489 1428 IV tmp = SvIV((SV*)SvRV(ST(2)));
56431972 1429 oldsigset = INT2PTR(POSIX__SigSet,tmp);
77253bbf
AB
1430 } else {
1431 croak("oldsigset is not of type POSIX::SigSet");
33c27489 1432 }
2304df62
AD
1433
1434SysRet
1435sigsuspend(signal_mask)
1436 POSIX::SigSet signal_mask
1437
2304df62
AD
1438void
1439_exit(status)
1440 int status
8990e307 1441
85e6fe83 1442SysRet
8990e307
LW
1443close(fd)
1444 int fd
1445
85e6fe83 1446SysRet
8990e307
LW
1447dup(fd)
1448 int fd
1449
85e6fe83 1450SysRet
8990e307
LW
1451dup2(fd1, fd2)
1452 int fd1
1453 int fd2
1454
4f4e7967 1455SV *
a0d0e21e 1456lseek(fd, offset, whence)
85e6fe83
LW
1457 int fd
1458 Off_t offset
1459 int whence
4f4e7967
JH
1460 CODE:
1461 Off_t pos = PerlLIO_lseek(fd, offset, whence);
1462 RETVAL = sizeof(Off_t) > sizeof(IV)
1463 ? newSVnv((NV)pos) : newSViv((IV)pos);
1464 OUTPUT:
1465 RETVAL
8990e307 1466
c43a4d73 1467void
8990e307
LW
1468nice(incr)
1469 int incr
630cd32b
JH
1470 PPCODE:
1471 errno = 0;
1472 if ((incr = nice(incr)) != -1 || errno == 0) {
1473 if (incr == 0)
1474 XPUSHs(sv_2mortal(newSVpvn("0 but true", 10)));
1475 else
1476 XPUSHs(sv_2mortal(newSViv(incr)));
1477 }
8990e307 1478
8063af02 1479void
8990e307 1480pipe()
85e6fe83
LW
1481 PPCODE:
1482 int fds[2];
85e6fe83 1483 if (pipe(fds) != -1) {
924508f0 1484 EXTEND(SP,2);
85e6fe83
LW
1485 PUSHs(sv_2mortal(newSViv(fds[0])));
1486 PUSHs(sv_2mortal(newSViv(fds[1])));
1487 }
8990e307 1488
85e6fe83 1489SysRet
a0d0e21e 1490read(fd, buffer, nbytes)
7747499c
TB
1491 PREINIT:
1492 SV *sv_buffer = SvROK(ST(1)) ? SvRV(ST(1)) : ST(1);
1493 INPUT:
1494 int fd
1495 size_t nbytes
1496 char * buffer = sv_grow( sv_buffer, nbytes+1 );
a0d0e21e 1497 CLEANUP:
7747499c 1498 if (RETVAL >= 0) {
a8dc4fe8 1499 SvCUR_set(sv_buffer, RETVAL);
7747499c
TB
1500 SvPOK_only(sv_buffer);
1501 *SvEND(sv_buffer) = '\0';
bbce6d69 1502 SvTAINTED_on(sv_buffer);
7747499c 1503 }
8990e307 1504
85e6fe83 1505SysRet
8990e307 1506setpgid(pid, pgid)
86200d5c
JH
1507 pid_t pid
1508 pid_t pgid
8990e307 1509
86200d5c 1510pid_t
8990e307
LW
1511setsid()
1512
86200d5c 1513pid_t
8990e307
LW
1514tcgetpgrp(fd)
1515 int fd
1516
85e6fe83 1517SysRet
8990e307
LW
1518tcsetpgrp(fd, pgrp_id)
1519 int fd
86200d5c 1520 pid_t pgrp_id
8990e307 1521
8063af02 1522void
8990e307 1523uname()
2304df62 1524 PPCODE:
a0d0e21e 1525#ifdef HAS_UNAME
85e6fe83 1526 struct utsname buf;
85e6fe83 1527 if (uname(&buf) >= 0) {
924508f0 1528 EXTEND(SP, 5);
85e6fe83
LW
1529 PUSHs(sv_2mortal(newSVpv(buf.sysname, 0)));
1530 PUSHs(sv_2mortal(newSVpv(buf.nodename, 0)));
1531 PUSHs(sv_2mortal(newSVpv(buf.release, 0)));
1532 PUSHs(sv_2mortal(newSVpv(buf.version, 0)));
1533 PUSHs(sv_2mortal(newSVpv(buf.machine, 0)));
8990e307 1534 }
a0d0e21e
LW
1535#else
1536 uname((char *) 0); /* A stub to call not_here(). */
1537#endif
8990e307 1538
85e6fe83 1539SysRet
a0d0e21e
LW
1540write(fd, buffer, nbytes)
1541 int fd
1542 char * buffer
1543 size_t nbytes
1544
33f01dd1
SH
1545SV *
1546tmpnam()
1547 PREINIT:
1548 STRLEN i;
1549 int len;
1550 CODE:
1551 RETVAL = newSVpvn("", 0);
1552 SvGROW(RETVAL, L_tmpnam);
1553 len = strlen(tmpnam(SvPV(RETVAL, i)));
1554 SvCUR_set(RETVAL, len);
1555 OUTPUT:
1556 RETVAL
a0d0e21e
LW
1557
1558void
1559abort()
1560
1561int
1562mblen(s, n)
1563 char * s
1564 size_t n
1565
1566size_t
1567mbstowcs(s, pwcs, n)
1568 wchar_t * s
1569 char * pwcs
1570 size_t n
1571
1572int
1573mbtowc(pwc, s, n)
1574 wchar_t * pwc
1575 char * s
1576 size_t n
1577
1578int
1579wcstombs(s, pwcs, n)
1580 char * s
1581 wchar_t * pwcs
1582 size_t n
1583
1584int
1585wctomb(s, wchar)
1586 char * s
1587 wchar_t wchar
1588
1589int
1590strcoll(s1, s2)
1591 char * s1
1592 char * s2
1593
a89d8a78
DH
1594void
1595strtod(str)
1596 char * str
1597 PREINIT:
1598 double num;
1599 char *unparsed;
1600 PPCODE:
36477c24 1601 SET_NUMERIC_LOCAL();
a89d8a78
DH
1602 num = strtod(str, &unparsed);
1603 PUSHs(sv_2mortal(newSVnv(num)));
1604 if (GIMME == G_ARRAY) {
924508f0 1605 EXTEND(SP, 1);
a89d8a78
DH
1606 if (unparsed)
1607 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1608 else
6b88bc9c 1609 PUSHs(&PL_sv_undef);
a89d8a78
DH
1610 }
1611
1612void
1613strtol(str, base = 0)
1614 char * str
1615 int base
1616 PREINIT:
1617 long num;
1618 char *unparsed;
1619 PPCODE:
1620 num = strtol(str, &unparsed, base);
42718184
RB
1621#if IVSIZE <= LONGSIZE
1622 if (num < IV_MIN || num > IV_MAX)
a89d8a78 1623 PUSHs(sv_2mortal(newSVnv((double)num)));
42718184
RB
1624 else
1625#endif
1626 PUSHs(sv_2mortal(newSViv((IV)num)));
a89d8a78 1627 if (GIMME == G_ARRAY) {
924508f0 1628 EXTEND(SP, 1);
a89d8a78
DH
1629 if (unparsed)
1630 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1631 else
6b88bc9c 1632 PUSHs(&PL_sv_undef);
a89d8a78
DH
1633 }
1634
1635void
1636strtoul(str, base = 0)
1637 char * str
1638 int base
1639 PREINIT:
1640 unsigned long num;
1641 char *unparsed;
1642 PPCODE:
1643 num = strtoul(str, &unparsed, base);
f824e39a
JH
1644#if IVSIZE <= LONGSIZE
1645 if (num > IV_MAX)
a89d8a78 1646 PUSHs(sv_2mortal(newSVnv((double)num)));
f824e39a
JH
1647 else
1648#endif
1649 PUSHs(sv_2mortal(newSViv((IV)num)));
a89d8a78 1650 if (GIMME == G_ARRAY) {
924508f0 1651 EXTEND(SP, 1);
a89d8a78
DH
1652 if (unparsed)
1653 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1654 else
6b88bc9c 1655 PUSHs(&PL_sv_undef);
a89d8a78
DH
1656 }
1657
8063af02 1658void
a0d0e21e
LW
1659strxfrm(src)
1660 SV * src
85e6fe83 1661 CODE:
a0d0e21e
LW
1662 {
1663 STRLEN srclen;
1664 STRLEN dstlen;
1665 char *p = SvPV(src,srclen);
1666 srclen++;
37cda61e 1667 ST(0) = sv_2mortal(NEWSV(800,srclen*4+1));
a0d0e21e
LW
1668 dstlen = strxfrm(SvPVX(ST(0)), p, (size_t)srclen);
1669 if (dstlen > srclen) {
1670 dstlen++;
1671 SvGROW(ST(0), dstlen);
1672 strxfrm(SvPVX(ST(0)), p, (size_t)dstlen);
1673 dstlen--;
1674 }
a8dc4fe8 1675 SvCUR_set(ST(0), dstlen);
a0d0e21e
LW
1676 SvPOK_only(ST(0));
1677 }
1678
1679SysRet
1680mkfifo(filename, mode)
1681 char * filename
1682 Mode_t mode
748a9306
LW
1683 CODE:
1684 TAINT_PROPER("mkfifo");
1685 RETVAL = mkfifo(filename, mode);
1686 OUTPUT:
1687 RETVAL
a0d0e21e
LW
1688
1689SysRet
1690tcdrain(fd)
1691 int fd
1692
1693
1694SysRet
1695tcflow(fd, action)
1696 int fd
1697 int action
1698
1699
1700SysRet
1701tcflush(fd, queue_selector)
1702 int fd
1703 int queue_selector
1704
1705SysRet
1706tcsendbreak(fd, duration)
1707 int fd
1708 int duration
1709
1710char *
1711asctime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = 0)
1712 int sec
1713 int min
1714 int hour
1715 int mday
1716 int mon
1717 int year
1718 int wday
1719 int yday
1720 int isdst
1721 CODE:
1722 {
1723 struct tm mytm;
7747499c 1724 init_tm(&mytm); /* XXX workaround - see init_tm() above */
a0d0e21e
LW
1725 mytm.tm_sec = sec;
1726 mytm.tm_min = min;
1727 mytm.tm_hour = hour;
1728 mytm.tm_mday = mday;
1729 mytm.tm_mon = mon;
1730 mytm.tm_year = year;
1731 mytm.tm_wday = wday;
1732 mytm.tm_yday = yday;
1733 mytm.tm_isdst = isdst;
1734 RETVAL = asctime(&mytm);
1735 }
1736 OUTPUT:
1737 RETVAL
1738
1739long
1740clock()
1741
1742char *
1743ctime(time)
748a9306 1744 Time_t &time
8990e307 1745
37120919
AD
1746void
1747times()
1748 PPCODE:
1749 struct tms tms;
1750 clock_t realtime;
1751 realtime = times( &tms );
924508f0 1752 EXTEND(SP,5);
9607fc9c 1753 PUSHs( sv_2mortal( newSViv( (IV) realtime ) ) );
1754 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_utime ) ) );
1755 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_stime ) ) );
1756 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cutime ) ) );
1757 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cstime ) ) );
37120919 1758
a0d0e21e
LW
1759double
1760difftime(time1, time2)
1761 Time_t time1
1762 Time_t time2
1763
1764SysRetLong
1765mktime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = 0)
1766 int sec
1767 int min
1768 int hour
1769 int mday
1770 int mon
1771 int year
1772 int wday
1773 int yday
1774 int isdst
1775 CODE:
1776 {
1777 struct tm mytm;
7747499c 1778 init_tm(&mytm); /* XXX workaround - see init_tm() above */
a0d0e21e
LW
1779 mytm.tm_sec = sec;
1780 mytm.tm_min = min;
1781 mytm.tm_hour = hour;
1782 mytm.tm_mday = mday;
1783 mytm.tm_mon = mon;
1784 mytm.tm_year = year;
1785 mytm.tm_wday = wday;
1786 mytm.tm_yday = yday;
1787 mytm.tm_isdst = isdst;
1788 RETVAL = mktime(&mytm);
1789 }
85e6fe83
LW
1790 OUTPUT:
1791 RETVAL
a0d0e21e 1792
8063af02
DM
1793#XXX: if $xsubpp::WantOptimize is always the default
1794# sv_setpv(TARG, ...) could be used rather than
1795# ST(0) = sv_2mortal(newSVpv(...))
1796void
e44f695e 1797strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1)
a0d0e21e
LW
1798 char * fmt
1799 int sec
1800 int min
1801 int hour
1802 int mday
1803 int mon
1804 int year
1805 int wday
1806 int yday
1807 int isdst
1808 CODE:
1809 {
b3c85772 1810 char *buf = my_strftime(fmt, sec, min, hour, mday, mon, year, wday, yday, isdst);
2a74cb2d
JH
1811 if (buf) {
1812 ST(0) = sv_2mortal(newSVpv(buf, 0));
bf8afc63 1813 Safefree(buf);
2a74cb2d 1814 }
a0d0e21e
LW
1815 }
1816
1817void
1818tzset()
1819
1820void
1821tzname()
1822 PPCODE:
924508f0 1823 EXTEND(SP,2);
79cb57f6
GS
1824 PUSHs(sv_2mortal(newSVpvn(tzname[0],strlen(tzname[0]))));
1825 PUSHs(sv_2mortal(newSVpvn(tzname[1],strlen(tzname[1]))));
a0d0e21e
LW
1826
1827SysRet
1828access(filename, mode)
1829 char * filename
1830 Mode_t mode
1831
1832char *
1833ctermid(s = 0)
cb0e10e2
NC
1834 char * s = 0;
1835 CODE:
1836#ifdef HAS_CTERMID_R
1837 s = safemalloc((size_t) L_ctermid);
1838#endif
1839 RETVAL = ctermid(s);
1840 OUTPUT:
1841 RETVAL
1842 CLEANUP:
1843#ifdef HAS_CTERMID_R
1844 Safefree(s);
1845#endif
a0d0e21e
LW
1846
1847char *
1848cuserid(s = 0)
1849 char * s = 0;
1850
1851SysRetLong
1852fpathconf(fd, name)
1853 int fd
1854 int name
1855
1856SysRetLong
1857pathconf(filename, name)
1858 char * filename
1859 int name
1860
1861SysRet
1862pause()
1863
a043a685
GW
1864SysRet
1865setgid(gid)
1866 Gid_t gid
a1050883 1867 CLEANUP:
1ce94807 1868#ifndef WIN32
a1050883
SR
1869 if (RETVAL >= 0) {
1870 PL_gid = getgid();
1871 PL_egid = getegid();
1872 }
1ce94807 1873#endif
a043a685
GW
1874
1875SysRet
1876setuid(uid)
1877 Uid_t uid
a1050883 1878 CLEANUP:
1ce94807 1879#ifndef WIN32
a1050883
SR
1880 if (RETVAL >= 0) {
1881 PL_uid = getuid();
1882 PL_euid = geteuid();
1883 }
1ce94807 1884#endif
a043a685 1885
a0d0e21e
LW
1886SysRetLong
1887sysconf(name)
1888 int name
1889
1890char *
1891ttyname(fd)
1892 int fd
a043a685 1893
c6c619a9 1894void
b5846a0b 1895getcwd()
8f95b30d
JH
1896 PPCODE:
1897 {
1898 dXSTARG;
89423764 1899 getcwd_sv(TARG);
8f95b30d
JH
1900 XSprePUSH; PUSHTARG;
1901 }
1902
9dce9c87
NC
1903SysRet
1904lchown(uid, gid, path)
1905 Uid_t uid
1906 Gid_t gid
1907 char * path
1908 CODE:
1909#ifdef HAS_LCHOWN
1910 /* yes, the order of arguments is different,
1911 * but consistent with CORE::chown() */
1912 RETVAL = lchown(path, uid, gid);
1913#else
1914 RETVAL = not_here("lchown");
1915#endif
1916 OUTPUT:
1917 RETVAL