Τρίτη, 7 Ιουνίου 2011

Αλλάζοντας το όνομα του εκτελέσιμου ενός προγράμματος στο Linux

Για ένα άρθρο ήθελα να γράψω ένα πρόγραμμα στο Linux το οποίο να αλλάζει το όνομά του (όπως αυτό φαίνεται στο ps, top κλπ) κατά τη διάρκεια της εκτέλεσης. Πολλά προγράμματα έχουν αυτή τη δυνατότητα όπως το ssh, η postgresql κλπ.

Ο πιο portable τρόπος για να γίνει κάτι τέτοιο είναι να κάνει απλά το πρόγραμμα exec τον εαυτό του με άλλο όνομα.

Στη δική μου περίπτωση το exec δε βόλευε για άλλους λόγους, οπότε η μόνη λύση ήταν η κατευθείαν αλλαγή του ονόματος. Τα BSD έχουν γι αυτή τη δουλειά την κλήση συστήματος setproctitle. Στο Linux όμως δεν υπάρχει κάτι τέτοιο.

Τελικά η λύση είναι διττή: αφενός πρέπει να υπερκαλύψεις (overwrite) τα δεδομένα του argv[0], αφετέρου χρειάζεται το prctl system call με παράμετρο PR_SET_TITLE. Στη δική μου περίπτωση δε χρειάστηκε να κάνω "χώρο" για το νέο όνομα αφού ήξερα με βεβαιότητα ότι θα είναι μικρότερο από το παλιό. Αν κάποιος θέλει τη γενική συνάρτηση που δουλεύει για σχεδόν arbitrary καινούργια ονόματα αυτή υπάρχει στον κώδικα του πακέτου util-linux ως "setproctitle".

Η απλή τώρα λύση, σε κώδικα πάει κάπως έτσι:


  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <sys/prctl.h>
  4.  
  5. #define PNAME "sh"
  6.  
  7. int main (int argc, char **argv)
  8. {
  9.     memset (argv[0], '\0', strlen (argv[0]));
  10.     strcpy (argv[0], PNAME);
  11.     prctl (PR_SET_NAME, PNAME, 0, 0, 0);
  12.  
  13.     /* cpu hog so that we show up in top */
  14.     for (;;) ;
  15.  
  16.     return 0;
  17. }
  18.  

Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου