source: trunk/third/tcsh/tc.sched.c @ 22036

Revision 22036, 7.3 KB checked in by ghudson, 19 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r22035, which included commits to RCS files with non-trunk default branches.
RevLine 
[22035]1/* $Header: /afs/dev.mit.edu/source/repository/third/tcsh/tc.sched.c,v 1.1.1.3 2005-06-03 14:35:05 ghudson Exp $ */
[9005]2/*
3 * tc.sched.c: Scheduled command execution
4 *
5 * Karl Kleinpaste: Computer Consoles Inc. 1984
6 */
7/*-
8 * Copyright (c) 1980, 1991 The Regents of the University of California.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
[22035]19 * 3. Neither the name of the University nor the names of its contributors
[9005]20 *    may be used to endorse or promote products derived from this software
21 *    without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35#include "sh.h"
36
[22035]37RCSID("$Id: tc.sched.c,v 1.1.1.3 2005-06-03 14:35:05 ghudson Exp $")
[9005]38
39#include "ed.h"
[22035]40#include "tw.h"
[9005]41#include "tc.h"
42
43extern int just_signaled;
44
45struct sched_event {
46    struct sched_event *t_next;
47    time_t t_when;
48    Char  **t_lex;
49};
50static struct sched_event *sched_ptr = NULL;
51
52
53time_t
54sched_next()
55{
56    if (sched_ptr)
57        return (sched_ptr->t_when);
58    return ((time_t) - 1);
59}
60
61/*ARGSUSED*/
62void
63dosched(v, c)
[22035]64    Char **v;
[9005]65    struct command *c;
66{
[22035]67    struct sched_event *tp, *tp1, *tp2;
[9005]68    time_t  cur_time;
69    int     count, hours, minutes, dif_hour, dif_min;
70    Char   *cp;
[22035]71    int    relative;            /* time specified as +hh:mm */
[9005]72    struct tm *ltp;
73
[12038]74    USE(c);
[9005]75/* This is a major kludge because of a gcc linker  */
76/* Problem.  It may or may not be needed for you   */
[22035]77#if defined(_MINIX) && !defined(_MINIX_VMD)
[9005]78    char kludge[10];
79    extern char *sprintf();
[12038]80    sprintf(kludge, CGETS(24, 1, "kludge"));
[22035]81#endif /* _MINIX && !_MINIX_VMD */
[9005]82
83    v++;
84    cp = *v++;
85    if (cp == NULL) {
[12038]86        Char   *fmt;
87        if ((fmt = varval(STRsched)) == STRNULL)
88            fmt = str2short("%h\t%T\t%R\n");
[9005]89        /* print list of scheduled events */
90        for (count = 1, tp = sched_ptr; tp; count++, tp = tp->t_next) {
[12038]91            Char buf[BUFSIZE], sbuf[BUFSIZE];
92            blkexpand(tp->t_lex, buf);
93            tprintf(FMT_SCHED, sbuf, fmt, sizeof(sbuf),
94                    short2str(buf), tp->t_when, (ptr_t) &count);
95            for (cp = sbuf; *cp;)
[22035]96                xputwchar(*cp++);
[9005]97        }
98        return;
99    }
100
101    if (*cp == '-') {
102        /* remove item from list */
103        if (!sched_ptr)
104            stderror(ERR_NOSCHED);
105        if (*v)
106            stderror(ERR_SCHEDUSAGE);
107        count = atoi(short2str(++cp));
108        if (count <= 0)
109            stderror(ERR_SCHEDUSAGE);
110        tp = sched_ptr;
111        tp1 = 0;
112        while (--count) {
113            if (tp->t_next == 0)
114                break;
115            else {
116                tp1 = tp;
117                tp = tp->t_next;
118            }
119        }
120        if (count)
121            stderror(ERR_SCHEDEV);
122        if (tp1 == 0)
123            sched_ptr = tp->t_next;
124        else
125            tp1->t_next = tp->t_next;
126        blkfree(tp->t_lex);
127        xfree((ptr_t) tp);
128        return;
129    }
130
131    /* else, add an item to the list */
132    if (!*v)
133        stderror(ERR_SCHEDCOM);
134    relative = 0;
135    if (!Isdigit(*cp)) {        /* not abs. time */
136        if (*cp != '+')
137            stderror(ERR_SCHEDUSAGE);
138        cp++, relative++;
139    }
140    minutes = 0;
141    hours = atoi(short2str(cp));
142    while (*cp && *cp != ':' && *cp != 'a' && *cp != 'p')
143        cp++;
144    if (*cp && *cp == ':')
145        minutes = atoi(short2str(++cp));
146    if ((hours < 0) || (minutes < 0) ||
147        (hours > 23) || (minutes > 59))
148        stderror(ERR_SCHEDTIME);
149    while (*cp && *cp != 'p' && *cp != 'a')
150        cp++;
151    if (*cp && relative)
152        stderror(ERR_SCHEDREL);
153    if (*cp == 'p')
154        hours += 12;
155    (void) time(&cur_time);
156    ltp = localtime(&cur_time);
157    if (relative) {
158        dif_hour = hours;
159        dif_min = minutes;
160    }
161    else {
162        if ((dif_hour = hours - ltp->tm_hour) < 0)
163            dif_hour += 24;
164        if ((dif_min = minutes - ltp->tm_min) < 0) {
165            dif_min += 60;
166            if ((--dif_hour) < 0)
167                dif_hour = 23;
168        }
169    }
170    tp = (struct sched_event *) xcalloc(1, sizeof *tp);
[22035]171#ifdef _SX
172    tp->t_when = cur_time - ltp->tm_sec + dif_hour * 3600 + dif_min * 60;
173#else   /* _SX */       
[9005]174    tp->t_when = cur_time - ltp->tm_sec + dif_hour * 3600L + dif_min * 60L;
[22035]175#endif /* _SX */
[9005]176    /* use of tm_sec: get to beginning of minute. */
177    if (!sched_ptr || tp->t_when < sched_ptr->t_when) {
178        tp->t_next = sched_ptr;
179        sched_ptr = tp;
180    }
181    else {
182        tp1 = sched_ptr->t_next;
183        tp2 = sched_ptr;
184        while (tp1 && tp->t_when >= tp1->t_when) {
185            tp2 = tp1;
186            tp1 = tp1->t_next;
187        }
188        tp->t_next = tp1;
189        tp2->t_next = tp;
190    }
191    tp->t_lex = saveblk(v);
192}
193
194/*
195 * Execute scheduled events
196 */
[12038]197/*ARGSUSED*/
[9005]198void
[12038]199sched_run(n)
200    int n;
[9005]201{
202    time_t   cur_time;
[22035]203    struct sched_event *tp, *tp1;
[9005]204    struct wordent cmd, *nextword, *lastword;
205    struct command *t;
206    Char  **v, *cp;
207#ifdef BSDSIGS
208    sigmask_t omask;
209
210    omask = sigblock(sigmask(SIGINT)) & ~sigmask(SIGINT);
211#else
212    (void) sighold(SIGINT);
213#endif
214
[12038]215    USE(n);
216
[9005]217    (void) time(&cur_time);
218    tp = sched_ptr;
219
220    /* bugfix by: Justin Bur at Universite de Montreal */
221    /*
222     * this test wouldn't be necessary if this routine were not called before
223     * each prompt (in sh.c).  But it is, to catch missed alarms.  Someone
224     * ought to fix it all up.  -jbb
225     */
226    if (!(tp && tp->t_when < cur_time)) {
227#ifdef BSDSIGS
228        (void) sigsetmask(omask);
229#else
230        (void) sigrelse(SIGINT);
231#endif
232        return;
233    }
234
235    if (GettingInput)
236        (void) Cookedmode();
237
238    while (tp && tp->t_when < cur_time) {
239        if (seterr) {
240            xfree((ptr_t) seterr);
241            seterr = NULL;
242        }
243        cmd.word = STRNULL;
244        lastword = &cmd;
245        v = tp->t_lex;
246        for (cp = *v; cp; cp = *++v) {
247            nextword = (struct wordent *) xcalloc(1, sizeof cmd);
248            nextword->word = Strsave(cp);
249            lastword->next = nextword;
250            nextword->prev = lastword;
251            lastword = nextword;
252        }
253        lastword->next = &cmd;
254        cmd.prev = lastword;
255        tp1 = tp;
256        sched_ptr = tp = tp1->t_next;   /* looping termination cond: */
257        blkfree(tp1->t_lex);    /* straighten out in case of */
258        xfree((ptr_t) tp1);     /* command blow-up. */
259
260        /* expand aliases like process() does. */
261        alias(&cmd);
262        /* build a syntax tree for the command. */
263        t = syntax(cmd.next, &cmd, 0);
264        if (seterr)
265            stderror(ERR_OLD);
266        /* execute the parse tree. */
[22035]267        execute(t, -1, NULL, NULL, TRUE);
[9005]268        /* done. free the lex list and parse tree. */
269        freelex(&cmd), freesyn(t);
270    }
271    if (GettingInput && !just_signaled) {       /* PWP */
272        (void) Rawmode();
273        ClearLines();           /* do a real refresh since something may */
274        ClearDisp();            /* have printed to the screen */
275        Refresh();
276    }
277    just_signaled = 0;
278
279#ifdef BSDSIGS
280    (void) sigsetmask(omask);
281#else
282    (void) sigrelse(SIGINT);
283#endif
284}
Note: See TracBrowser for help on using the repository browser.