guix-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug#57050] [PATCH v2 04/13] gnu: Add Zuo.


From: Philip McGrath
Subject: [bug#57050] [PATCH v2 04/13] gnu: Add Zuo.
Date: Mon, 22 Aug 2022 21:40:29 -0400
User-agent: Cyrus-JMAP/3.7.0-alpha0-841-g7899e99a45-fm-20220811.002-g7899e99a

Hi,

On Tue, Aug 16, 2022, at 10:47 AM, Maxime Devos wrote:
> On 11-08-2022 16:00, Philip McGrath wrote:
>>>> +        #~`(,(string-append "CPPFLAGS=-DGUIX_RKTIO_BIN_SH="
>>>> +                            #$(file-append (this-package-input
>>>> "bash-minimal")
>>>> +                                           "/bin/sh"))
>>>> 
>>> As with chez-scheme, I do think using a Racket-agnostic macro name is
>>> helpful here.
>>> 
>> I'm planning to respond in the other thread about the possibility of a truly 
>> generic macro name, but I hope it doesn't need to become an issue blocking 
>> this patch series. For now, I'm not entirely sure what "Racket-agnostic" 
>> means; the bottom line for my is I think it would be absurdly awful to have 
>> to write, e.g. if cross-compiling using `distro-build` with the top-level 
>> Makefile:
>> 
>>     ./configure CPPFLAGS="GUIX_RKTIO_BIN_SH=/input/bin/sh 
>> GUIX_ZUO_BIN_SH=/input/bin/sh GUIX_CHEZ_BIN_SH=/input/bin/sh" 
>> CPPFLAGS_FOR_BUILD="GUIX_RKTIO_BIN_SH=/native-input/bin/sh 
>> GUIX_ZUO_BIN_SH=/native-input/bin/sh GUIX_CHEZ_BIN_SH=/native-input/bin/sh"
>
> Example: GUIX_SH=/inputs/bin/sh.
> 

I will use GUIX_SH in v3 of this series.

My concern with it originally was that it's generic enough that it might be 
used in other ways elsewhere in Guix, but, since I'm hoping it's only going to 
be a medium-term solution, it seems good enough, and I haven't heard any 
objections to it.

> I haven't been following the discussion on the other patches, but didn't I 
> give an example of something independent of the Racket component in use and 
> even independent of Racket itself? See the suggestion of using the already 
> existing _PATH_BSHELL from <paths.h>. It's even not Guix-specific, apparently 
> it's a BSD-ism!
> 

