forked from Stichting-MINIX-Research-Foundation/minix
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsocket.c
More file actions
132 lines (114 loc) · 2.52 KB
/
Copy pathsocket.c
File metadata and controls
132 lines (114 loc) · 2.52 KB
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 <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <net/netlib.h>
#include <net/ioctl.h>
#include <netinet/in.h>
#define DEBUG 0
static int _tcp_socket(int protocol);
static int _udp_socket(int protocol);
static int _uds_socket(int type, int protocol);
int socket(int domain, int type, int protocol)
{
#if DEBUG
fprintf(stderr, "socket: domain %d, type %d, protocol %d\n",
domain, type, protocol);
#endif
if (domain != AF_INET && domain != AF_UNIX)
{
#if DEBUG
fprintf(stderr, "socket: bad domain %d\n", domain);
#endif
errno= EAFNOSUPPORT;
return -1;
}
if (domain == AF_UNIX && (type == SOCK_STREAM ||
type == SOCK_DGRAM || type == SOCK_SEQPACKET))
return _uds_socket(type, protocol);
if (domain == AF_INET && type == SOCK_STREAM)
return _tcp_socket(protocol);
if (domain == AF_INET && type == SOCK_DGRAM)
return _udp_socket(protocol);
#if DEBUG
fprintf(stderr, "socket: nothing for domain %d, type %d, protocol %d\n",
domain, type, protocol);
#endif
errno= EPROTOTYPE;
return -1;
}
static int _tcp_socket(int protocol)
{
int fd;
if (protocol != 0 && protocol != IPPROTO_TCP)
{
#if DEBUG
fprintf(stderr, "socket(tcp): bad protocol %d\n", protocol);
#endif
errno= EPROTONOSUPPORT;
return -1;
}
fd= open(TCP_DEVICE, O_RDWR);
return fd;
}
static int _udp_socket(int protocol)
{
int r, fd, t_errno;
struct sockaddr_in sin;
if (protocol != 0 && protocol != IPPROTO_UDP)
{
#if DEBUG
fprintf(stderr, "socket(udp): bad protocol %d\n", protocol);
#endif
errno= EPROTONOSUPPORT;
return -1;
}
fd= open(UDP_DEVICE, O_RDWR);
if (fd == -1)
return fd;
/* Bind is implict for UDP sockets? */
sin.sin_family= AF_INET;
sin.sin_addr.s_addr= INADDR_ANY;
sin.sin_port= 0;
r= bind(fd, (struct sockaddr *)&sin, sizeof(sin));
if (r != 0)
{
t_errno= errno;
close(fd);
errno= t_errno;
return -1;
}
return fd;
}
static int _uds_socket(int type, int protocol)
{
int fd, r;
if (protocol != 0)
{
#if DEBUG
fprintf(stderr, "socket(uds): bad protocol %d\n", protocol);
#endif
errno= EPROTONOSUPPORT;
return -1;
}
fd= open(UDS_DEVICE, O_RDWR);
if (fd == -1) {
return fd;
}
/* set the type for the socket via ioctl (SOCK_DGRAM,
* SOCK_STREAM, SOCK_SEQPACKET, etc)
*/
r= ioctl(fd, NWIOSUDSTYPE, &type);
if (r == -1) {
int ioctl_errno;
/* if that failed rollback socket creation */
ioctl_errno= errno;
close(fd);
/* return the error thrown by the call to ioctl */
errno= ioctl_errno;
return -1;
}
return fd;
}