OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [net/] [tcpip/] [current/] [src/] [sys/] [kern/] [sys_generic.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      sys/kern/sys_generic.c
4
//
5
//     
6
//
7
//==========================================================================
8
// ####BSDALTCOPYRIGHTBEGIN####                                             
9
// -------------------------------------------                              
10
// Portions of this software may have been derived from OpenBSD             
11
// or other sources, and if so are covered by the appropriate copyright     
12
// and license included herein.                                             
13
// -------------------------------------------                              
14
// ####BSDALTCOPYRIGHTEND####                                               
15
//==========================================================================
16
//#####DESCRIPTIONBEGIN####
17
//
18
// Author(s):    gthomas
19
// Contributors: gthomas
20
// Date:         2000-01-10
21
// Purpose:      
22
// Description:  
23
//              
24
//
25
//####DESCRIPTIONEND####
26
//
27
//==========================================================================
28
 
29
 
30
/*      $OpenBSD: sys_generic.c,v 1.22 1999/11/29 22:02:14 deraadt Exp $        */
31
/*      $NetBSD: sys_generic.c,v 1.24 1996/03/29 00:25:32 cgd Exp $     */
32
 
33
/*
34
 * Copyright (c) 1996 Theo de Raadt
35
 * Copyright (c) 1982, 1986, 1989, 1993
36
 *      The Regents of the University of California.  All rights reserved.
37
 * (c) UNIX System Laboratories, Inc.
38
 * All or some portions of this file are derived from material licensed
39
 * to the University of California by American Telephone and Telegraph
40
 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
41
 * the permission of UNIX System Laboratories, Inc.
42
 *
43
 * Redistribution and use in source and binary forms, with or without
44
 * modification, are permitted provided that the following conditions
45
 * are met:
46
 * 1. Redistributions of source code must retain the above copyright
47
 *    notice, this list of conditions and the following disclaimer.
48
 * 2. Redistributions in binary form must reproduce the above copyright
49
 *    notice, this list of conditions and the following disclaimer in the
50
 *    documentation and/or other materials provided with the distribution.
51
 * 3. All advertising materials mentioning features or use of this software
52
 *    must display the following acknowledgement:
53
 *      This product includes software developed by the University of
54
 *      California, Berkeley and its contributors.
55
 * 4. Neither the name of the University nor the names of its contributors
56
 *    may be used to endorse or promote products derived from this software
57
 *    without specific prior written permission.
58
 *
59
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
60
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
61
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
62
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
63
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
64
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
65
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
66
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
67
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
68
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
69
 * SUCH DAMAGE.
70
 *
71
 *      @(#)sys_generic.c       8.5 (Berkeley) 1/21/94
72
 */
73
 
74
#include <sys/param.h>
75
#ifndef __ECOS
76
#include <sys/systm.h>
77
#include <sys/filedesc.h>
78
#endif // __ECOS
79
#include <sys/ioctl.h>
80
#ifdef __ECOS
81
#include <cyg/io/file.h>
82
#else // __ECOS
83
#include <sys/file.h>
84
#include <sys/proc.h>
85
#include <sys/resourcevar.h>
86
#endif // __ECOS
87
#include <sys/socketvar.h>
88
#ifndef __ECOS
89
#include <sys/signalvar.h>
90
#include <sys/kernel.h>
91
#include <sys/uio.h>
92
#include <sys/stat.h>
93
#endif // __ECOS
94
#include <sys/malloc.h>
95
#ifndef __ECOS
96
#include <sys/poll.h>
97
#endif // __ECOS
98
#ifdef KTRACE
99
#include <sys/ktrace.h>
100
#endif
101
 
102
#ifndef __ECOS
103
#include <sys/mount.h>
104
#endif // __ECOS
105
#include <sys/syscallargs.h>
106
 
107
#ifndef __ECOS
108
int selscan __P((struct proc *, fd_set *, fd_set *, int, register_t *));
109
int seltrue __P((dev_t, int, struct proc *));
110
void pollscan __P((struct proc *, struct pollfd *, int, register_t *));
111
#endif // __ECOS
112
 
113
/*
114
 * Read system call.
115
 */
116
#ifdef __ECOS
117
int
118
sys_read(struct sys_read_args *uap, register_t *retval)
119
#else
120
/* ARGSUSED */
121
int
122
sys_read(p, v, retval)
123
        struct proc *p;
124
        void *v;
125
        register_t *retval;
126
#endif
127
{
128
#ifndef __ECOS
129
        register struct sys_read_args /* {
130
                syscallarg(int) fd;
131
                syscallarg(void *) buf;
132
                syscallarg(size_t) nbyte;
133
        } */ *uap = v;
134
        register struct filedesc *fdp = p->p_fd;
135
#endif
136
        struct file *fp;
137
        struct uio auio;
138
        struct iovec aiov;
139
        long cnt, error = 0;
140
#ifdef KTRACE
141
        struct iovec ktriov;
142
#endif
143
 
144
#ifdef __ECOS
145
        if (getfp((u_int)SCARG(uap, fd), &fp) ||
146
#else
147
        if (((u_int)SCARG(uap, fd)) >= fdp->fd_nfiles ||
148
            (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL ||
149
#endif
150
            (fp->f_flag & FREAD) == 0)
151
                return (EBADF);
152
        /* Don't allow nbyte to be larger than max return val */
153
        if (SCARG(uap, nbyte) > SSIZE_MAX)
154
                return(EINVAL);
155
        aiov.iov_base = (caddr_t)SCARG(uap, buf);
156
        aiov.iov_len = SCARG(uap, nbyte);
157
        auio.uio_iov = &aiov;
158
        auio.uio_iovcnt = 1;
159
        auio.uio_resid = SCARG(uap, nbyte);
160
        auio.uio_rw = UIO_READ;
161
        auio.uio_segflg = UIO_USERSPACE;
162
#ifndef __ECOS
163
        auio.uio_procp = p;
164
#endif
165
#ifdef KTRACE
166
        /*
167
         * if tracing, save a copy of iovec
168
         */
169
        if (KTRPOINT(p, KTR_GENIO))
170
                ktriov = aiov;
171
#endif
172
        cnt = SCARG(uap, nbyte);
173
#ifdef __ECOS
174
        error = (*fp->f_ops->fo_read)(fp, &auio);
175
#else
176
        error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred);
177
#endif
178
        if (error)
179
#ifdef __ECOS
180
                if (auio.uio_resid != cnt && (
181
#else
182
                if (auio.uio_resid != cnt && (error == ERESTART ||
183
#endif
184
                    error == EINTR || error == EWOULDBLOCK))
185
                        error = 0;
186
        cnt -= auio.uio_resid;
187
#ifdef KTRACE
188
        if (KTRPOINT(p, KTR_GENIO) && error == 0)
189
                ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_READ, &ktriov,
190
                    cnt, error);
191
#endif
192
        *retval = cnt;
193
        return (error);
194
}
195
 
196
 
197
#ifndef __ECOS
198
/*
199
 * Scatter read system call.
200
 */
201
int
202
sys_readv(p, v, retval)
203
        struct proc *p;
204
        void *v;
205
        register_t *retval;
206
{
207
        register struct sys_readv_args /* {
208
                syscallarg(int) fd;
209
                syscallarg(struct iovec *) iovp;
210
                syscallarg(int) iovcnt;
211
        } */ *uap = v;
212
        register struct file *fp;
213
        register struct filedesc *fdp = p->p_fd;
214
        struct uio auio;
215
        register struct iovec *iov;
216
        struct iovec *needfree;
217
        struct iovec aiov[UIO_SMALLIOV];
218
        long i, cnt, error = 0;
219
        u_int iovlen;
220
#ifdef KTRACE
221
        struct iovec *ktriov = NULL;
222
#endif
223
 
224
        if (((u_int)SCARG(uap, fd)) >= fdp->fd_nfiles ||
225
            (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL ||
226
            (fp->f_flag & FREAD) == 0)
227
                return (EBADF);
228
        if (SCARG(uap, iovcnt) <= 0)
229
                return (EINVAL);
230
        /* note: can't use iovlen until iovcnt is validated */
231
        iovlen = SCARG(uap, iovcnt) * sizeof (struct iovec);
232
        if (SCARG(uap, iovcnt) > UIO_SMALLIOV) {
233
                if (SCARG(uap, iovcnt) > IOV_MAX)
234
                        return (EINVAL);
235
                MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
236
                needfree = iov;
237
        } else {
238
                iov = aiov;
239
                needfree = NULL;
240
        }
241
        auio.uio_iov = iov;
242
        auio.uio_iovcnt = SCARG(uap, iovcnt);
243
        auio.uio_rw = UIO_READ;
244
        auio.uio_segflg = UIO_USERSPACE;
245
        auio.uio_procp = p;
246
        error = copyin((caddr_t)SCARG(uap, iovp), (caddr_t)iov, iovlen);
247
        if (error)
248
                goto done;
249
        auio.uio_resid = 0;
250
        for (i = 0; i < SCARG(uap, iovcnt); i++, iov++) {
251
                /* Don't allow sum > SSIZE_MAX */
252
                if (iov->iov_len > SSIZE_MAX ||
253
                    (auio.uio_resid += iov->iov_len) > SSIZE_MAX) {
254
                        error = EINVAL;
255
                        goto done;
256
                }
257
        }
258
#ifdef KTRACE
259
        /*
260
         * if tracing, save a copy of iovec
261
         */
262
        if (KTRPOINT(p, KTR_GENIO))  {
263
                MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
264
                bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
265
        }
266
#endif
267
        cnt = auio.uio_resid;
268
        error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred);
269
        if (error)
270
                if (auio.uio_resid != cnt && (error == ERESTART ||
271
                    error == EINTR || error == EWOULDBLOCK))
272
                        error = 0;
273
        cnt -= auio.uio_resid;
274
#ifdef KTRACE
275
        if (ktriov != NULL) {
276
                if (error == 0)
277
                        ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_READ, ktriov,
278
                            cnt, error);
279
                FREE(ktriov, M_TEMP);
280
        }
281
#endif
282
        *retval = cnt;
283
done:
284
        if (needfree)
285
                FREE(needfree, M_IOV);
286
        return (error);
287
}
288
#endif
289
 
290
/*
291
 * Write system call
292
 */
293
#ifdef __ECOS
294
int
295
sys_write(struct sys_write_args *uap, register_t *retval)
296
#else
297
int
298
sys_write(p, v, retval)
299
        struct proc *p;
300
        void *v;
301
        register_t *retval;
302
#endif
303
{
304
#ifndef __ECOS
305
        register struct sys_write_args /* {
306
                syscallarg(int) fd;
307
                syscallarg(void *) buf;
308
                syscallarg(size_t) nbyte;
309
        } */ *uap = v;
310
        register struct filedesc *fdp = p->p_fd;
311
#endif
312
        struct file *fp;
313
        struct uio auio;
314
        struct iovec aiov;
315
        long cnt, error = 0;
316
#ifdef KTRACE
317
        struct iovec ktriov;
318
#endif
319
 
320
#ifdef __ECOS
321
        if (getfp((u_int)SCARG(uap, fd), &fp) ||
322
#else
323
        if (((u_int)SCARG(uap, fd)) >= fdp->fd_nfiles ||
324
            (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL ||
325
#endif
326
            (fp->f_flag & FWRITE) == 0)
327
                return (EBADF);
328
        /* Don't allow nbyte to be larger than max return val */
329
        if (SCARG(uap, nbyte) > SSIZE_MAX)
330
                return(EINVAL);
331
        aiov.iov_base = (caddr_t)SCARG(uap, buf);
332
        aiov.iov_len = SCARG(uap, nbyte);
333
        auio.uio_iov = &aiov;
334
        auio.uio_iovcnt = 1;
335
        auio.uio_resid = SCARG(uap, nbyte);
336
        auio.uio_rw = UIO_WRITE;
337
        auio.uio_segflg = UIO_USERSPACE;
338
#ifndef __ECOS
339
        auio.uio_procp = p;
340
#endif
341
#ifdef KTRACE
342
        /*
343
         * if tracing, save a copy of iovec
344
         */
345
        if (KTRPOINT(p, KTR_GENIO))
346
                ktriov = aiov;
347
#endif
348
        cnt = SCARG(uap, nbyte);
349
#ifdef __ECOS
350
        error = (*fp->f_ops->fo_write)(fp, &auio);
351
#else
352
        error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred);
353
#endif
354
        if (error) {
355
#ifdef __ECOS
356
                if (auio.uio_resid != cnt &&
357
                    (error == EINTR || error == EWOULDBLOCK))
358
                        error = 0;
359
#else
360
                if (auio.uio_resid != cnt && (error == ERESTART ||
361
                    error == EINTR || error == EWOULDBLOCK))
362
                        error = 0;
363
                if (error == EPIPE)
364
                        psignal(p, SIGPIPE);
365
#endif
366
        }
367
        cnt -= auio.uio_resid;
368
#ifdef KTRACE
369
        if (KTRPOINT(p, KTR_GENIO) && error == 0)
370
                ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_WRITE,
371
                    &ktriov, cnt, error);
372
#endif
373
        *retval = cnt;
374
        return (error);
375
}
376
 
377
#ifndef __ECOS
378
/*
379
 * Gather write system call
380
 */
381
int
382
sys_writev(p, v, retval)
383
        struct proc *p;
384
        void *v;
385
        register_t *retval;
386
{
387
        register struct sys_writev_args /* {
388
                syscallarg(int) fd;
389
                syscallarg(struct iovec *) iovp;
390
                syscallarg(int) iovcnt;
391
        } */ *uap = v;
392
        register struct file *fp;
393
        register struct filedesc *fdp = p->p_fd;
394
        struct uio auio;
395
        register struct iovec *iov;
396
        struct iovec *needfree;
397
        struct iovec aiov[UIO_SMALLIOV];
398
        long i, cnt, error = 0;
399
        u_int iovlen;
400
#ifdef KTRACE
401
        struct iovec *ktriov = NULL;
402
#endif
403
 
404
        if (((u_int)SCARG(uap, fd)) >= fdp->fd_nfiles ||
405
            (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL ||
406
            (fp->f_flag & FWRITE) == 0)
407
                return (EBADF);
408
        if (SCARG(uap, iovcnt) <= 0)
409
                return (EINVAL);
410
        /* note: can't use iovlen until iovcnt is validated */
411
        iovlen = SCARG(uap, iovcnt) * sizeof (struct iovec);
412
        if (SCARG(uap, iovcnt) > UIO_SMALLIOV) {
413
                if (SCARG(uap, iovcnt) > IOV_MAX)
414
                        return (EINVAL);
415
                MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
416
                needfree = iov;
417
        } else {
418
                iov = aiov;
419
                needfree = NULL;
420
        }
421
        auio.uio_iov = iov;
422
        auio.uio_iovcnt = SCARG(uap, iovcnt);
423
        auio.uio_rw = UIO_WRITE;
424
        auio.uio_segflg = UIO_USERSPACE;
425
        auio.uio_procp = p;
426
        error = copyin((caddr_t)SCARG(uap, iovp), (caddr_t)iov, iovlen);
427
        if (error)
428
                goto done;
429
        auio.uio_resid = 0;
430
        for (i = 0; i < SCARG(uap, iovcnt); i++, iov++) {
431
                /* Don't allow sum > SSIZE_MAX */
432
                if (iov->iov_len > SSIZE_MAX ||
433
                    (auio.uio_resid += iov->iov_len) > SSIZE_MAX) {
434
                        error = EINVAL;
435
                        goto done;
436
                }
437
        }
438
#ifdef KTRACE
439
        /*
440
         * if tracing, save a copy of iovec
441
         */
442
        if (KTRPOINT(p, KTR_GENIO))  {
443
                MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
444
                bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
445
        }
446
#endif
447
        cnt = auio.uio_resid;
448
        error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred);
449
        if (error) {
450
                if (auio.uio_resid != cnt && (error == ERESTART ||
451
                    error == EINTR || error == EWOULDBLOCK))
452
                        error = 0;
453
                if (error == EPIPE)
454
                        psignal(p, SIGPIPE);
455
        }
456
        cnt -= auio.uio_resid;
457
#ifdef KTRACE
458
        if (ktriov != NULL) {
459
                if (error == 0)
460
                        ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_WRITE,
461
                                ktriov, cnt, error);
462
                FREE(ktriov, M_TEMP);
463
        }
464
#endif
465
        *retval = cnt;
466
done:
467
        if (needfree)
468
                FREE(needfree, M_IOV);
469
        return (error);
470
}
471
#endif
472
 
473
/*
474
 * Ioctl system call
475
 */
476
#ifdef __ECOS
477
int
478
sys_ioctl(struct sys_ioctl_args *uap, register_t *retval)
479
#else
480
/* ARGSUSED */
481
int
482
sys_ioctl(p, v, retval)
483
        struct proc *p;
484
        void *v;
485
        register_t *retval;
486
#endif
487
{
488
#ifndef __ECOS
489
        register struct sys_ioctl_args /* {
490
                syscallarg(int) fd;
491
                syscallarg(u_long) com;
492
                syscallarg(caddr_t) data;
493
        } */ *uap = v;
494
        register struct filedesc *fdp;
495
#endif
496
        int tmp;
497
        struct file *fp;
498
        register u_long com;
499
        register int error;
500
        register u_int size;
501
        caddr_t data, memp;
502
#define STK_PARAMS      128
503
        char stkbuf[STK_PARAMS];
504
 
505
#ifdef __ECOS
506
        if (getfp(SCARG(uap, fd), &fp))
507
#else
508
        fdp = p->p_fd;
509
        if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles ||
510
            (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL)
511
#endif
512
                return (EBADF);
513
 
514
        if ((fp->f_flag & (FREAD | FWRITE)) == 0)
515
                return (EBADF);
516
 
517
#ifdef __ECOS
518
        com = SCARG(uap, com);
519
#else
520
        switch (com = SCARG(uap, com)) {
521
        case FIONCLEX:
522
                fdp->fd_ofileflags[SCARG(uap, fd)] &= ~UF_EXCLOSE;
523
                return (0);
524
        case FIOCLEX:
525
                fdp->fd_ofileflags[SCARG(uap, fd)] |= UF_EXCLOSE;
526
                return (0);
527
        }
528
#endif
529
 
530
        /*
531
         * Interpret high order word to find amount of data to be
532
         * copied to/from the user's address space.
533
         */
534
        size = IOCPARM_LEN(com);
535
#ifndef __ECOS
536
        if (size > IOCPARM_MAX)
537
                return (ENOTTY);
538
#endif
539
        memp = NULL;
540
        if (size > sizeof (stkbuf)) {
541
                memp = (caddr_t)malloc((u_long)size, M_IOCTLOPS, M_WAITOK);
542
                data = memp;
543
        } else
544
                data = stkbuf;
545
        if (com&IOC_IN) {
546
                if (size) {
547
                        error = copyin(SCARG(uap, data), data, (u_int)size);
548
                        if (error) {
549
                                if (memp)
550
                                        free(memp, M_IOCTLOPS);
551
                                return (error);
552
                        }
553
                } else
554
                        *(caddr_t *)data = SCARG(uap, data);
555
        } else if ((com&IOC_OUT) && size)
556
                /*
557
                 * Zero the buffer so the user always
558
                 * gets back something deterministic.
559
                 */
560
                bzero(data, size);
561
        else if (com&IOC_VOID)
562
                *(caddr_t *)data = SCARG(uap, data);
563
 
564
        switch (com) {
565
 
566
        case FIONBIO:
567
                if ((tmp = *(int *)data) != 0)
568
                        fp->f_flag |= FNONBLOCK;
569
                else
570
                        fp->f_flag &= ~FNONBLOCK;
571
#ifdef __ECOS
572
                error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (CYG_ADDRWORD)&tmp);
573
#else
574
                error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p);
575
#endif
576
                break;
577
 
578
        case FIOASYNC:
579
                if ((tmp = *(int *)data) != 0)
580
                        fp->f_flag |= FASYNC;
581
                else
582
                        fp->f_flag &= ~FASYNC;
583
#ifdef __ECOS
584
                error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (CYG_ADDRWORD)&tmp);
585
#else
586
                error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (caddr_t)&tmp, p);
587
#endif
588
                break;
589
 
590
#ifndef __ECOS
591
        case FIOSETOWN:
592
                tmp = *(int *)data;
593
                if (fp->f_type == DTYPE_SOCKET) {
594
                        struct socket *so = (struct socket *)fp->f_data;
595
 
596
                        so->so_pgid = tmp;
597
                        so->so_siguid = p->p_cred->p_ruid;
598
                        so->so_sigeuid = p->p_ucred->cr_uid;
599
                        error = 0;
600
                        break;
601
                }
602
                if (tmp <= 0) {
603
                        tmp = -tmp;
604
                } else {
605
                        struct proc *p1 = pfind(tmp);
606
                        if (p1 == 0) {
607
                                error = ESRCH;
608
                                break;
609
                        }
610
                        tmp = p1->p_pgrp->pg_id;
611
                }
612
                error = (*fp->f_ops->fo_ioctl)
613
                        (fp, TIOCSPGRP, (caddr_t)&tmp, p);
614
                break;
615
 
616
        case FIOGETOWN:
617
                if (fp->f_type == DTYPE_SOCKET) {
618
                        error = 0;
619
                        *(int *)data = ((struct socket *)fp->f_data)->so_pgid;
620
                        break;
621
                }
