PCI: adds device-specific data pointer
[akaros.git] / user / bsd / listen.c
1 /* 
2  * This file is part of the UCB release of Plan 9. It is subject to the license
3  * terms in the LICENSE file found in the top-level directory of this
4  * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
5  * part of the UCB release of Plan 9, including this file, may be copied,
6  * modified, propagated, or distributed except according to the terms contained
7  * in the LICENSE file.
8  */
9 /* posix */
10 #include <sys/types.h>
11 #include <unistd.h>
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <fcntl.h>
15 #include <string.h>
16 #include <errno.h>
17 #include <sys/stat.h>
18 #include <signal.h>
19
20 /* socket extensions */
21 #include <sys/uio.h>
22 #include <sys/socket.h>
23 #include <netinet/in.h>
24 #include <sys/un.h>
25
26 #include "priv.h"
27
28 int
29 listen(fd, backlog)
30         int fd;
31         int backlog;
32 {
33         Rock *r;
34         int n, cfd;
35         char msg[128];
36         struct sockaddr_in *lip;
37         struct sockaddr_un *lunix;
38
39         r = _sock_findrock(fd, 0);
40         if(r == 0){
41                 errno = ENOTSOCK;
42                 return -1;
43         }
44
45         switch(r->domain){
46         case PF_INET:
47                 cfd = open(r->ctl, O_RDWR);
48                 if(cfd < 0){
49                         errno = EBADF;
50                         return -1;
51                 }
52                 lip = (struct sockaddr_in*)&r->addr;
53                 if(lip->sin_port >= 0) {
54                         if(write(cfd, "bind 0", 6) < 0) {
55                                 errno = EINVAL; //EGREG;
56                                 close(cfd);
57                                 return -1;
58                         }
59                         snprintf(msg, sizeof msg, "announce %d",
60                                 ntohs(lip->sin_port));
61                 }
62                 else
63                         strcpy(msg, "announce *");
64                 n = write(cfd, msg, strlen(msg));
65                 if(n < 0){
66                         errno = EOPNOTSUPP;     /* Improve error reporting!!! */
67                         close(cfd);
68                         return -1;
69                 }
70                 close(cfd);
71
72                 return 0;
73
74         case PF_UNIX:
75                 if(r->other < 0){
76                         errno = EINVAL;//EGREG;
77                         return -1;
78                 }
79                 lunix = (struct sockaddr_un*)&r->addr;
80                 if(_sock_srv(lunix->sun_path, r->other) < 0){
81                         r->other = -1;
82                         return -1;
83                 }
84                 r->other = -1;
85                 return 0;
86         default:
87                 errno = EAFNOSUPPORT;
88                 return -1;
89         }
90 }