]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/compat/cloudabi/cloudabi_fd.c
Allow us to create UNIX sockets and socketpairs in CloudABI processes.
[FreeBSD/FreeBSD.git] / sys / compat / cloudabi / cloudabi_fd.c
1 /*-
2  * Copyright (c) 2015 Nuxi, https://nuxi.nl/
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  */
25
26 #include <sys/cdefs.h>
27 __FBSDID("$FreeBSD$");
28
29 #include <sys/param.h>
30 #include <sys/filedesc.h>
31 #include <sys/proc.h>
32 #include <sys/syscallsubr.h>
33 #include <sys/sysproto.h>
34 #include <sys/unistd.h>
35
36 #include <compat/cloudabi/cloudabi_proto.h>
37
38 int
39 cloudabi_sys_fd_close(struct thread *td, struct cloudabi_sys_fd_close_args *uap)
40 {
41
42         return (kern_close(td, uap->fd));
43 }
44
45 int
46 cloudabi_sys_fd_create1(struct thread *td,
47     struct cloudabi_sys_fd_create1_args *uap)
48 {
49         struct socket_args socket_args = {
50                 .domain = AF_UNIX,
51         };
52
53         switch (uap->type) {
54         case CLOUDABI_FILETYPE_SOCKET_DGRAM:
55                 socket_args.type = SOCK_DGRAM;
56                 return (sys_socket(td, &socket_args));
57         case CLOUDABI_FILETYPE_SOCKET_SEQPACKET:
58                 socket_args.type = SOCK_SEQPACKET;
59                 return (sys_socket(td, &socket_args));
60         case CLOUDABI_FILETYPE_SOCKET_STREAM:
61                 socket_args.type = SOCK_STREAM;
62                 return (sys_socket(td, &socket_args));
63         default:
64                 return (EINVAL);
65         }
66 }
67
68 int
69 cloudabi_sys_fd_create2(struct thread *td,
70     struct cloudabi_sys_fd_create2_args *uap)
71 {
72         int fds[2];
73         int error;
74
75         switch (uap->type) {
76         case CLOUDABI_FILETYPE_SOCKET_DGRAM:
77                 error = kern_socketpair(td, AF_UNIX, SOCK_DGRAM, 0, fds);
78                 break;
79         case CLOUDABI_FILETYPE_SOCKET_SEQPACKET:
80                 error = kern_socketpair(td, AF_UNIX, SOCK_SEQPACKET, 0, fds);
81                 break;
82         case CLOUDABI_FILETYPE_SOCKET_STREAM:
83                 error = kern_socketpair(td, AF_UNIX, SOCK_STREAM, 0, fds);
84                 break;
85         default:
86                 return (EINVAL);
87         }
88
89         if (error == 0) {
90                 td->td_retval[0] = fds[0];
91                 td->td_retval[1] = fds[1];
92         }
93         return (0);
94 }
95
96 int
97 cloudabi_sys_fd_datasync(struct thread *td,
98     struct cloudabi_sys_fd_datasync_args *uap)
99 {
100         struct fsync_args fsync_args = {
101                 .fd = uap->fd
102         };
103
104         /* Call into fsync(), as FreeBSD lacks fdatasync(). */
105         return (sys_fsync(td, &fsync_args));
106 }
107
108 int
109 cloudabi_sys_fd_dup(struct thread *td, struct cloudabi_sys_fd_dup_args *uap)
110 {
111
112         return (kern_dup(td, FDDUP_NORMAL, 0, uap->from, 0));
113 }
114
115 int
116 cloudabi_sys_fd_replace(struct thread *td,
117     struct cloudabi_sys_fd_replace_args *uap)
118 {
119         int error;
120
121         /*
122          * CloudABI's equivalent to dup2(). CloudABI processes should
123          * not depend on hardcoded file descriptor layouts, but simply
124          * use the file descriptor numbers that are allocated by the
125          * kernel. Duplicating file descriptors to arbitrary numbers
126          * should not be done.
127          *
128          * Invoke kern_dup() with FDDUP_MUSTREPLACE, so that we return
129          * EBADF when duplicating to a nonexistent file descriptor. Also
130          * clear the return value, as this system call yields no return
131          * value.
132          */
133         error = kern_dup(td, FDDUP_MUSTREPLACE, 0, uap->from, uap->to);
134         td->td_retval[0] = 0;
135         return (error);
136 }
137
138 int
139 cloudabi_sys_fd_seek(struct thread *td, struct cloudabi_sys_fd_seek_args *uap)
140 {
141         struct lseek_args lseek_args = {
142                 .fd     = uap->fd,
143                 .offset = uap->offset
144         };
145
146         switch (uap->whence) {
147         case CLOUDABI_WHENCE_CUR:
148                 lseek_args.whence = SEEK_CUR;
149                 break;
150         case CLOUDABI_WHENCE_END:
151                 lseek_args.whence = SEEK_END;
152                 break;
153         case CLOUDABI_WHENCE_SET:
154                 lseek_args.whence = SEEK_SET;
155                 break;
156         default:
157                 return (EINVAL);
158         }
159
160         return (sys_lseek(td, &lseek_args));
161 }
162
163 int
164 cloudabi_sys_fd_stat_get(struct thread *td,
165     struct cloudabi_sys_fd_stat_get_args *uap)
166 {
167
168         /* Not implemented. */
169         return (ENOSYS);
170 }
171
172 int
173 cloudabi_sys_fd_stat_put(struct thread *td,
174     struct cloudabi_sys_fd_stat_put_args *uap)
175 {
176
177         /* Not implemented. */
178         return (ENOSYS);
179 }
180
181 int
182 cloudabi_sys_fd_sync(struct thread *td, struct cloudabi_sys_fd_sync_args *uap)
183 {
184         struct fsync_args fsync_args = {
185                 .fd = uap->fd
186         };
187
188         return (sys_fsync(td, &fsync_args));
189 }