This is done via a process filter.
By default comint-output-filter-functions
includes comint-watch-for-password-prompt
, which is the filter function that handles this.
If it sees text matching comint-password-prompt-regexp
then it calls send-invisible
to prompt the user for a password.
For more information about how process filters work, refer to C-hig (elisp)Filter Functions
Edit: As a follow-up, note also that you can M-x toggle-debug-on-quit
and then at the sudo prompt type C-g to get a backtrace which would show what's going on. e.g.:
Debugger entered--Lisp error: (quit)
read-string("[sudo] password for <username>: " nil t nil)
read-passwd("[sudo] password for <username>: ")
send-invisible("[sudo] password for <username>: ")
comint-watch-for-password-prompt("[sudo] password for <username>: ")
run-hook-with-args(comint-watch-for-password-prompt "[sudo] password for <username>: ")
comint-output-filter(#<process shell> "[sudo] password for <username>: ")
The output is minimal on account of byte-compiled code being evaluated, so the detail of comint-output-filter-functions
is lost, but you can still immediately see the general situation. You could also M-x load-library
RET comint.el
RET to load the uncompiled code and then repeat the whole process to get a more detailed backtrace.