xref: /plan9/sys/src/ape/lib/bsd/bind.c (revision 7e125112574862ca44c733e2ecf7b75e72c6ed0e)
1219b2ee8SDavid du Colombier /* posix */
2219b2ee8SDavid du Colombier #include <sys/types.h>
3219b2ee8SDavid du Colombier #include <unistd.h>
4219b2ee8SDavid du Colombier #include <stdlib.h>
5219b2ee8SDavid du Colombier #include <stdio.h>
6219b2ee8SDavid du Colombier #include <fcntl.h>
7219b2ee8SDavid du Colombier #include <string.h>
8219b2ee8SDavid du Colombier #include <errno.h>
9219b2ee8SDavid du Colombier #include <sys/stat.h>
10219b2ee8SDavid du Colombier #include <signal.h>
11219b2ee8SDavid du Colombier 
12219b2ee8SDavid du Colombier /* socket extensions */
13219b2ee8SDavid du Colombier #include <sys/uio.h>
14219b2ee8SDavid du Colombier #include <sys/socket.h>
15219b2ee8SDavid du Colombier #include <netinet/in.h>
16219b2ee8SDavid du Colombier #include <sys/un.h>
17219b2ee8SDavid du Colombier 
18219b2ee8SDavid du Colombier /* plan 9 */
19219b2ee8SDavid du Colombier #include "lib.h"
20219b2ee8SDavid du Colombier #include "sys9.h"
21219b2ee8SDavid du Colombier 
22219b2ee8SDavid du Colombier #include "priv.h"
23219b2ee8SDavid du Colombier 
24219b2ee8SDavid du Colombier int
bind(int fd,void * a,int alen)25219b2ee8SDavid du Colombier bind(int fd, void *a, int alen)
26219b2ee8SDavid du Colombier {
27219b2ee8SDavid du Colombier 	int n, len, cfd;
28219b2ee8SDavid du Colombier 	Rock *r;
29219b2ee8SDavid du Colombier 	char msg[128];
30219b2ee8SDavid du Colombier 	struct sockaddr_in *lip;
31219b2ee8SDavid du Colombier 
32219b2ee8SDavid du Colombier 	/* assign the address */
33219b2ee8SDavid du Colombier 	r = _sock_findrock(fd, 0);
34219b2ee8SDavid du Colombier 	if(r == 0){
35219b2ee8SDavid du Colombier 		errno = ENOTSOCK;
36219b2ee8SDavid du Colombier 		return -1;
37219b2ee8SDavid du Colombier 	}
38219b2ee8SDavid du Colombier 	if(alen > sizeof(r->addr)){
39219b2ee8SDavid du Colombier 		errno = ENAMETOOLONG;
40219b2ee8SDavid du Colombier 		return -1;
41219b2ee8SDavid du Colombier 	}
42219b2ee8SDavid du Colombier 	memmove(&r->addr, a, alen);
43219b2ee8SDavid du Colombier 
44219b2ee8SDavid du Colombier 	/* the rest is IP sepecific */
45219b2ee8SDavid du Colombier 	if (r->domain != PF_INET)
46219b2ee8SDavid du Colombier 		return 0;
47219b2ee8SDavid du Colombier 
48219b2ee8SDavid du Colombier 	cfd = open(r->ctl, O_RDWR);
49219b2ee8SDavid du Colombier 	if(cfd < 0){
50219b2ee8SDavid du Colombier 		errno = EBADF;
51219b2ee8SDavid du Colombier 		return -1;
52219b2ee8SDavid du Colombier 	}
53219b2ee8SDavid du Colombier 	lip = (struct sockaddr_in*)&r->addr;
54219b2ee8SDavid du Colombier 	if(lip->sin_port > 0)
55*7e125112SDavid du Colombier 		snprintf(msg, sizeof msg, "bind %d", ntohs(lip->sin_port));
56219b2ee8SDavid du Colombier 	else
57*7e125112SDavid du Colombier 		strcpy(msg, "bind *");
58219b2ee8SDavid du Colombier 	n = write(cfd, msg, strlen(msg));
59219b2ee8SDavid du Colombier 	if(n < 0){
60219b2ee8SDavid du Colombier 		errno = EOPNOTSUPP;	/* Improve error reporting!!! */
61219b2ee8SDavid du Colombier 		close(cfd);
62219b2ee8SDavid du Colombier 		return -1;
63219b2ee8SDavid du Colombier 	}
64219b2ee8SDavid du Colombier 	close(cfd);
65219b2ee8SDavid du Colombier 
66219b2ee8SDavid du Colombier 	if(lip->sin_port <= 0)
67219b2ee8SDavid du Colombier 		_sock_ingetaddr(r, lip, &len, "local");
68219b2ee8SDavid du Colombier 
69219b2ee8SDavid du Colombier 	return 0;
70219b2ee8SDavid du Colombier }
71