622
                error = (*fp->f_ops->fo_ioctl)(fp, TIOCGPGRP, data, p);
623
                *(int *)data = -*(int *)data;
624
                break;
625
#endif
626
        default:
627
#ifdef __ECOS
628
                error = (*fp->f_ops->fo_ioctl)(fp, com, (CYG_ADDRWORD)data);
629
#else
630
                error = (*fp->f_ops->fo_ioctl)(fp, com, data, p);
631
#endif
632
                /*
633
                 * Copy any data to user, size was
634
                 * already set and checked above.
635
                 */
636
                if (error == 0 && (com&IOC_OUT) && size)
637
                        error = copyout(data, SCARG(uap, data), (u_int)size);
638
                break;
639
        }
640
        if (memp)
641
                free(memp, M_IOCTLOPS);
642
        return (error);
643
}
644
 
645
#ifndef __ECOS
646
int     selwait, nselcoll;
647
 
648
/*
649
 * Select system call.
650
 */
651
int
652
sys_select(p, v, retval)
653
        register struct proc *p;
654
        void *v;
655
        register_t *retval;
656
{
657
        register struct sys_select_args /* {
658
                syscallarg(int) nd;
659
                syscallarg(fd_set *) in;
660
                syscallarg(fd_set *) ou;
661
                syscallarg(fd_set *) ex;
662
                syscallarg(struct timeval *) tv;
663
        } */ *uap = v;
664
        fd_set bits[6], *pibits[3], *pobits[3];
665
        struct timeval atv;
666
        int s, ncoll, error = 0, timo;
667
        u_int ni;
668
 
669
        if (SCARG(uap, nd) > p->p_fd->fd_nfiles) {
670
                /* forgiving; slightly wrong */
671
                SCARG(uap, nd) = p->p_fd->fd_nfiles;
672
        }
673
        ni = howmany(SCARG(uap, nd), NFDBITS) * sizeof(fd_mask);
674
        if (SCARG(uap, nd) > FD_SETSIZE) {
675
                caddr_t mbits;
676
 
677
                if ((mbits = malloc(ni * 6, M_TEMP, M_WAITOK)) == NULL) {
678
                        error = EINVAL;
679
                        goto cleanup;
680
                }
681
                bzero(mbits, ni * 6);
682
                pibits[0] = (fd_set *)&mbits[ni * 0];
683
                pibits[1] = (fd_set *)&mbits[ni * 1];
684
                pibits[2] = (fd_set *)&mbits[ni * 2];
685
                pobits[0] = (fd_set *)&mbits[ni * 3];
686
                pobits[1] = (fd_set *)&mbits[ni * 4];
687
                pobits[2] = (fd_set *)&mbits[ni * 5];
688
        } else {
689
                bzero((caddr_t)bits, sizeof(bits));
690
                pibits[0] = &bits[0];
691
                pibits[1] = &bits[1];
692
                pibits[2] = &bits[2];
693
                pobits[0] = &bits[3];
694
                pobits[1] = &bits[4];
695
                pobits[2] = &bits[5];
696
        }
697
 
698
#define getbits(name, x) \
699
        if (SCARG(uap, name) && (error = copyin((caddr_t)SCARG(uap, name), \
700
            (caddr_t)pibits[x], ni))) \
701
                goto done;
702
        getbits(in, 0);
703
        getbits(ou, 1);
704
        getbits(ex, 2);
705
#undef  getbits
706
 
707
        if (SCARG(uap, tv)) {
708
                error = copyin((caddr_t)SCARG(uap, tv), (caddr_t)&atv,
709
                        sizeof (atv));
710
                if (error)
711
                        goto done;
712
                if (itimerfix(&atv)) {
713
                        error = EINVAL;
714
                        goto done;
715
                }
716
                s = splclock();
717
                timeradd(&atv, &time, &atv);
718
                timo = hzto(&atv);
719
                /*
720
                 * Avoid inadvertently sleeping forever.
721
                 */
722
                if (timo == 0)
723
                        timo = 1;
724
                splx(s);
725
        } else
726
                timo = 0;
727
retry:
728
        ncoll = nselcoll;
729
        p->p_flag |= P_SELECT;
730
        error = selscan(p, pibits[0], pobits[0], SCARG(uap, nd), retval);
731
        if (error || *retval)
732
                goto done;
733
        s = splhigh();
734
        /* this should be timercmp(&time, &atv, >=) */
735
        if (SCARG(uap, tv) && (time.tv_sec > atv.tv_sec ||
736
            (time.tv_sec == atv.tv_sec && time.tv_usec >= atv.tv_usec))) {
737
                splx(s);
738
                goto done;
739
        }
740
        if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) {
741
                splx(s);
742
                goto retry;
743
        }
744
        p->p_flag &= ~P_SELECT;
745
        error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "select", timo);
746
        splx(s);
747
        if (error == 0)
748
                goto retry;
749
done:
750
        p->p_flag &= ~P_SELECT;
751
        /* select is not restarted after signals... */
752
        if (error == ERESTART)
753
                error = EINTR;
754
        if (error == EWOULDBLOCK)
755
                error = 0;
756
#define putbits(name, x) \
757
        if (SCARG(uap, name) && (error2 = copyout((caddr_t)pobits[x], \
758
            (caddr_t)SCARG(uap, name), ni))) \
759
                error = error2;
760
        if (error == 0) {
761
                int error2;
762
 
763
                putbits(in, 0);
764
                putbits(ou, 1);
765
                putbits(ex, 2);
766
#undef putbits
767
        }
768
 
769
cleanup:
770
        if (pibits[0] != &bits[0])
771
                free(pibits[0], M_TEMP);
772
        return (error);
773
}
774
 
775
int
776
selscan(p, ibits, obits, nfd, retval)
777
        struct proc *p;
778
        fd_set *ibits, *obits;
779
        int nfd;
780
        register_t *retval;
781
{
782
        caddr_t cibits = (caddr_t)ibits, cobits = (caddr_t)obits;
783
        register struct filedesc *fdp = p->p_fd;
784
        register int msk, i, j, fd;
785
        register fd_mask bits;
786
        struct file *fp;
787
        int ni, n = 0;
788
        static int flag[3] = { FREAD, FWRITE, 0 };
789
 
790
        /*
791
         * if nfd > FD_SETSIZE then the fd_set's contain nfd bits (rounded
792
         * up to the next byte) otherwise the fd_set's are normal sized.
793
         */
794
        ni = sizeof(fd_set);
795
        if (nfd > FD_SETSIZE)
796
                ni = howmany(nfd, NFDBITS) * sizeof(fd_mask);
797
 
798
        for (msk = 0; msk < 3; msk++) {
799
                fd_set *pibits = (fd_set *)&cibits[msk*ni];
800
                fd_set *pobits = (fd_set *)&cobits[msk*ni];
801
 
802
                for (i = 0; i < nfd; i += NFDBITS) {
803
                        bits = pibits->fds_bits[i/NFDBITS];
804
                        while ((j = ffs(bits)) && (fd = i + --j) < nfd) {
805
                                bits &= ~(1 << j);
806
                                fp = fdp->fd_ofiles[fd];
807
                                if (fp == NULL)
808
                                        return (EBADF);
809
                                if ((*fp->f_ops->fo_select)(fp, flag[msk], p)) {
810
                                        FD_SET(fd, pobits);
811
                                        n++;
812
                                }
813
                        }
814
                }
815
        }
816
        *retval = n;
817
        return (0);
818
}
819
 
820
/*ARGSUSED*/
821
int
822
seltrue(dev, flag, p)
823
        dev_t dev;
824
        int flag;
825
        struct proc *p;
826
{
827
 
828
        return (1);
829
}
830
 
831
/*
832
 * Record a select request.
833
 */
834
void
835
selrecord(selector, sip)
836
        struct proc *selector;
837
        struct selinfo *sip;
838
{
839
        struct proc *p;
840
        pid_t mypid;
841
 
842
        mypid = selector->p_pid;
843
        if (sip->si_selpid == mypid)
844
                return;
845
        if (sip->si_selpid && (p = pfind(sip->si_selpid)) &&
846
            p->p_wchan == (caddr_t)&selwait)
847
                sip->si_flags |= SI_COLL;
848
        else
849
                sip->si_selpid = mypid;
850
}
851
 
852
/*
853
 * Do a wakeup when a selectable event occurs.
854
 */
855
void
856
selwakeup(sip)
857
        register struct selinfo *sip;
858
{
859
        register struct proc *p;
860
        int s;
861
 
862
        if (sip->si_selpid == 0)
863
                return;
864
        if (sip->si_flags & SI_COLL) {
865
                nselcoll++;
866
                sip->si_flags &= ~SI_COLL;
867
                wakeup((caddr_t)&selwait);
868
        }
869
        p = pfind(sip->si_selpid);
870
        sip->si_selpid = 0;
871
        if (p != NULL) {
872
                s = splhigh();
873
                if (p->p_wchan == (caddr_t)&selwait) {
874
                        if (p->p_stat == SSLEEP)
875
                                setrunnable(p);
876
                        else
877
                                unsleep(p);
878
                } else if (p->p_flag & P_SELECT)
879
                        p->p_flag &= ~P_SELECT;
880
                splx(s);
881
        }
882
}
883
 
