[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Differences between container used by "guix build" and "guix environ
From: |
Ludovic Courtès |
Subject: |
Re: Differences between container used by "guix build" and "guix environment -C -N" |
Date: |
Sat, 01 Jul 2017 14:59:25 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/25.2 (gnu/linux) |
Hi,
Danny Milosavljevic <address@hidden> skribis:
> it does pretty much the equvalent of this Python program, in Rust:
>
> ------------------------
> #!/usr/bin/env python3
>
> import os
> import subprocess
> import signal
>
> signal.pthread_sigmask(signal.SIG_BLOCK, [signal.SIGINT])
>
> p = subprocess.Popen(["cat"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
>
> signal.pthread_sigmask(signal.SIG_UNBLOCK, [signal.SIGINT])
>
> os.kill(p.pid, signal.SIGINT)
> stdout, stderr = p.communicate(b"hello\n", timeout=1)
> assert stdout == b""
> p.wait()
> ------------------------
>
> The goal of it is to test this feature: Their "Popen" implementation uses
> something like spawnvp, only they have overwritten it in order to clear the
> signal mask for the child.
>
> In Rust the test is:
>
> ------------------------------------------------------
>
> fn test_process_mask() {
> unsafe {
> // Test to make sure that a signal mask does not get inherited.
> let mut cmd = Command::new(OsStr::new("cat"));
>
> let mut set: libc::sigset_t = mem::uninitialized();
> let mut old_set: libc::sigset_t = mem::uninitialized();
> t!(cvt(libc::sigemptyset(&mut set)));
> t!(cvt(sigaddset(&mut set, libc::SIGINT)));
> t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set, &mut
> old_set)));
>
> cmd.stdin(Stdio::MakePipe);
> cmd.stdout(Stdio::MakePipe);
>
> let (mut cat, mut pipes) = t!(cmd.spawn(Stdio::Null, true));
> let stdin_write = pipes.stdin.take().unwrap();
> let stdout_read = pipes.stdout.take().unwrap();
>
> t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &old_set,
> ptr::null_mut())));
>
> t!(cvt(libc::kill(cat.id() as libc::pid_t, libc::SIGINT)));
> // We need to wait until SIGINT is definitely delivered. The
> // easiest way is to write something to cat, and try to read it
> // back: if SIGINT is unmasked, it'll get delivered when cat is
> // next scheduled.
> let _ = stdin_write.write(b"Hello");
> drop(stdin_write);
>
> // Either EOF or failure (EPIPE) is okay.
> let mut buf = [0; 5];
> if let Ok(ret) = stdout_read.read(&mut buf) {
> assert!(ret == 0);
> }
>
> t!(cat.wait());
> }
>
> ------------------------------------------------------
>
> and the implementation that clears the mask is
> https://github.com/rust-lang/rust/blob/1.16.0/src/libstd/sys/unix/process/process_unix.rs#L144
> (line 144ff, bottom of "fn do_exec")
I guess the question would be whether ‘cmd.spawn’ relies on /bin/sh to
spawn processes, in which case “/bin/sh” would need patching like we do
for the ‘system’ function in libc and in other similar situations. That
doesn’t seem to be the case at first sight.
Ludo’.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: Differences between container used by "guix build" and "guix environment -C -N",
Ludovic Courtès <=