akaros/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/bind.c
<<
>>
Prefs
   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 <sys/plan9_helpers.h>
  27
  28/* Give the socket FD the local address ADDR (which is LEN bytes long).  */
  29int __bind(int fd, __CONST_SOCKADDR_ARG addr, socklen_t alen)
  30{
  31        int n;
  32        socklen_t len;
  33        Rock *r;
  34        char msg[128];
  35        struct sockaddr_in *lip;
  36
  37        /* assign the address */
  38        r = _sock_findrock(fd, 0);
  39        if (r == 0) {
  40                errno = ENOTSOCK;
  41                return -1;
  42        }
  43        if (alen > sizeof(r->addr_stor)) {
  44                errno = ENAMETOOLONG;
  45                return -1;
  46        }
  47        memmove(&r->addr, addr.__sockaddr__, alen);
  48
  49        /* the rest is IP sepecific */
  50        if (r->domain != PF_INET)
  51                return 0;
  52
  53        lip = (struct sockaddr_in *)&r->addr;
  54        if (lip->sin_port > 0)
  55                snprintf(msg, sizeof msg, "bind %d", ntohs(lip->sin_port));
  56        else
  57                strcpy(msg, "bind *");
  58        n = write(r->ctl_fd, msg, strlen(msg));
  59        if (n < 0) {
  60                errno = EOPNOTSUPP;     /* Improve error reporting!!! */
  61                return -1;
  62        }
  63        if (lip->sin_port <= 0)
  64                _sock_ingetaddr(r, lip, &len, "local");
  65        /* UDP sockets are in headers mode, and need to be announced.  This
  66         * isn't a full announce, in that the kernel UDP stack doesn't expect
  67         * someone to open the listen file or anything like that. */
  68        if ((r->domain == PF_INET) && (r->stype == SOCK_DGRAM)) {
  69                n = snprintf(msg, sizeof(msg), "announce *!%d",
  70                             ntohs(lip->sin_port));
  71                n = write(r->ctl_fd, msg, n);
  72                if (n < 0) {
  73                        perror("bind-announce failed");
  74                        return -1;
  75                }
  76        }
  77        return 0;
  78}
  79weak_alias(__bind, bind)
  80