Backport
[AROS.git] / workbench / c / Wait.c
blobda7f86d7df375e3cb64cd6932fc3efa26b9c3d7f
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Wait CLI Command.
6 */
8 /******************************************************************************
11 NAME
13 Wait [(n)] [SEC | SECS | MIN | MINS] [ UNTIL (time) ]
15 SYNOPSIS
17 TIME/N,SEC=SECS/S,MIN=MINS/S,UNTIL/K
19 LOCATION
23 FUNCTION
25 Wait a certain amount of time or until a specified time. Using
26 Wait without any arguments waits for one second.
28 INPUTS
30 TIME -- the number of time units to wait (default is seconds)
31 SEC=SECS -- set the time unit to seconds
32 MIN=MINS -- set the time unit to minutes
33 UNTIL -- wait until the specified time is reached. The time
34 is given in the format HH:MM.
36 RESULT
38 NOTES
40 EXAMPLE
42 BUGS
44 SEE ALSO
46 INTERNALS
48 ******************************************************************************/
50 #include <exec/execbase.h>
51 #include <exec/libraries.h>
52 #include <devices/timer.h>
53 #include <dos/dos.h>
55 #include <proto/dos.h>
56 #include <proto/exec.h>
58 #include <string.h>
60 const TEXT version[] = "$VER: Wait 41.2 (30.4.2000)\n";
62 int __nocommandline;
64 int main (void)
66 IPTR args[4] = { 0, 0, 0, 0 };
67 struct RDArgs *rda;
68 LONG error = RETURN_OK;
69 ULONG delay = 1;
71 #define ERROR(a) { error = a; goto end; }
73 rda = ReadArgs("TIME/N,SEC=SECS/S,MIN=MINS/S,UNTIL/K", args, NULL);
75 if (rda == NULL)
77 PrintFault(IoErr(),"Wait");
78 ERROR(RETURN_FAIL);
81 if (args[3])
83 /* UNTIL */
84 struct DateTime dt;
85 struct DateStamp ds;
86 LONG now_secs, then_secs, diff_secs;
87 UBYTE timestring[9];
89 DateStamp(&ds);
90 now_secs = ds.ds_Minute * 60 + ds.ds_Tick / TICKS_PER_SECOND;
92 if (strlen((char *)args[3]) > 5)
94 PutStr("Time should be HH:MM");
95 ERROR(RETURN_FAIL);
98 strcpy(timestring, (UBYTE *)args[3]);
99 strcat(timestring, ":00");
101 memset(&dt, 0, sizeof(dt));
102 dt.dat_StrTime = timestring;
104 if (!StrToDate(&dt))
106 PutStr("Time should be HH:MM");
107 ERROR(RETURN_FAIL);
110 then_secs = dt.dat_Stamp.ds_Minute * 60 + dt.dat_Stamp.ds_Tick / TICKS_PER_SECOND;
111 diff_secs = then_secs - now_secs;
113 if (diff_secs < 0)
115 diff_secs += 60L * 60L * 24L;
118 delay = diff_secs * TICKS_PER_SECOND;
121 else
123 if (args[0])
125 delay = *((ULONG *)args[0]);
128 if (args[2])
130 delay *= 60L;
133 delay *= TICKS_PER_SECOND;
136 if (delay > 0)
138 // Commented out the following: Wait is often used in scripts to allow to break loops, so it must always care about breaking
139 // if (delay <= TICKS_PER_SECOND)
140 // {
141 // /* Don't care about breaking if delay is less than 1 second */
142 // Delay (delay);
143 // }
144 // else
146 struct MsgPort *timermp;
147 struct timerequest *timerio;
148 BOOL memok = FALSE, devok = FALSE;
150 if ((timermp = CreateMsgPort()))
152 if ((timerio = (struct timerequest *)CreateIORequest(timermp, sizeof(struct timerequest))))
154 memok = TRUE;
155 if (OpenDevice("timer.device", UNIT_VBLANK, &timerio->tr_node, 0) == 0)
157 ULONG timermask, sigs;
158 BOOL done = FALSE;
160 devok = TRUE;
162 timerio->tr_node.io_Command = TR_ADDREQUEST;
163 timerio->tr_time.tv_secs = delay / TICKS_PER_SECOND;
164 timerio->tr_time.tv_micro = 1000000UL / TICKS_PER_SECOND * (delay % TICKS_PER_SECOND);
166 timermask = 1L << timermp->mp_SigBit;
168 SendIO(&timerio->tr_node);
170 while(!done)
172 sigs = Wait(SIGBREAKF_CTRL_C | timermask);
174 if (sigs & timermask)
176 done = TRUE;
179 if (sigs & SIGBREAKF_CTRL_C)
181 if (!CheckIO(&timerio->tr_node)) AbortIO(&timerio->tr_node);
182 WaitIO(&timerio->tr_node);
184 error = RETURN_WARN;
185 done = TRUE;
188 } /* while(!finished) */
189 CloseDevice(&timerio->tr_node);
191 } /* if (OpenDevice("timer.device", UNIT_VBLANK, &timerio->tr_node, 0) == 0) */
192 DeleteIORequest(&timerio->tr_node);
194 } /* if (timerio = (struct timerequest *)CreateIORequest(timermp, sizeof(struct timerequest))) */
195 DeleteMsgPort(timermp);
197 } /* if ((timermp = CreateMsgPort())) */
199 if (!memok)
201 PrintFault(ERROR_NO_FREE_STORE,"Wait");
202 ERROR(RETURN_FAIL);
204 else if (!devok)
206 PutStr("Wait: Could not open timer.device!");
207 ERROR(RETURN_FAIL);
212 } /* if (delay > 0) */
214 end:
215 if (rda)
217 FreeArgs(rda);
220 return error;