1

Here's my problem - I'm trying to write a small wrapper script that adds a command line argument when Xorg is called (I don't have access to the caller's source.) It seemed simple enough, but the problem I'm now running into is that the caller is waiting for a USR1 signal from Xorg. From the XSERVER man page:

SIGUSR1

This signal is used quite differently from either of the above. When the server starts, it checks to see if it has inherited SIGUSR1 as SIG_IGN instead of the usual SIG_DFL. In this case, the server sends a SIGUSR1 to its parent process after it has set up the various connection schemes. Xdm uses this feature to recognize when connecting to the server is possible.

I thought I could simply trap the signal and forward it:

#!/bin/bash
parent_trap(){
   echo sending USR1 to $PPID &> /tmp/wrapper.log
   kill -USR1 $PPID
}
trap "parent_trap" USR1
Xorg $@ (extra stuff) &
wait

But of course this doesn't work, as the script itself is started by the caller ignoring USR1. I THINK what I need to do is have the script stop ignoring the signal, but also somehow launch Xorg with USR1 ignored (to trigger the behavior from the man page.)

Is this possible in Bash/some other scripting language? For a few reasons I'm hoping to avoid a compiled solution, but it's not unthinkable. It's also possible I'm completely thinking about this wrong and there's some other way to get USR1 from Xorg to the caller.

1

Your new script

Instead of trying to do something fancy with the signals why not just do this instead:

$ cat xorg_wrapper
#!/bin/bash

exec Xorg $@ (extra stuff)

How it works

To illustrate what's going on with the above, here's a more elaborate example that helps to show the mechanics of the exec in the above script.

$ cat xorg.bash
#!/bin/bash

echo "script's PID: $$"
sleep 5
echo "starting fakeXorg..."
exec sleep 5

# Nothing below here will execute due to exec
echo $!
echo "fakeXorg finished..."
sleep 5

This will launch Xorg as you specified but because we're using the exec command Xorg will assume the same PID and replace our xorg.bash script with itself.

NOTE: The intent of the above last 3 lines is to demonstrate that the xorg.bash is no longer in play/running after the exec sleep ... command runs.

Example

First we run our script:

$ ./xorg.bash
script's PID: 22471

...5 seconds passes...

starting fakeXorg...

...now the exec runs and 5 more seconds pass...

$

If we were to monitor this in another shell using ps auxf we'd see this.

phase 1 - xorg.bash pre-exec
$ ps auxf
....
root     21184  0.0  0.3 116596  3412 pts/2    S    20:19   0:00                  \_ /bin/bash
root     22471  0.0  0.1 113176  1400 pts/2    S+   20:43   0:00                      \_ /bin/bash ./xorg.bash
root     22472  0.0  0.0 107948   348 pts/2    S+   20:43   0:00                          \_ sleep 5
phase 2 - xorg.bash post-exec
$ ps auxf
....
root     21184  0.0  0.3 116596  3412 pts/2    S    20:19   0:00                  \_ /bin/bash
root     22471  0.0  0.0 107948   352 pts/2    S+   20:43   0:00                      \_ sleep 5

Notice in phase 1 that xorg.bash has a PID of 22471, but in phase 2, the exec sleep 5 now has the same PID, 22471.

The lines after exec ...

The function of the exec command causes the current shell to be replaced by another executable:

   $ help exec
    ...
        Replace the shell with the given command.

As a consequence of this, any commands in the xorg.bash never get executed because at the point where exec .... is, xorg.bash ceases to exist as a process, having been replaced by the sleep command.

References

  • That's perfect - I was completely ignorant of how exec works. Thank you! – Kevin Jul 14 '18 at 20:35
  • @Kevin you're quite welcome, good luck. – slm Jul 14 '18 at 20:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.