Add shims for {get,set}sockopt() (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Tue, 21 Jul 2015 09:35:35 +0000 (05:35 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 24 Jul 2015 07:05:14 +0000 (03:05 -0400)
Only supports SOL_SOCKET->SO_TYPE for now.  Note that setsockopt() can't
change the type.

Rebuild glibc.

tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getsockopt.c
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/setsockopt.c

index b60073a..9ec252f 100644 (file)
@@ -1,34 +1,44 @@
-/* Copyright (C) 1991-2014 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
+/* Copyright (c) 2015 Google, Inc.
+ * Barret Rhoden <brho@cs.berkeley.edu>
+ * See LICENSE for details. */
 
 #include <errno.h>
 #include <sys/socket.h>
 
-/* Put the current value for socket FD's option OPTNAME at protocol level LEVEL
-   into OPTVAL (which is *OPTLEN bytes long), and set *OPTLEN to the value's
-   actual length.  Returns 0 on success, -1 for errors.  */
-int
-getsockopt (fd, level, optname, optval, optlen)
-     int fd;
-     int level;
-     int optname;
-     void *optval;
-     socklen_t *optlen;
+#include "plan9_sockets.h"
+
+static int sol_socket_gso(Rock *r, int optname, void *optval, socklen_t *optlen)
+{
+       switch (optname) {
+               case (SO_TYPE):
+                       if (*optlen < 4) {
+                               __set_errno(EINVAL);
+                               return -1;
+                       }
+                       *(int*)optval = r->stype;
+                       *optlen = 4;
+                       break;
+               default:
+                       __set_errno(ENOPROTOOPT);
+                       return -1;
+       };
+       return 0;
+}
+
+int getsockopt(int sockfd, int level, int optname, void *optval,
+               socklen_t *optlen)
 {
-       __set_errno (ENOPROTOOPT);
-       return -1;
+       Rock *r = _sock_findrock(sockfd, 0);
+       if (!r) {
+               /* could be EBADF too, we can't tell */
+               __set_errno(ENOTSOCK);
+               return -1;
+       }
+       switch (level) {
+               case (SOL_SOCKET):
+                       return sol_socket_gso(r, optname, optval, optlen);
+               default:
+                       __set_errno(ENOPROTOOPT);
+                       return -1;
+       };
 }
index e464001..7e08aa6 100644 (file)
@@ -1,36 +1,48 @@
-/* Copyright (C) 1991-2014 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
+/* Copyright (c) 2015 Google, Inc.
+ * Barret Rhoden <brho@cs.berkeley.edu>
+ * See LICENSE for details. */
 
 #include <errno.h>
 #include <sys/socket.h>
 
-/* Set socket FD's option OPTNAME at protocol level LEVEL
-   to *OPTVAL (which is OPTLEN bytes long).
-   Returns 0 on success, -1 for errors.  */
-int
-__setsockopt (fd, level, optname, optval, optlen)
-     int fd;
-     int level;
-     int optname;
-     const __ptr_t optval;
-     socklen_t optlen;
+#include "plan9_sockets.h"
+
+static int sol_socket_sso(Rock *r, int optname, void *optval, socklen_t optlen)
 {
-       __set_errno (ENOPROTOOPT);
-       return -1;
+       switch (optname) {
+               #if 0
+               /* We don't support setting any options yet */
+               case (SO_FOO):
+                       if (optlen < foo_len) {
+                               __set_errno(EINVAL);
+                               return -1;
+                       }
+                       r->foo = *optval;
+                       break;
+               #endif
+               default:
+                       __set_errno(ENOPROTOOPT);
+                       return -1;
+       };
+       return 0;
 }
 
+int __setsockopt(int sockfd, int level, int optname, const __ptr_t __optval,
+                 socklen_t optlen)
+{
+       Rock *r = _sock_findrock(sockfd, 0);
+       void *optval = (void*)__optval;
+       if (!r) {
+               /* could be EBADF too, we can't tell */
+               __set_errno(ENOTSOCK);
+               return -1;
+       }
+       switch (level) {
+               case (SOL_SOCKET):
+                       return sol_socket_sso(r, optname, optval, optlen);
+               default:
+                       __set_errno(ENOPROTOOPT);
+                       return -1;
+       };
+}
 weak_alias (__setsockopt, setsockopt)