chiark / gitweb /
750bd709c495ac50245bc5b5f76a17cad2b218ee
[elogind.git] / klibc / klibc / inet / bindresvport.c
1 /*
2  * inet/bindresvport.c
3  */
4
5 #include <errno.h>
6 #include <sys/types.h>
7 #include <sys/socket.h>
8 #include <netinet/in.h>
9 #include <string.h>
10 #include <unistd.h>
11
12 #define START_PORT      768
13 #define END_PORT        IPPORT_RESERVED
14 #define NUM_PORTS       (END_PORT - START_PORT)
15
16 int bindresvport(int sd, struct sockaddr_in *sin)
17 {
18         struct sockaddr_in me;
19         static short port;
20         int ret = 0;
21         int i;
22
23         if (sin == NULL) {
24                 memset(&me, 0, sizeof(me));
25                 sin = &me;
26                 sin->sin_family = AF_INET;
27         } else if (sin->sin_family != AF_INET) {
28                 errno = EPFNOSUPPORT;
29                 return -1;
30         }
31         
32         if (port == 0) {
33                 port = START_PORT + (getpid() % NUM_PORTS);
34         }
35         
36         for (i = 0; i < NUM_PORTS; i++, port++) {
37                 if (port == END_PORT)
38                         port = START_PORT;
39                 sin->sin_port = htons(port);
40                 if ((ret = bind(sd, (struct sockaddr *)sin, sizeof(*sin))) != -1)
41                         break;
42         }
43
44         return ret;
45 }