annotate packages/net/tcpip/current/src/sys/kern/sys_generic.c @ 2729:74dbf4c3f2e1 after-copyright-change-20090129

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