884
void
885
pollscan(p, pl, nfd, retval)
886
        struct proc *p;
887
        struct pollfd *pl;
888
        int nfd;
889
        register_t *retval;
890
{
891
        register struct filedesc *fdp = p->p_fd;
892
        register int msk, i;
893
        struct file *fp;
894
        int x, n = 0;
895
        static int flag[3] = { FREAD, FWRITE, 0 };
896
        static int pflag[3] = { POLLIN|POLLRDNORM, POLLOUT, POLLERR };
897
 
898
        /*
899
         * XXX: We need to implement the rest of the flags.
900
         */
901
        for (i = 0; i < nfd; i++) {
902
                /* Check the file descriptor. */
903
                if (pl[i].fd < 0)
904
                        continue;
905
                if (pl[i].fd >= fdp->fd_nfiles) {
906
                        pl[i].revents = POLLNVAL;
907
                        n++;
908
                        continue;
909
                }
910
 
911
                fp = fdp->fd_ofiles[pl[i].fd];
912
                if (fp == NULL) {
913
                        pl[i].revents = POLLNVAL;
914
                        n++;
915
                        continue;
916
                }
917
                for (x = msk = 0; msk < 3; msk++) {
918
                        if (pl[i].events & pflag[msk]) {
919
                                if ((*fp->f_ops->fo_select)(fp, flag[msk], p)) {
920
                                        pl[i].revents |= pflag[msk] &
921
                                            pl[i].events;
922
                                        x++;
923
                                }
924
                        }
925
                }
926
                if (x)
927
                        n++;
928
        }
929
        *retval = n;
930
}
931
 
