forked from runshenzhu/6.828-MIT-OS
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsockets.c
132 lines (115 loc) · 2.3 KB
/
sockets.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include <inc/lib.h>
#include <lwip/sockets.h>
static ssize_t devsock_read(struct Fd *fd, void *buf, size_t n);
static ssize_t devsock_write(struct Fd *fd, const void *buf, size_t n);
static int devsock_close(struct Fd *fd);
static int devsock_stat(struct Fd *fd, struct Stat *stat);
struct Dev devsock =
{
.dev_id = 's',
.dev_name = "sock",
.dev_read = devsock_read,
.dev_write = devsock_write,
.dev_close = devsock_close,
.dev_stat = devsock_stat,
};
static int
fd2sockid(int fd)
{
struct Fd *sfd;
int r;
if ((r = fd_lookup(fd, &sfd)) < 0)
return r;
if (sfd->fd_dev_id != devsock.dev_id)
return -E_NOT_SUPP;
return sfd->fd_sock.sockid;
}
static int
alloc_sockfd(int sockid)
{
struct Fd *sfd;
int r;
if ((r = fd_alloc(&sfd)) < 0
|| (r = sys_page_alloc(0, sfd, PTE_P|PTE_W|PTE_U|PTE_SHARE)) < 0) {
nsipc_close(sockid);
return r;
}
sfd->fd_dev_id = devsock.dev_id;
sfd->fd_omode = O_RDWR;
sfd->fd_sock.sockid = sockid;
return fd2num(sfd);
}
int
accept(int s, struct sockaddr *addr, socklen_t *addrlen)
{
int r;
if ((r = fd2sockid(s)) < 0)
return r;
if ((r = nsipc_accept(r, addr, addrlen)) < 0)
return r;
return alloc_sockfd(r);
}
int
bind(int s, struct sockaddr *name, socklen_t namelen)
{
int r;
if ((r = fd2sockid(s)) < 0)
return r;
return nsipc_bind(r, name, namelen);
}
int
shutdown(int s, int how)
{
int r;
if ((r = fd2sockid(s)) < 0)
return r;
return nsipc_shutdown(r, how);
}
static int
devsock_close(struct Fd *fd)
{
if (pageref(fd) == 1)
return nsipc_close(fd->fd_sock.sockid);
else
return 0;
}
int
connect(int s, const struct sockaddr *name, socklen_t namelen)
{
int r;
if ((r = fd2sockid(s)) < 0)
return r;
return nsipc_connect(r, name, namelen);
}
int
listen(int s, int backlog)
{
int r;
if ((r = fd2sockid(s)) < 0)
return r;
return nsipc_listen(r, backlog);
}
static ssize_t
devsock_read(struct Fd *fd, void *buf, size_t n)
{
return nsipc_recv(fd->fd_sock.sockid, buf, n, 0);
}
static ssize_t
devsock_write(struct Fd *fd, const void *buf, size_t n)
{
return nsipc_send(fd->fd_sock.sockid, buf, n, 0);
}
static int
devsock_stat(struct Fd *fd, struct Stat *stat)
{
strcpy(stat->st_name, "<sock>");
return 0;
}
int
socket(int domain, int type, int protocol)
{
int r;
if ((r = nsipc_socket(domain, type, protocol)) < 0)
return r;
return alloc_sockfd(r);
}