This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
amigaos4: add Amiga::ARexx and Amiga::Exec
[perl5.git] / ext / Amiga-Exec / Exec.xs
1 #include "EXTERN.h"
2 #include "perl.h"
3 #include "XSUB.h"
4
5 #include "ppport.h"
6
7 #undef __USE_INLINE__
8 #include <exec/types.h>
9 #include <utility/tagitem.h>
10 #include <dos/dos.h>
11 #include <proto/exec.h>
12 #include <proto/intuition.h>
13 #include <proto/utility.h>
14
15
16
17 struct TimeRequest *
18 OpenTimer(void)
19 {
20         struct MsgPort *port = IExec->AllocSysObjectTags(ASOT_PORT, TAG_END);
21         if (port == NULL)
22         {
23                 return NULL;
24         }
25
26         struct TimeRequest *req = IExec->AllocSysObjectTags(ASOT_IOREQUEST,
27                 ASOIOR_Size, sizeof(struct TimeRequest),
28                 ASOIOR_ReplyPort, port,
29                 TAG_END);
30
31         if (req == NULL)
32         {
33                 IExec->FreeSysObject(ASOT_PORT, port);
34                 return NULL;
35         }
36
37         int8 deverr = IExec->OpenDevice("timer.device", UNIT_MICROHZ,
38                 &req->Request, 0);
39
40         if (deverr != IOERR_SUCCESS)
41         {
42                 IExec->FreeSysObject(ASOT_IOREQUEST, req);
43                 IExec->FreeSysObject(ASOT_PORT, port);
44                 return NULL;
45         }
46
47         return req;
48 }
49
50
51 void
52 CloseTimer(struct TimeRequest *req)
53 {
54         if (req != NULL)
55         {
56                 struct MsgPort *port = req->Request.io_Message.mn_ReplyPort;
57
58                 IExec->CloseDevice(&req->Request);
59                 IExec->FreeSysObject(ASOT_IOREQUEST, req);
60                 IExec->FreeSysObject(ASOT_PORT, port);
61         }
62 }
63
64
65
66 uint32 WaitTimeout(uint32 signalmask , int timeout)
67 {
68
69         struct TimeRequest *req = NULL;
70         uint32 timermask        = 0;
71
72         if (timeout > 0)
73         {
74                 req = OpenTimer();
75
76                 if (req != NULL)
77                 {
78                         timermask = 1L << req->Request.io_Message.mn_ReplyPort->mp_SigBit;
79
80                         req->Request.io_Command = TR_ADDREQUEST;
81                         req->Time.Seconds       = 0;
82                         req->Time.Microseconds  = timeout;
83
84                         IExec->SendIO(&req->Request);
85                 }
86         }
87
88         uint32 waitmask = timermask |  signalmask | SIGBREAKF_CTRL_C;
89
90         uint32 sigmask = IExec->Wait(waitmask);
91
92         if (req != NULL)
93         {
94                 IExec->AbortIO(&req->Request);
95                 IExec->WaitIO(&req->Request);
96                 CloseTimer(req);
97         }
98
99         /* remove the timer mask bit */
100
101         return sigmask & (~timermask );
102 }
103
104
105
106 MODULE = Amiga::Exec              PACKAGE = Amiga::Exec
107
108 PROTOTYPES: DISABLE
109
110
111 uint32 _Wait(signalmask,timeout)
112     uint32 signalmask;
113     uint32 timeout;
114     CODE:
115         RETVAL = WaitTimeout(signalmask,timeout);
116     OUTPUT:
117         RETVAL
118