Subject: bug#26341: [PATCH 2/5] build: syscalls: Allow use to network-interface syscalls independently of calling context.

From: Mathieu Othacehe <[email-masked]>
Date: Sat, 8 Apr 2017 18:03:26 +0200

* guix/build/syscalls.scm (network-interface-flags): Use static-or-ffi macro
  and add to #:replace list.
(set-network-interface-flags): Ditto.
(set-network-interface-address): Ditto.
(IFF_UP, IFF_BROADCAST and IFF_LOOPBACK): Move from #:export to #:replace.
---
 guix/build/syscalls.scm | 123 ++++++++++++++++++++++++++----------------------
 1 file changed, 66 insertions(+), 57 deletions(-)

diff --git a/guix/build/syscalls.scm b/guix/build/syscalls.scm
index af5ec4b6a..6afbfb86e 100644
--- a/guix/build/syscalls.scm
+++ b/guix/build/syscalls.scm
@@ -84,17 +84,11 @@
 
             PF_PACKET
             AF_PACKET
-            IFF_UP
-            IFF_BROADCAST
-            IFF_LOOPBACK
             all-network-interface-names
             network-interface-names
-            network-interface-flags
             network-interface-netmask
             loopback-network-interface?
             network-interface-address
-            set-network-interface-flags
-            set-network-interface-address
             set-network-interface-netmask
             set-network-interface-up
             configure-network-interface
@@ -153,7 +147,13 @@
              RB_POWER_OFF
              RB_SW_SUSPEND
              RB_KEXEC
-             reboot))
+             reboot
+             IFF_UP
+             IFF_BROADCAST
+             IFF_LOOPBACK
+             network-interface-flags
+             set-network-interface-flags
+             set-network-interface-address))
 
 ;;; Commentary:
 ;;;
@@ -1066,26 +1066,29 @@ that are not up."
                 (else
                  (loop interfaces))))))))
 
-(define (network-interface-flags socket name)
-  "Return a number that is the bit-wise or of 'IFF*' flags for network
+(define network-interface-flags
+  (static-or-ffi
+   'network-interface-flags
+   (lambda (socket name)
+     "Return a number that is the bit-wise or of 'IFF*' flags for network
 interface NAME."
-  (let ((req (make-bytevector ifreq-struct-size)))
-    (bytevector-copy! (string->utf8 name) 0 req 0
-                      (min (string-length name) (- IF_NAMESIZE 1)))
-    (let-values (((ret err)
-                  (%ioctl (fileno socket) SIOCGIFFLAGS
-                          (bytevector->pointer req))))
-      (if (zero? ret)
-
-          ;; The 'ifr_flags' field is IF_NAMESIZE bytes after the beginning of
-          ;; 'struct ifreq', and it's a short int.
-          (bytevector-sint-ref req IF_NAMESIZE (native-endianness)
-                               (sizeof short))
-
-          (throw 'system-error "network-interface-flags"
-                 "network-interface-flags on ~A: ~A"
-                 (list name (strerror err))
-                 (list err))))))
+     (let ((req (make-bytevector ifreq-struct-size)))
+       (bytevector-copy! (string->utf8 name) 0 req 0
+                         (min (string-length name) (- IF_NAMESIZE 1)))
+       (let-values (((ret err)
+                     (%ioctl (fileno socket) SIOCGIFFLAGS
+                             (bytevector->pointer req))))
+         (if (zero? ret)
+
+             ;; The 'ifr_flags' field is IF_NAMESIZE bytes after the
+             ;; beginning of 'struct ifreq', and it's a short int.
+             (bytevector-sint-ref req IF_NAMESIZE (native-endianness)
+                                  (sizeof short))
+
+             (throw 'system-error "network-interface-flags"
+                    "network-interface-flags on ~A: ~A"
+                    (list name (strerror err))
+                    (list err))))))))
 
 (define (loopback-network-interface? name)
   "Return true if NAME designates a loopback network interface."
@@ -1094,38 +1097,44 @@ interface NAME."
     (close-port sock)
     (not (zero? (logand flags IFF_LOOPBACK)))))
 
-(define (set-network-interface-flags socket name flags)
-  "Set the flag of network interface NAME to FLAGS."
-  (let ((req (make-bytevector ifreq-struct-size)))
-    (bytevector-copy! (string->utf8 name) 0 req 0
-                      (min (string-length name) (- IF_NAMESIZE 1)))
-    ;; Set the 'ifr_flags' field.
-    (bytevector-uint-set! req IF_NAMESIZE flags (native-endianness)
-                          (sizeof short))
-    (let-values (((ret err)
-                  (%ioctl (fileno socket) SIOCSIFFLAGS
-                          (bytevector->pointer req))))
-      (unless (zero? ret)
-        (throw 'system-error "set-network-interface-flags"
-               "set-network-interface-flags on ~A: ~A"
-               (list name (strerror err))
-               (list err))))))
+(define set-network-interface-flags
+  (static-or-ffi
+   'set-network-interface-flags
+   (lambda (socket name flags)
+     "Set the flag of network interface NAME to FLAGS."
+     (let ((req (make-bytevector ifreq-struct-size)))
+       (bytevector-copy! (string->utf8 name) 0 req 0
+                         (min (string-length name) (- IF_NAMESIZE 1)))
+       ;; Set the 'ifr_flags' field.
+       (bytevector-uint-set! req IF_NAMESIZE flags (native-endianness)
+                             (sizeof short))
+       (let-values (((ret err)
+                     (%ioctl (fileno socket) SIOCSIFFLAGS
+                             (bytevector->pointer req))))
+         (unless (zero? ret)
+           (throw 'system-error "set-network-interface-flags"
+                  "set-network-interface-flags on ~A: ~A"
+                  (list name (strerror err))
+                  (list err))))))))
 
-(define (set-network-interface-address socket name sockaddr)
-  "Set the address of network interface NAME to SOCKADDR."
-  (let ((req (make-bytevector ifreq-struct-size)))
-    (bytevector-copy! (string->utf8 name) 0 req 0
-                      (min (string-length name) (- IF_NAMESIZE 1)))
-    ;; Set the 'ifr_addr' field.
-    (write-socket-address! sockaddr req IF_NAMESIZE)
-    (let-values (((ret err)
-                  (%ioctl (fileno socket) SIOCSIFADDR
-                          (bytevector->pointer req))))
-      (unless (zero? ret)
-        (throw 'system-error "set-network-interface-address"
-               "set-network-interface-address on ~A: ~A"
-               (list name (strerror err))
-               (list err))))))
+(define set-network-interface-address
+  (static-or-ffi
+   'set-network-interface-address
+   (lambda (socket name sockaddr)
+     "Set the address of network interface NAME to SOCKADDR."
+     (let ((req (make-bytevector ifreq-struct-size)))
+       (bytevector-copy! (string->utf8 name) 0 req 0
+                         (min (string-length name) (- IF_NAMESIZE 1)))
+       ;; Set the 'ifr_addr' field.
+       (write-socket-address! sockaddr req IF_NAMESIZE)
+       (let-values (((ret err)
+                     (%ioctl (fileno socket) SIOCSIFADDR
+                             (bytevector->pointer req))))
+         (unless (zero? ret)
+           (throw 'system-error "set-network-interface-address"
+                  "set-network-interface-address on ~A: ~A"
+                  (list name (strerror err))
+                  (list err))))))))
 
 (define (set-network-interface-netmask socket name sockaddr)
   "Set the network mask of interface NAME to SOCKADDR."
-- 
2.12.2