932
/*
933
 * We are using the same mechanism as select only we encode/decode args
934
 * differently.
935
 */
936
int
937
sys_poll(p, v, retval)
938
        register struct proc *p;
939
        void *v;
940
        register_t *retval;
941
{
942
        struct sys_poll_args *uap = v;
943
        size_t sz;
944
        struct pollfd pfds[4], *pl = pfds;
945
        int msec = SCARG(uap, timeout);
946
        struct timeval atv;
947
        int timo, ncoll, i, s, error, error2;
948
        extern int nselcoll, selwait;
949
 
950
        /* Standards say no more than MAX_OPEN; this is possibly better. */
951
        if (SCARG(uap, nfds) > min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur,
952
            maxfiles))
953
                return (EINVAL);
954
 
955
        sz = sizeof(struct pollfd) * SCARG(uap, nfds);
956
 
957
        /* optimize for the default case, of a small nfds value */
958
        if (sz > sizeof(pfds))
959
                pl = (struct pollfd *) malloc(sz, M_TEMP, M_WAITOK);
960
 
961
        if ((error = copyin(SCARG(uap, fds), pl, sz)) != 0)
962
                goto bad;
963
 
964
        for (i = 0; i < SCARG(uap, nfds); i++)
965
                pl[i].revents = 0;
