zsh-users
 help / color / mirror / code / Atom feed
* Redirecting a programs job control messages to parent's STDOUT
@ 2017-07-10 21:16 zv
  2017-07-25 19:33 ` zv
  2017-07-25 21:03 ` Bart Schaefer
  0 siblings, 2 replies; 3+ messages in thread
From: zv @ 2017-07-10 21:16 UTC (permalink / raw)
  To: zsh-users

I've defined a function in my .zshrc to compile & run a file with the function
below:

  crun() {
      local file=$1
      shift
      local exepath="$(mktemp)"

      if [[ $file =~ "\.c$" ]]; then
          gcc -g -Wall $file -o $exepath || return $?
      else
          echo "no filetype detected"
          return 126
      fi

      $exepath "$@"
  }

Which is called like so:

  % crun source.cc arg_1 arg_2

This works for normal program, but has the problem that the shell's job control
messages, such as those generated from a segfault, do not appear.

As an example:

  % echo 'int main=0' >> /tmp/faulty.c # a crashing c program
  % crun faulty.c
  % # no output generated

Whereas the equivalent interactive commands would generate this:

  % g++ faulty.c -o /tmp/faulty && /tmp/faulty
  [1] 2894 segmentation fault (core dumped) # 🢀 zsh's job control output for
SIGSEGV

I've tried a number of different ways to trap the signal or have the invoking
("parent") shell to treat "constructed binaries" identically to an ordinary
executable/command but nothing seems to work without a hacks large enough to
morally bankrupt me.

Is there any way to display these messages for a crashing executable whose path
is dynamically calculated? Ideally without writing your own trap/signal handlers
+ exec, using `sh -c "$exepath $@"`, or writing a totally new program entirely)

- zv


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

* Re: Redirecting a programs job control messages to parent's STDOUT
  2017-07-10 21:16 Redirecting a programs job control messages to parent's STDOUT zv
@ 2017-07-25 19:33 ` zv
  2017-07-25 21:03 ` Bart Schaefer
  1 sibling, 0 replies; 3+ messages in thread
From: zv @ 2017-07-25 19:33 UTC (permalink / raw)
  To: zsh-users

In case any later readers are interested in this question, I've posted an answer
below which came to me via _another_ answer by a certain Vartan Simonian (thanks
Vartan!)

------------------------------------------------------------

You can get zsh to print the segmentation fault message from the job if you
start it as a background job and then immediately bring it to the foreground.

    "$exepath" "$@" &
    fg

This will cause zsh to print out messages for signals on the job started for
$exepath.

The downside is that you will get a little bit more than you bargained for:

    % crun faulty.c
    faulty.c:1:5: warning: ‘main’ is usually a function [-Wmain]
     int main=0;
         ^~~~
    [2] 2080
    [2]  - running    "$exepath" "$@"
    zsh: segmentation fault (core dumped)  "$exepath" "$@"

But as shown, you will get the segfault messages printed in the terminal.

Because the messages are printed by the interactive shell, not the failing
process, the job messages won't get redirected should you try to redirect stdout
or stderr.

So on the one hand, should you try to take useful output out of your running
process and redirect it somewhere else, you don't need to worry about the job
messages getting in the way. But this also means you won't get the segfault
message should you try to redirect it by redirecting stderr.

Here's a demonstration of this effect, with line breaks added in-between
commands for clarity:

    % crun good.c > test
    [2] 2071
    [2]  - running    "$exepath" "$@"

    % cat test
    Hello, world!

    % crun faulty.c 2>test
    [2] 2092
    [2]  - running    "$exepath" "$@"
    zsh: segmentation fault (core dumped)  "$exepath" "$@"

    % cat test
    faulty.c:1:5: warning: ‘main’ is usually a function [-Wmain]
     int main=0;
         ^~~~



- zv

On 07/10/2017 02:16 PM, zv wrote:
> I've defined a function in my .zshrc to compile & run a file with the function
> below:
> 
>   crun() {
>       local file=$1
>       shift
>       local exepath="$(mktemp)"
> 
>       if [[ $file =~ "\.c$" ]]; then
>           gcc -g -Wall $file -o $exepath || return $?
>       else
>           echo "no filetype detected"
>           return 126
>       fi
> 
>       $exepath "$@"
>   }
> 
> Which is called like so:
> 
>   % crun source.cc arg_1 arg_2
> 
> This works for normal program, but has the problem that the shell's job control
> messages, such as those generated from a segfault, do not appear.
> 
> As an example:
> 
>   % echo 'int main=0' >> /tmp/faulty.c # a crashing c program
>   % crun faulty.c
>   % # no output generated
> 
> Whereas the equivalent interactive commands would generate this:
> 
>   % g++ faulty.c -o /tmp/faulty && /tmp/faulty
>   [1] 2894 segmentation fault (core dumped) # 🢀 zsh's job control output for
> SIGSEGV
> 
> I've tried a number of different ways to trap the signal or have the invoking
> ("parent") shell to treat "constructed binaries" identically to an ordinary
> executable/command but nothing seems to work without a hacks large enough to
> morally bankrupt me.
> 
> Is there any way to display these messages for a crashing executable whose path
> is dynamically calculated? Ideally without writing your own trap/signal handlers
> + exec, using `sh -c "$exepath $@"`, or writing a totally new program entirely)
> 
> - zv
> 
> 



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

* Re: Redirecting a programs job control messages to parent's STDOUT
  2017-07-10 21:16 Redirecting a programs job control messages to parent's STDOUT zv
  2017-07-25 19:33 ` zv
@ 2017-07-25 21:03 ` Bart Schaefer
  1 sibling, 0 replies; 3+ messages in thread
From: Bart Schaefer @ 2017-07-25 21:03 UTC (permalink / raw)
  To: Zsh Users; +Cc: zv

Meant to reply to this before; it got lost in the aftermath of
returning from a vacation.

On Mon, Jul 10, 2017 at 2:16 PM, zv <zv@nxvr.org> wrote:
> I've defined a function in my .zshrc to compile & run a file

What's going on here is that the function is considered to be running
within the current shell, so job status messages for the exit status
of the function are not printed.  The exit status of the function is
the status of the last command it executed, so if you were to examine
the value of $? (or $status) after the function was done, you would
see that it reflects the failure.  The lack of message has nothing to
do with how the executable or path to it was created.

So you have a couple of choices:
1.  Run the command in the background so full job control applies
during the function, which is effectively what Vartan describes; or
2.  Examine the exit status yourself and print  your own message.

E.g. if you end your crun function with

   $exepath "$@"
   integer stat=$status
   if (( stat > 128 )); then print -u2 -- ${exepath}: exited with
SIG${signals[stat-127]}; fi
   return stat

You'll see something like

   faulty.c: exited with SIGSEGV

You could also/instead "setopt print_exit_value" which would give something like

   zsh: exit 139


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

end of thread, other threads:[~2017-07-25 21:03 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-07-10 21:16 Redirecting a programs job control messages to parent's STDOUT zv
2017-07-25 19:33 ` zv
2017-07-25 21:03 ` Bart Schaefer

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

	https://git.vuxu.org/mirror/zsh/

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 NNTP newsgroup(s).