If you write a zshell function for compiling & running a piece of C code, you might begin with this:

compile_run () {
    local exepath="$(mktemp)"
    cc -g "$1" -o $exepath
    "$exepath" "$@"
}

Which works as expected for well-behaved programs:

job_control_1.png

If your program contains a segmentation fault however, job control messages will be hidden from you as if your program printed no input at all.

job_control_2.png

You may have known that messages like [1] 21212 segmentation fault (core dumped) ./faulty aren’t ordinary messages in the sense you can’t capture them and they aren’t generated by the program itself. They are actually generated by your shell trapping those signals before executing a program, which, should that program have issues, will run before your program terminates.

Shell-defined functions which run external programs (like compile_run) are considered to be running within the current shell however, so job status messages for the exit status of the function are not printed.

Cycling background jobs hack

To get around this, 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:

compile_run () {
    local exepath="$(mktemp)"
    cc -g "$1" -o $exepath
    ## Magic Happens Here: ###############
    "$exepath" "$@" & fg
    ######################################
}

A more comprehensive “compile run” function would have the same idea but with some additional logic:

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

    if [[ $file = *.cc ]]; then
        c++ -std=c++1z -g -Wall -Weffc++ $file -o $exepath
    elif [[ $file = *.c ]]; then
        cc -g -Wall $file -o $exepath
    else
        echo "no filetype detected"
        return 126
    fi  || return $?

    "$exepath" "$@" & fg
}

Custom messages

If you want control over the exact message printed, you can also examine the exit status of the program you ran yourself.

compile_run () {
    local exepath="$(mktemp)"
    cc -g "$1" -o $exepath

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

Using setopt print_exit_value

Finally, zshell has an option print_exit_value that won’t display messages identically to job control messages, but will let you know what the exit status code of your program is:

job_control_3.png