Add receive-and-decode-msg to decode multipart messages.
doc/guile-netlink.texi
| 266 | 266 | @code{deserialize} (@xref{Data Types}) | |
| 267 | 267 | @end deffn | |
| 268 | 268 | ||
| 269 | + | @deffn {Scheme Procedure} receive-and-decode-msg @var{sock} @var{decoder} @ | |
| 270 | + | [#:@var{addr}] | |
| 271 | + | Receives one or more messages from @var{sock} from @var{addr}. this procedure | |
| 272 | + | is blocking. If not passed, @var{addr} defaults to the address of the kernel. | |
| 273 | + | This procedure returns a list of messages that were decoded using @var{decoder}. | |
| 274 | + | ||
| 275 | + | When the answer has the @code{NLM_F_MULTI} flag, this procedure decodes the next | |
| 276 | + | message, until it receives a @code{NLMSG_DONE} message. It returns the list | |
| 277 | + | of every netlink messages it received, including the @code{NLMSG_DONE}. | |
| 278 | + | @end deffn | |
| 279 | + | ||
| 269 | 280 | @node Netlink API | |
| 270 | 281 | @section Netlink API | |
| 271 | 282 |
netlink/connection.scm
| 27 | 27 | close-socket | |
| 28 | 28 | send-msg | |
| 29 | 29 | receive-msg | |
| 30 | + | receive-and-decode-msg | |
| 30 | 31 | get-addr)) | |
| 31 | 32 | ||
| 32 | 33 | (define libc (dynamic-link)) | |
… | |||
| 117 | 118 | (when (> size 0) | |
| 118 | 119 | (bytevector-copy! bv 0 answer 0 size)) | |
| 119 | 120 | answer)) | |
| 121 | + | ||
| 122 | + | (define* (receive-and-decode-msg sock decoder | |
| 123 | + | #:key (addr (get-addr AF_NETLINK 0 0))) | |
| 124 | + | (let* ((answer (receive-msg sock #:addr addr)) | |
| 125 | + | (size (bytevector-length answer))) | |
| 126 | + | (let loop ((messages '()) (pos 0)) | |
| 127 | + | (if (>= pos size) | |
| 128 | + | (let ((last-message (car messages))) | |
| 129 | + | (if (and | |
| 130 | + | (equal? (logand (message-flags last-message) NLM_F_MULTI) | |
| 131 | + | NLM_F_MULTI) | |
| 132 | + | (> (message-kind last-message) NLMSG_OVERUN)) | |
| 133 | + | (append (reverse messages) | |
| 134 | + | (receive-and-decode-msg sock decoder #:addr addr)) | |
| 135 | + | (reverse messages))) | |
| 136 | + | (let ((message (deserialize 'message decoder answer pos))) | |
| 137 | + | (loop (cons message messages) | |
| 138 | + | (+ (data-size message) pos))))))) | |