On Wed, Aug 10, 2022, at 7:46 AM, Maxime Devos wrote:
> On 09-08-2022 23:58, Philip McGrath wrote:
>
>> On Tuesday, August 9, 2022 5:38:56 PM EDT ( wrote:
>>> On Tue Aug 9, 2022 at 10:24 PM BST, Maxime Devos wrote:
>>>> In the glibc headers, there's some (POSIX?) standard macro that points
>>>> at "/gnu/store/.../bin/sh" (I don't recall the name), any reason we
>>>> aren't using that macro?  That would be Guix-independent. I'm not sure
>>>> if a /gnu/store/... prefix is included, but if not, maybe we could try
>>>> overriding it with -D...="/gnu/store/...", or failing that, add a
>>>> post-unpack substitute* replacing [the macro name] ->
>>>> "/gnu/store/.../bin/sh".
>>> I believe you might be referring to <paths.h>, which defines _PATH_BSHELL.
>>>
>>> It's not standard C <https://en.cppreference.com/w/c/header> nor POSIX
>>> <https://pubs.opengroup.org/onlinepubs/9699919799/idx/head.html> though.
>>>
>>>      -- (
>
> Looking at the "paths.h" header, it appears to be a BSDism. Not really 
> standard but still better than a Guix-ism.
>
>> I'd love to be wrong, but I also can't find such a macro. In the glibc source
>> tree, "stdlib/system.c" defines a stub implementation that always fails with
>> ENOSYS, and "sysdeps/posix/system.c" contains:
>>
>>      #define SHELL_PATH      "/bin/sh"       /* Path of the shell.  */
>>      #define SHELL_NAME      "sh"    /* Name to give it.  */
>>
>> Concretely, I think Guix's glibc currently uses /bin/sh dynamically: in my
>> Chez example above, if you replace `process` with `system` (which uses libc's
>> `system`), the result is always "/bin/sh\n".
>
> If so, that's a bug.  I do not know what result you are referring to.

(Disregard this part; I think I was thinking about some other way I had tried 
things.)

>
> Anyway, the Guix package definition of glibc substitutes _PATH_BSHELL 
> and SHELL_PATH, so unless there's a bug, it doesn't depend on /bin/sh.
>

I have been looking further into options for addressing this upstream.

First of all, I have found that there *is* another Unix-like system where 
"/bin/sh" doesn't exist: on Android, the POSIX shell is usually at 
"/system/bin/sh". Also, at least on some versions, _PATH_BSHELL isn't a 
compile-time constant. It is:

    #define _PATH_BSHELL __bionic_get_shell_path()

(There are also systems where "/bin/sh" is some non-POSIX shell and the POSIX 
shell is at "/usr/xpg4/bin/sh". If changing this upstream, Racket may need to 
decide whether POSIX compatibility or historical compatibility is more 
important there.)

I've found that there does seem to be a POSIX recommendation for finding "sh". 
The POSIX spec for `system` 
<https://pubs.opengroup.org/onlinepubs/9699919799/functions/system.html> says, 
under "Application Usage", "There is no defined way for an application to find 
the specific path for the shell. However, confstr() can provide a value for 
PATH that is guaranteed to find the sh utility." Similarly, 
<https://pubs.opengroup.org/onlinepubs/9699919799/utilities/sh.html> says that 
"applications should note that the standard PATH to the shell cannot be assumed 
to be either /bin/sh or /usr/bin/sh, and should be determined by interrogation 
of the PATH returned by getconf PATH, ensuring that the returned pathname is an 
absolute pathname and not a shell built-in." Most emphatically, 
<https://pubs.opengroup.org/onlinepubs/9699919799/functions/confstr.html> says 
in the normative "Description":

>
> If the implementation supports the POSIX shell option, the string stored in 
> buf after a call to:
>
>     confstr(_CS_PATH, buf, sizeof(buf))
>
> can be used as a value of the PATH environment variable that accesses all of 
> the standard utilities of POSIX.1-2017, that are provided in a manner 
> accessible via the exec family of functions, if the return value is less than 
> or equal to sizeof(buf).
>

However, apparently using `confstr` with `_CS_PATH` does not give a useful 
result in Guix build environments. Try building the following package with 
`guix build -f`: I've put the interesting log output in the description. In 
particular, note that *both* bash-minimal and bash-static are present!

--8<---------------cut here---------------start------------->8---
(use-modules
 (guix build-system gnu)
 (guix gexp)
 ((guix licenses) #:prefix license:)
 (guix packages))
(define src
  (plain-file "demo.c"
              "#include <stdlib.h>
#include <stdio.h>
#include <paths.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
  puts(_PATH_BSHELL);
  size_t buf_len = confstr(_CS_PATH, NULL, 0);
  char* buf = malloc(buf_len);
  if (NULL == buf) {
    return 1;
  };
  confstr(_CS_PATH, buf, buf_len);
  puts(buf);
  fflush(stdout);
  int status = system(\"echo $BASH\");
  fflush(stdout);
  printf(\"status: %i\\n\", status);
  return 0;
}
"))
(package
  (name "libc-system-demo")
  (version "0")
  (source src)
  (build-system gnu-build-system)
  (arguments
   (list
    #:phases
    #~(modify-phases %standard-phases
        (delete 'configure)
        (replace 'build
          (lambda args
            (invoke "gcc" "-o" "demo" #$src)))
        (replace 'check
          (lambda args
            (invoke "./demo")))
        (replace 'install
          (lambda args
            (install-file "demo" (string-append #$output "/bin")))))))
  (home-page "https://issues.guix.gnu.org/57050";)
  (synopsis "Some 'sh'-related values from glibc")
  (description "starting phase `check'
/gnu/store/720rj90bch716isd8z7lcwrnvz28ap4y-bash-static-5.1.8/bin/sh
/bin:/usr/bin
/gnu/store/4y5m9lb8k3qkb1y9m02sw9w9a6hacd16-bash-minimal-5.1.8/bin/sh
status: 0
phase `check' succeeded after 0.0 seconds")
  (license license:cc0))
--8<---------------cut here---------------end--------------->8---

AFAICT, Glibc's `confstr` implementation for `_CS_PATH` doesn't have any 
mechanism for configuring the search path; it simply uses the compile-time 
version, `CS_PATH`, which is:

    #define     CS_PATH "/bin:/usr/bin"

More generally, it seems questionable for our glibc to retain a store reference 
to Bash (let alone two). Wouldn't that prevent creating containers or packs 
without a shell present?

After I've sent a v3 of this series, I plan to raise these questions on the 
guix-devel list. Then, once I have a sense of whether Guix would like to 
support `confstr` with  `_CS_PATH` as a way of finding the shell, I'll propose 
some changes to Racket upstream.

-Philip





reply via email to

[Prev in Thread] Current Thread [Next in Thread]