aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2014-09-14 22:56:12 +0200
committerLudovic Courtès <ludo@gnu.org>2014-09-14 23:49:02 +0200
commit4d54785c69602b0714b3f9021b9bf6a5d619d40c (patch)
treed0c20e7ae64af801857c9a1ec2a69f3f3e6eee7a
parent973eea34781078091869143602d4f1dfdfd82e19 (diff)
downloadguix-4d54785c69602b0714b3f9021b9bf6a5d619d40c.tar
guix-4d54785c69602b0714b3f9021b9bf6a5d619d40c.tar.gz
syscalls: Add 'all-network-interfaces'.
* guix/build/syscalls.scm (network-interfaces): Update docstring. (%interface-line): New variable. (all-network-interfaces): New procedure. * tests/syscalls.scm ("all-network-interfaces"): New test. ("network-interfaces"): Change to make sure the result is a subset of (all-network-interfaces).
-rw-r--r--guix/build/syscalls.scm25
-rw-r--r--tests/syscalls.scm8
2 files changed, 31 insertions, 2 deletions
diff --git a/guix/build/syscalls.scm b/guix/build/syscalls.scm
index 06f69e119e..c8ec13983b 100644
--- a/guix/build/syscalls.scm
+++ b/guix/build/syscalls.scm
@@ -21,6 +21,7 @@
#:use-module (rnrs bytevectors)
#:use-module (srfi srfi-1)
#:use-module (ice-9 rdelim)
+ #:use-module (ice-9 regex)
#:use-module (ice-9 match)
#:use-module (ice-9 ftw)
#:export (errno
@@ -35,6 +36,7 @@
IFF_UP
IFF_BROADCAST
IFF_LOOPBACK
+ all-network-interfaces
network-interfaces
network-interface-flags
loopback-network-interface?))
@@ -244,7 +246,8 @@ most LEN bytes from BV."
result))))))
(define* (network-interfaces #:optional sock)
- "Return the list of existing network interfaces."
+ "Return the list of existing network interfaces. This is typically limited
+to interfaces that are currently up."
(let* ((close? (not sock))
(sock (or sock (socket SOCK_STREAM AF_INET 0)))
(len (* ifreq-struct-size 10))
@@ -264,6 +267,26 @@ most LEN bytes from BV."
(list (strerror err))
(list err)))))
+(define %interface-line
+ ;; Regexp matching an interface line in Linux's /proc/net/dev.
+ (make-regexp "^[[:blank:]]*([[:alnum:]]+): .*$"))
+
+(define (all-network-interfaces)
+ "Return all the registered network interfaces, including those that are not
+up."
+ (call-with-input-file "/proc/net/dev" ;XXX: Linux-specific
+ (lambda (port)
+ (let loop ((interfaces '()))
+ (let ((line (read-line port)))
+ (cond ((eof-object? line)
+ (reverse interfaces))
+ ((regexp-exec %interface-line line)
+ =>
+ (lambda (match)
+ (loop (cons (match:substring match 1) interfaces))))
+ (else
+ (loop interfaces))))))))
+
(define (network-interface-flags socket name)
"Return a number that is the bit-wise or of 'IFF*' flags for network
interface NAME."
diff --git a/tests/syscalls.scm b/tests/syscalls.scm
index c3550ac31a..b1dc298a14 100644
--- a/tests/syscalls.scm
+++ b/tests/syscalls.scm
@@ -18,6 +18,7 @@
(define-module (test-syscalls)
#:use-module (guix build syscalls)
+ #:use-module (srfi srfi-1)
#:use-module (srfi srfi-64)
#:use-module (ice-9 match))
@@ -43,10 +44,15 @@
;; Both return values have been encountered in the wild.
(memv (system-error-errno args) (list EPERM ENOENT)))))
+(test-assert "all-network-interfaces"
+ (match (all-network-interfaces)
+ (((? string? names) ..1)
+ (member "lo" names))))
+
(test-assert "network-interfaces"
(match (network-interfaces)
(((? string? names) ..1)
- (member "lo" names))))
+ (lset<= string=? names (all-network-interfaces)))))
(test-assert "network-interface-flags"
(let* ((sock (socket SOCK_STREAM AF_INET 0))