Hacker News new | ask | show | jobs
by chrisseaton 2716 days ago
Sorry I don’t know anything about how Bash is implemented, but when someone assigns to that variable Bash just needs to write that string to argv.
1 comments

I tried python, bash and even C, none of them update /proc/self/comm when argv[0] is updated:

  dualbus@system76-pc:~$ cat argv0.c
  #include <stdio.h>
  #include <string.h>
  int main(int argc, char **argv) {
      FILE *fp;
      char buf[256]; // XXX :-)
      strcpy(argv[0], "XYZ");
      //puts(argv[0]);
      fp = fopen("/proc/self/comm", "r");
      fread(&buf, 1, 256, fp);
      buf[255] = '\0';
      puts(buf);
  }
  dualbus@system76-pc:~$ gcc -o argv0 argv0.c  -Wall
  dualbus@system76-pc:~$ ./argv0
  argv0

  dualbus@system76-pc:~$ python -c 'import sys; sys.argv[0] = "XYZ"; print(open("/proc/self/comm").read())'
  python

  dualbus@system76-pc:~$ ~/src/gnu/bash/bash -c 'BASH_ARGV0="XYZ"; cat /proc/$BASHPID/comm'
  bash
Furthermore, https://github.com/torvalds/linux/blob/master/Documentation/... says:

  > 3.6   /proc/<pid>/comm  & /proc/<pid>/task/<tid>/comm
  > --------------------------------------------------------
  > These files provide a method to access a tasks comm value. It also allows for
  > a task to set its own or one of its thread siblings comm value. The comm value
  > is limited in size compared to the cmdline value, so writing anything longer
  > then the kernel's TASK_COMM_LEN (currently 16 chars) will result in a truncated
  > comm value.
Which works as advertised:

  dualbus@system76-pc:~$ ~/src/gnu/bash/bash -c 'echo -n XYZ > /proc/$BASHPID/comm; ps -p $BASHPID'
    PID TTY          TIME CMD
  28797 pts/6    00:00:00 XYZ
Can you show me an example, in any language, where updating argv[0] causes ps (or /proc/self/comm) to show the updated value?

EDIT: formatting.

EDIT2: I stand corrected, see willglynn's comment.

You're looking at the wrong file. Setting argv[0] doesn't update /proc/self/comm, it updates /proc/self/cmdline.

demo.c:

    #include <unistd.h>
    #include <string.h>
    
    int main(int argc, char *argv[]) {
    	strcpy(argv[0], "frob");
    	sleep(100);
    }
Terminal 1:

    $ make demo
    cc     demo.c   -o demo
    $ ./demo --greppable
Terminal 2:

    $ ps aux|grep greppable
    luke     25858  0.0  0.0   2164   752 pts/0    S+   00:32   0:00 frob o --greppable
    luke     25931  0.0  0.0   8192  2356 pts/5    S+   00:32   0:00 grep --color=auto greppable
    $ cat -v /proc/25858/cmdline
    frob^@o^@--greppable^@$

    $ ruby -e "\$0 = 'im not lying to you'; sleep"
    $ ps