unofficial mirror of guix-patches@gnu.org 
 help / color / mirror / code / Atom feed
* [bug#57730] [PATCH] syscalls: Adjust for glibc 2.34 and later.
@ 2022-09-11 10:50 Marius Bakke
  2022-09-11 11:01 ` Marius Bakke
  2022-09-12 21:45 ` Ludovic Courtès
  0 siblings, 2 replies; 6+ messages in thread
From: Marius Bakke @ 2022-09-11 10:50 UTC (permalink / raw)
  To: 57730

This is a re-implementation of 3c8b6fd94ceb1e898216929e8768fb518dbf1de9 that
works with new and old libc's.

* guix/build/syscalls.scm (openpty, login-tty): Wrap in exception handlers and
retry with libutil if the first call is unsuccessful.
---
 guix/build/syscalls.scm | 71 ++++++++++++++++++++++++++---------------
 1 file changed, 45 insertions(+), 26 deletions(-)

diff --git a/guix/build/syscalls.scm b/guix/build/syscalls.scm
index b00615d9b7..eee90216eb 100644
--- a/guix/build/syscalls.scm
+++ b/guix/build/syscalls.scm
@@ -9,6 +9,7 @@
 ;;; Copyright © 2021 Chris Marusich <cmmarusich@gmail.com>
 ;;; Copyright © 2021 Tobias Geerinckx-Rice <me@tobias.gr>
 ;;; Copyright © 2022 Oleg Pykhalov <go.wigust@gmail.com>
+;;; Copyright © 2022 Marius Bakke <marius@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -2339,39 +2340,57 @@ (define* (terminal-rows #:optional (port (current-output-port)))
   (terminal-dimension window-size-rows port (const 25)))
 
 (define openpty
-  (let ((proc (syscall->procedure int "openpty" '(* * * * *)
-                                  #:library "libutil")))
-    (lambda ()
-      "Return two file descriptors: one for the pseudo-terminal control side,
+  (lambda* (#:optional library)
+    "Return two file descriptors: one for the pseudo-terminal control side,
 and one for the controlled side."
+    (let ((proc (syscall->procedure int "openpty" '(* * * * *)
+                                    #:library library)))
       (let ((head     (make-bytevector (sizeof int)))
             (inferior (make-bytevector (sizeof int))))
-        (let-values (((ret err)
-                      (proc (bytevector->pointer head)
-                            (bytevector->pointer inferior)
-                            %null-pointer %null-pointer %null-pointer)))
-          (unless (zero? ret)
-            (throw 'system-error "openpty" "~A"
-                   (list (strerror err))
-                   (list err))))
-
-        (let ((* (lambda (bv)
-                   (bytevector-sint-ref bv 0 (native-endianness)
-                                        (sizeof int)))))
-          (values (* head) (* inferior)))))))
+        (catch 'system-error
+          (lambda ()
+            (let-values (((ret err)
+                          (proc (bytevector->pointer head)
+                                (bytevector->pointer inferior)
+                                %null-pointer %null-pointer %null-pointer)))
+              (unless (zero? ret)
+                (throw 'system-error "openpty" "~A"
+                       (list (strerror err))
+                       (list err)))
+
+              (let ((* (lambda (bv)
+                         (bytevector-sint-ref bv 0 (native-endianness)
+                                              (sizeof int)))))
+                (values (* head) (* inferior)))))
+          (lambda args
+            (if (and (= (system-error-errno args) 38)
+                     (not library))
+                ;; Prior to glibc 2.34, openpty resided in libutil.
+                ;; Try again, fingers crossed!
+                (openpty "libutil")
+                (apply throw args))))))))
 
 (define login-tty
-  (let* ((proc (syscall->procedure int "login_tty" (list int)
-                                   #:library "libutil")))
-    (lambda (fd)
-      "Make FD the controlling terminal of the current process (with the
+  (lambda* (fd #:optional library)
+    "Make FD the controlling terminal of the current process (with the
 TIOCSCTTY ioctl), redirect standard input, standard output and standard error
 output to this terminal, and close FD."
-      (let-values (((ret err) (proc fd)))
-        (unless (zero? ret)
-          (throw 'system-error "login-pty" "~A"
-                 (list (strerror err))
-                 (list err)))))))
+    (let ((proc (syscall->procedure int "login_tty" (list int)
+                                    #:library library)))
+      (catch 'system-error
+        (lambda ()
+          (let-values (((ret err) (proc fd)))
+            (unless (zero? ret)
+              (throw 'system-error "login-pty" "~A"
+                     (list (strerror err))
+                     (list err)))))
+        (lambda args
+          (if (and (= (system-error-errno args) 38)
+                   (not library))
+              ;; Prior to glibc 2.34, login-pty resided in libutil.
+              ;; Try again, fingers crossed!
+              (login-tty fd "libutil")
+              (apply throw args)))))))
 
 \f
 ;;;
-- 
2.37.3





^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [bug#57730] [PATCH] syscalls: Adjust for glibc 2.34 and later.
  2022-09-11 10:50 [bug#57730] [PATCH] syscalls: Adjust for glibc 2.34 and later Marius Bakke
@ 2022-09-11 11:01 ` Marius Bakke
  2022-09-12 21:45 ` Ludovic Courtès
  1 sibling, 0 replies; 6+ messages in thread
From: Marius Bakke @ 2022-09-11 11:01 UTC (permalink / raw)
  To: 57730

[-- Attachment #1: Type: text/plain, Size: 805 bytes --]

Marius Bakke <marius@gnu.org> skriver:

> This is a re-implementation of 3c8b6fd94ceb1e898216929e8768fb518dbf1de9 that
> works with new and old libc's.
>
> * guix/build/syscalls.scm (openpty, login-tty): Wrap in exception handlers and
> retry with libutil if the first call is unsuccessful.

An alternative approach could be to use this helper:

(define gnu-get-libc-version
  (let ((proc (syscall->procedure '* "gnu_get_libc_version" '())))
    (lambda ()
      (let-values (((ret err) (proc)))
        (if (zero? err)
            (pointer->string ret)
            (throw 'system-error "gnu-get-libc-version"
                   "gnu-get-libc-version: ~A"
                   (list (strerror err))
                   (list err)))))))

...and maybe set a %glibc-version variable that can be used as needed.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 247 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [bug#57730] [PATCH] syscalls: Adjust for glibc 2.34 and later.
  2022-09-11 10:50 [bug#57730] [PATCH] syscalls: Adjust for glibc 2.34 and later Marius Bakke
  2022-09-11 11:01 ` Marius Bakke
@ 2022-09-12 21:45 ` Ludovic Courtès
  2022-09-15 15:26   ` Marius Bakke
  1 sibling, 1 reply; 6+ messages in thread
From: Ludovic Courtès @ 2022-09-12 21:45 UTC (permalink / raw)
  To: Marius Bakke; +Cc: 57730

[-- Attachment #1: Type: text/plain, Size: 1092 bytes --]

Hi,

Marius Bakke <marius@gnu.org> skribis:

> This is a re-implementation of 3c8b6fd94ceb1e898216929e8768fb518dbf1de9 that
> works with new and old libc's.
>
> * guix/build/syscalls.scm (openpty, login-tty): Wrap in exception handlers and
> retry with libutil if the first call is unsuccessful.

[...]

>  (define openpty
> -  (let ((proc (syscall->procedure int "openpty" '(* * * * *)
> -                                  #:library "libutil")))
> -    (lambda ()
> -      "Return two file descriptors: one for the pseudo-terminal control side,
> +  (lambda* (#:optional library)
> +    "Return two file descriptors: one for the pseudo-terminal control side,
>  and one for the controlled side."
> +    (let ((proc (syscall->procedure int "openpty" '(* * * * *)
> +                                    #:library library)))

In general, we must ensure that ‘syscall->procedure’ is called only once
per procedure, because it’s expensive compared to the function we’re
wrapping (it’s doing dlopen, dlsym, and all that).

Anyway, I think this should work:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: text/x-patch, Size: 1010 bytes --]

diff --git a/guix/build/syscalls.scm b/guix/build/syscalls.scm
index 7842b0a9fc..e081aaca44 100644
--- a/guix/build/syscalls.scm
+++ b/guix/build/syscalls.scm
@@ -445,9 +445,14 @@ (define* (syscall->procedure return-type name argument-types
 the returned procedure is called."
   (catch #t
     (lambda ()
+      ;; Note: When #:library is set, try it first and fall back to libc
+      ;; proper.  This is because libraries like libutil.so have been subsumed
+      ;; by libc.so with glibc >= 2.34.
       (let ((ptr (dynamic-func name
                                (if library
-                                   (dynamic-link library)
+                                   (or (false-if-exception
+                                        (dynamic-link library))
+                                       (dynamic-link))
                                    (dynamic-link)))))
         ;; The #:return-errno? facility was introduced in Guile 2.0.12.
         (pointer->procedure return-type ptr argument-types

[-- Attachment #3: Type: text/plain, Size: 30 bytes --]


WDYT?

Thanks,
Ludo’.

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [bug#57730] [PATCH] syscalls: Adjust for glibc 2.34 and later.
  2022-09-12 21:45 ` Ludovic Courtès
@ 2022-09-15 15:26   ` Marius Bakke
  2022-11-01 17:54     ` Mathieu Othacehe
  0 siblings, 1 reply; 6+ messages in thread
From: Marius Bakke @ 2022-09-15 15:26 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 57730

[-- Attachment #1: Type: text/plain, Size: 2253 bytes --]

Ludovic Courtès <ludo@gnu.org> skriver:

>>  (define openpty
>> -  (let ((proc (syscall->procedure int "openpty" '(* * * * *)
>> -                                  #:library "libutil")))
>> -    (lambda ()
>> -      "Return two file descriptors: one for the pseudo-terminal control side,
>> +  (lambda* (#:optional library)
>> +    "Return two file descriptors: one for the pseudo-terminal control side,
>>  and one for the controlled side."
>> +    (let ((proc (syscall->procedure int "openpty" '(* * * * *)
>> +                                    #:library library)))
>
> In general, we must ensure that ‘syscall->procedure’ is called only once
> per procedure, because it’s expensive compared to the function we’re
> wrapping (it’s doing dlopen, dlsym, and all that).

That makes sense.

> Anyway, I think this should work:
>
> diff --git a/guix/build/syscalls.scm b/guix/build/syscalls.scm
> index 7842b0a9fc..e081aaca44 100644
> --- a/guix/build/syscalls.scm
> +++ b/guix/build/syscalls.scm
> @@ -445,9 +445,14 @@ (define* (syscall->procedure return-type name argument-types
>  the returned procedure is called."
>    (catch #t
>      (lambda ()
> +      ;; Note: When #:library is set, try it first and fall back to libc
> +      ;; proper.  This is because libraries like libutil.so have been subsumed
> +      ;; by libc.so with glibc >= 2.34.
>        (let ((ptr (dynamic-func name
>                                 (if library
> -                                   (dynamic-link library)
> +                                   (or (false-if-exception
> +                                        (dynamic-link library))
> +                                       (dynamic-link))
>                                     (dynamic-link)))))
>          ;; The #:return-errno? facility was introduced in Guile 2.0.12.
>          (pointer->procedure return-type ptr argument-types
>
> WDYT?

I can confirm this works after reverting 3c8b6fd94ceb1e89821.

Can you commit it, or should I do it on your behalf?  I think we should
try to get it in 1.4.0 so Guix works when linked against system libc on
foreign distributions.

I'll revert 3c8b6fd94ce once this lands on 'core-updates'.

Thanks!

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 247 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [bug#57730] [PATCH] syscalls: Adjust for glibc 2.34 and later.
  2022-09-15 15:26   ` Marius Bakke
@ 2022-11-01 17:54     ` Mathieu Othacehe
  2022-11-07 21:30       ` bug#57730: " Ludovic Courtès
  0 siblings, 1 reply; 6+ messages in thread
From: Mathieu Othacehe @ 2022-11-01 17:54 UTC (permalink / raw)
  To: Marius Bakke; +Cc: Ludovic Courtès, 57730


Hey,

> Can you commit it, or should I do it on your behalf?  I think we should
> try to get it in 1.4.0 so Guix works when linked against system libc on
> foreign distributions.

This indeed seems like the right thing to do :) Marius or Ludo, I think
you can go ahead :)

Thanks,

Mathieu




^ permalink raw reply	[flat|nested] 6+ messages in thread

* bug#57730: [PATCH] syscalls: Adjust for glibc 2.34 and later.
  2022-11-01 17:54     ` Mathieu Othacehe
@ 2022-11-07 21:30       ` Ludovic Courtès
  0 siblings, 0 replies; 6+ messages in thread
From: Ludovic Courtès @ 2022-11-07 21:30 UTC (permalink / raw)
  To: Mathieu Othacehe; +Cc: 57730-done, Marius Bakke

Hi,

Mathieu Othacehe <othacehe@gnu.org> skribis:

> Hey,
>
>> Can you commit it, or should I do it on your behalf?  I think we should
>> try to get it in 1.4.0 so Guix works when linked against system libc on
>> foreign distributions.
>
> This indeed seems like the right thing to do :) Marius or Ludo, I think
> you can go ahead :)

Pushed on ‘core-updates’ as 3f6c32a88fc7a4d707ae1ed8ef3f7bd995461aff!

Ludo’.




^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-11-07 21:31 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-09-11 10:50 [bug#57730] [PATCH] syscalls: Adjust for glibc 2.34 and later Marius Bakke
2022-09-11 11:01 ` Marius Bakke
2022-09-12 21:45 ` Ludovic Courtès
2022-09-15 15:26   ` Marius Bakke
2022-11-01 17:54     ` Mathieu Othacehe
2022-11-07 21:30       ` bug#57730: " Ludovic Courtès

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).