[HN Gopher] Binfmtc - binfmt_misc C scripting interface
       ___________________________________________________________________
        
       Binfmtc - binfmt_misc C scripting interface
        
       Author : todsacerdoti
       Score  : 74 points
       Date   : 2025-06-08 12:38 UTC (10 hours ago)
        
 (HTM) web link (www.netfort.gr.jp)
 (TXT) w3m dump (www.netfort.gr.jp)
        
       | zx2c4 wrote:
       | Similar project of mine from a long while ago:
       | https://git.zx2c4.com/cscript/about/
        
       | Surac wrote:
       | So lovely
        
       | elitepleb wrote:
       | similar to http://www.iq0.com/duffgram/com.html
        
       | JSR_FDED wrote:
       | C is still my first love. You can hold the whole language in your
       | head, and it's fast. Yes there are footguns but it's a
       | libertarian programming language - you're responsible for what
       | you build. No hand holding.
        
         | ykonstant wrote:
         | I like that too, but the problem is that C doesn't keep its end
         | of the deal. No hand holding, but make what you are doing
         | transparent. It used to be the case back in the 80s, but not
         | anymore. Not with our optimizing compilers and oodles of UB and
         | spec subtleties and implicit actions.
        
       | radiospiel wrote:
       | Amazing; when I tried something similar I used a "#!" line
       | pointing to a C compiler + runner of sorts
       | (https://github.com/radiospiel/jit).
       | https://git.zx2c4.com/cscript/about/ is also following that
       | approach.
       | 
       | What is the benefit of registering an extension via binfmt_misc?
        
         | lmz wrote:
         | It's still valid C source code? Is the #! sequence valid C?
        
       | enriquto wrote:
       | was surprised that "sudo apt install binfmtc" works out of the
       | box on my box (linux mint) and i can do the magic just as
       | described here
        
       | rwmj wrote:
       | You can already do this without using binfmt ...
       | #if 0       gcc "$0" -o "$@".out && exec ./"$@".out       #endif
       | #include <stdio.h>       int main () { printf ("hello, world\n");
       | return 0; }
       | 
       | Usage:                 $ chmod +x print.c       $ ./print.c
       | hello, world
       | 
       | (Could be better to use a temporary file though.)
       | 
       | There's a similar cute trick for compiled OCaml scripts that we
       | use with nbdkit: https://libguestfs.org/nbdkit-cc-
       | plugin.3.html#Using-this-pl...
        
         | mananaysiempre wrote:
         | Compiler errors won't cause as many funny consequences with
         | gcc "$0" -o "$@".out && exec ./"$@".out || exit $?   # I'd use
         | ${0%.c} not $@
         | 
         | Love this trick too, but the difference, as far as I
         | understand, is that it only works with a Bourne(-compatible)
         | shell, whereas shebangs or binfmt_misc also work with exec().
        
         | AlotOfReading wrote:
         | You can also #embed the compiler binary, and execve it to much
         | the same effect as binfmtc. I explored that trick for an IOCC
         | entry that was never submitted because it ended up far too
         | readable.
        
         | ckastner wrote:
         | Oh this is neat. Took me a bit.
         | 
         | The shell treats the first line as a comment. It executes the
         | second line, which eventually exec's the binary so the rest of
         | the file do not matter to the shell.
         | 
         | And the compiler treats the first line as a preprocessor
         | directive, so it ignores the second line.
         | 
         | I initially misread/mistook the first line for a shebang.
        
         | teo_zero wrote:
         | The use of $@ doesn't look right to me.
         | 
         | In the trivial case exposed here where there are no additional
         | arguments to pass to the .c program, the shell executes
         | gcc "print.c" -o .out && exec ./.out
         | 
         | and it works "by chance".
         | 
         | In a more complex scenario where print.c expects some
         | parameters, it won't work. For example,
         | ./print.c a b c
         | 
         | will result in the shell trying to invoke                 gcc
         | "print.c" -o "a" "b" "c".out && exec ./"a" "b" "c".out
         | 
         | which makes no sense.
         | 
         | Are you sure you didn't intend $0 instead of $@ ?
        
           | rwmj wrote:
           | It's true, that's a mistake!
           | 
           | OTOH we're trying to write self-compiling executable C
           | scripts, so the safety, correctness and good sense ships
           | sailed a while back.
        
       | monocasa wrote:
       | There's also tcc, which has a shebang compatible extension to
       | allow it to be used by scripts.
        
       | kazinator wrote:
       | This is doable entirely without a Linux-specific binfmt-misc
       | hack.
       | 
       | https://rosettacode.org/wiki/Multiline_shebang#C
        
         | enriquto wrote:
         | This is a neat hack, but the whole file is not a valid C
         | program.
        
       | codr7 wrote:
       | I did a simple hack for doing the same thing from inside a C
       | program for my book:
       | 
       | https://github.com/codr7/hacktical-c/tree/main/dynamic
        
       ___________________________________________________________________
       (page generated 2025-06-08 23:00 UTC)