Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I'm fairly sure `#!./quine` will cause an error because there's a limit of 5 recursive checks to find the interpreter of a script (fs/binfmt_script.c).


Ran it, works. I'm on freebsd 10.3 BTW.


On Linux you get ELOOP. How does that resolution even work on FreeBSD? Why does it resolve to $SHELL (the file resolves to itself).


Yeah, I don't see that working unless the shebang is changed to `#!/bin/sh`?


execve(2) on my machine defines ELOOP lie this: Too many symbolic links were encountered in translating the pathname.

Refer to sys/kern/imgact_shell.c and ^do_execve in sys/kern/kern_exec.c, I skimmed but could not find why it ran.


Presumably then, whatever shell you're using decides to just execute the code as a subshell rather than use execve(2). Can you dtrace it to figure out whether it actually calls execve(2)?


After running dtrace as

  $ sudo dtrace -n 'syscall::execve*:entry { printf("%s %s", execname, copyinstr(arg0)); }'
I had this output

    0  51617                     execve:entry sh ./quine
    1  51617                     execve:entry sh /bin/sh
    1  51617                     execve:entry sh /bin/cat
Altho this is the first time I use dtrace. I can try to run another command you can ask me to.

My login shell is the Bourne shell. However I tried bash, csh and tcsh too, it works, so it's probably the system level code that substitutes /bin/sh (maybe because it's my login shell?) to the interpreter.


I think shells are doing that. Otherwise you wouldn't see the execve("/bin/sh") syscall entry (it would get silently translated inside the kernel).




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: