~ubuntu-branches/ubuntu/lucid/graphviz/lucid-security

« back to all changes in this revision

Viewing changes to tools/sfio/sfpoll.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephen M Moraco
  • Date: 2002-02-05 18:52:12 UTC
  • Revision ID: james.westby@ubuntu.com-20020205185212-8i04c70te00rc40y
Tags: upstream-1.7.16
ImportĀ upstreamĀ versionĀ 1.7.16

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include        "sfhdr.h"
 
2
 
 
3
/*      Poll a set of streams to see if any is available for I/O.
 
4
**      Ready streams are moved to front of array but retain the
 
5
**      same relative order.
 
6
**
 
7
**      Written by Kiem-Phong Vo.
 
8
*/
 
9
 
 
10
#if __STD_C
 
11
int sfpoll(Sfio_t** fa, reg int n, int tm)
 
12
#else
 
13
int sfpoll(fa, n, tm)
 
14
Sfio_t**        fa;     /* array of streams to poll */
 
15
reg int         n;      /* number of streams in array */
 
16
int             tm;     /* the amount of time in ms to wait for selecting */
 
17
#endif
 
18
{
 
19
        reg int         r, c, m;
 
20
        reg Sfio_t*     f;
 
21
        reg Sfdisc_t*   d;
 
22
        reg int         *status, *check;
 
23
 
 
24
        if(n <= 0 || !fa)
 
25
                return -1;
 
26
 
 
27
        if(!(status = (int*)malloc(2*n*sizeof(int))) )
 
28
                return -1;
 
29
        else    check = status+n;
 
30
 
 
31
        /* this loop partitions the streams into 3 sets: Check, Ready, Notready */
 
32
retry:  for(r = c = 0; r < n; ++r)
 
33
        {       f = fa[r];
 
34
 
 
35
                /* this loop pops a stream stack as necessary */
 
36
                for(;;)
 
37
                {       /* check accessibility */
 
38
                        m = f->mode&SF_RDWR;
 
39
                        if((int)f->mode != m && _sfmode(f,m,0) < 0)
 
40
                                goto do_never;
 
41
 
 
42
                        /* clearly ready */
 
43
                        if(f->next < f->endb)
 
44
                                goto do_ready;
 
45
 
 
46
                        /* has discipline, ask its opinion */
 
47
                        for(d = f->disc; d; d = d->disc)
 
48
                                if(d->exceptf)
 
49
                                        break;
 
50
                        if(d)
 
51
                        {       if((m = (*d->exceptf)(f,SF_DPOLL,&tm,d)) < 0)
 
52
                                        goto do_never;
 
53
                                else if(m > 0)
 
54
                                        goto do_ready;
 
55
                                /*else check file descriptor*/
 
56
                        }
 
57
 
 
58
                        /* unseekable stream, must check for blockability */
 
59
                        if(f->extent < 0)
 
60
                                goto do_check;
 
61
 
 
62
                        /* string/regular streams with no possibility of blocking */
 
63
                        if(!f->push)
 
64
                                goto do_ready;
 
65
 
 
66
                        /* stacked regular file stream with I/O possibility */
 
67
                        if(!(f->flags&SF_STRING) &&
 
68
                           ((f->mode&SF_WRITE) || f->here < f->extent) )
 
69
                                goto do_ready;
 
70
 
 
71
                        /* at an apparent eof, pop stack if ok, then recheck */
 
72
                        SETLOCAL(f);
 
73
                        switch(_sfexcept(f,f->mode&SF_RDWR,0,f->disc))
 
74
                        {
 
75
                        case SF_EDONE:
 
76
                                if(f->flags&SF_STRING)
 
77
                                        goto do_never;
 
78
                                else    goto do_ready;
 
79
                        case SF_EDISC:
 
80
                                if(f->flags&SF_STRING)
 
81
                                        goto do_ready;
 
82
                        case SF_ESTACK:
 
83
                        case SF_ECONT:
 
84
                                continue;
 
85
                        }
 
86
                }
 
87
 
 
88
                do_check:       /* local function to set a stream for further checking */
 
89
                {       status[r] = 0;
 
90
                        check[c] = r;
 
91
                        c += 1;
 
92
                        continue;
 
93
                }
 
94
 
 
95
                do_ready:       /* local function to set the ready streams */
 
96
                {       status[r] = 1;
 
97
                        continue;
 
98
                }
 
99
 
 
100
                do_never:       /* local function to set the not-ready streams */
 
101
                {       status[r] = -1;
 
102
                        continue;
 
103
                }
 
104
        }
 
105
 
 
106
#if _lib_poll
 
107
        if(c > 0)
 
108
        {       struct pollfd*  fds;
 
109
 
 
110
                /* construct the poll array */
 
111
                if(!(fds = (struct pollfd*)malloc(c*sizeof(struct pollfd))) )
 
112
                        return -1;
 
113
                for(r = 0; r < c; r++)
 
114
                {       fds[r].fd = fa[check[r]]->file;
 
115
                        fds[r].events = (fa[check[r]]->mode&SF_READ) ? POLLIN : POLLOUT;
 
116
                        fds[r].revents = 0;
 
117
                }
 
118
 
 
119
                for(;;) /* this loop takes care of interrupts */
 
120
                {       if((r = SFPOLL(fds,c,tm)) == 0)
 
121
                                break;
 
122
                        else if(r < 0)
 
123
                        {       if(errno == EINTR || errno == EAGAIN)
 
124
                                {       errno = 0;
 
125
                                        continue;
 
126
                                }
 
127
                                else    break;
 
128
                        }
 
129
 
 
130
                        for(r = 0; r < c; ++r)
 
131
                        {       f = fa[check[r]];
 
132
                                if(((f->mode&SF_READ) && (fds[r].revents&POLLIN)) ||
 
133
                                   ((f->mode&SF_WRITE) && (fds[r].revents&POLLOUT)) )
 
134
                                        status[check[r]] = 1;
 
135
                        }
 
136
                        break;
 
137
                }
 
138
 
 
139
                free((Void_t*)fds);
 
140
        }
 
141
#endif /*_lib_poll*/
 
142
 
 
143
#if _lib_select
 
144
        if(c > 0)
 
145
        {       fd_set          rd, wr;
 
146
                struct timeval  tmb, *tmp;
 
147
 
 
148
                FD_ZERO(&rd);
 
149
                FD_ZERO(&wr);
 
150
                m = 0;
 
151
                for(r = 0; r < c; ++r)
 
152
                {       f = fa[check[r]];
 
153
                        if(f->file > m)
 
154
                                m = f->file;
 
155
                        if(f->mode&SF_READ)
 
156
                                FD_SET(f->file,&rd);
 
157
                        else    FD_SET(f->file,&wr);
 
158
                }
 
159
                if(tm < 0)
 
160
                        tmp = NIL(struct timeval*);
 
161
                else
 
162
                {       tmp = &tmb;
 
163
                        tmb.tv_sec = tm/SECOND;
 
164
                        tmb.tv_usec = (tm%SECOND)*SECOND;
 
165
                }
 
166
                for(;;)
 
167
                {       if((r = select(m+1,&rd,&wr,NIL(fd_set*),tmp)) == 0)
 
168
                                break;
 
169
                        else if(r < 0)
 
170
                        {       if(errno == EINTR)
 
171
                                        continue;
 
172
                                else    break;
 
173
                        }
 
174
 
 
175
                        for(r = 0; r < c; ++r)
 
176
                        {       f = fa[check[r]];
 
177
                                if(((f->mode&SF_READ) && FD_ISSET(f->file,&rd)) ||
 
178
                                   ((f->mode&SF_WRITE) && FD_ISSET(f->file,&wr)) )
 
179
                                        status[check[r]] = 1;
 
180
                        }
 
181
                        break;
 
182
                }
 
183
        }
 
184
#endif /*_lib_select*/
 
185
 
 
186
        /* call exception functions */
 
187
        for(c = 0; c < n; ++c)
 
188
        {       if(status[c] <= 0)
 
189
                        continue;
 
190
                if((d = fa[c]->disc) && d->exceptf)
 
191
                {       if((r = (*d->exceptf)(fa[c],SF_READY,(Void_t*)0,d)) < 0)
 
192
                                goto done;
 
193
                        else if(r > 0)
 
194
                                goto retry;
 
195
                }
 
196
        }
 
197
 
 
198
        /* move ready streams to the front */
 
199
        for(r = c = 0; c < n; ++c)
 
200
        {       if(status[c] > 0)
 
201
                {       if(c > r)
 
202
                        {       f = fa[r];
 
203
                                fa[r] = fa[c];
 
204
                                fa[c] = f;
 
205
                        }
 
206
                        r += 1;
 
207
                }
 
208
        }
 
209
 
 
210
done:
 
211
        free((Void_t*)status);
 
212
        return r;
 
213
}