966
 
967
        if (msec != -1) {
968
                atv.tv_sec = msec / 1000;
969
                atv.tv_usec = (msec - (atv.tv_sec * 1000)) * 1000;
970
 
971
                if (itimerfix(&atv)) {
972
                        error = EINVAL;
973
                        goto done;
974
                }
975
                s = splclock();
976
                timeradd(&atv, &time, &atv);
977
                timo = hzto(&atv);
978
                /*
979
                 * Avoid inadvertently sleeping forever.
980
                 */
981
                if (timo == 0)
982
                        timo = 1;
983
                splx(s);
984
        } else
985
                timo = 0;
986
 
987
retry:
988
        ncoll = nselcoll;
989
        p->p_flag |= P_SELECT;
990
        pollscan(p, pl, SCARG(uap, nfds), retval);
991
        if (*retval)
992
                goto done;
993
        s = splhigh();
994
        if (timo && timercmp(&time, &atv, >=)) {
995
                splx(s);
996
                goto done;
997
        }
998
        if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) {
999
                splx(s);
1000
                goto retry;
1001
        }
1002
        p->p_flag &= ~P_SELECT;
1003
        error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "poll", timo);
1004
        splx(s);
1005
        if (error == 0)
1006
                goto retry;
1007
 
1008
done:
1009
        p->p_flag &= ~P_SELECT;
1010
        /* poll is not restarted after signals... */
1011
        if (error == ERESTART)
1012
                error = EINTR;
1013
        if (error == EWOULDBLOCK)
1014
                error = 0;
1015
        if ((error2 = copyout(pl, SCARG(uap, fds), sz)) != 0)
1016
                error = error2;
1017
bad:
1018
        if (pl != pfds)
1019
                free((char *) pl, M_TEMP);
1020
        return (error);
1021
}
1022
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.