cpio: Fix device number calculation.

“dev_t in glibc is a 64-bit quantity, with 32-bit major and minor
 numbers.”  — glibc's <bits/sysmacros.h>

The "tests/cpio.scm" was failing because (guix cpio) treated it as a
16-bit quantity instead, leading to header mismatches with the GNU cpio
reference output.

* guix/cpio.scm (device-number, device->major+minor): Use all the bits.
This commit is contained in:
Tobias Geerinckx-Rice 2021-07-04 04:26:01 +02:00
parent 7cde70c7f8
commit f7e1478202
No known key found for this signature in database
GPG key ID: 0DB0FF884F556D79

View file

@ -1,5 +1,6 @@
;;; GNU Guix --- Functional package management for GNU ;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2015 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2015 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2021 Tobias Geerinckx-Rice <me@tobias.gr>
;;; ;;;
;;; This file is part of GNU Guix. ;;; This file is part of GNU Guix.
;;; ;;;
@ -153,15 +154,20 @@ denotes, similar to 'stat:type'."
(else (else
(error "unsupported file type" mode))))) (error "unsupported file type" mode)))))
(define (device-number major minor) ;see <sys/sysmacros.h> (define (device-number major minor) ; see glibc's <sys/sysmacros.h>
"Return the device number for the device with MAJOR and MINOR, for use as "Return the device number for the device with MAJOR and MINOR, for use as
the last argument of `mknod'." the last argument of `mknod'."
(+ (* major 256) minor)) (logior (ash (logand #x00000fff major) 8)
(ash (logand #xfffff000 major) 32)
(logand #x000000ff minor)
(ash (logand #xffffff00 minor) 12)))
(define (device->major+minor device) (define (device->major+minor device) ; see glibc's <sys/sysmacros.h>
"Return two values: the major and minor device numbers that make up DEVICE." "Return two values: the major and minor device numbers that make up DEVICE."
(values (ash device -8) (values (logior (ash (logand #x00000000000fff00 device) -8)
(logand device #xff))) (ash (logand #xfffff00000000000 device) -32))
(logior (logand #x00000000000000ff device)
(ash (logand #x00000ffffff00000 device) -12))))
(define* (file->cpio-header file #:optional (file-name file) (define* (file->cpio-header file #:optional (file-name file)
#:key (stat lstat)) #:key (stat lstat))