C: Múltiplos programas no mesmo binário

Um mesmo aplicativo pode se comportar de forma diferente dependendo da forma como é invocado. No exemplo a seguir, o mesmo programa é usado para calcular a raiz quadrada e potência de dois de um dado argumento.

#include <libgen.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv)
{
    double res;
    char *program = basename(argv[0]);

    if (argc != 2)
        return 1;

    if (!strcmp(program, "sqrt")) {
        res = sqrt(atof(argv[1]));
        printf("%f\n", res);
        return 0;
    }

    if (!strcmp(program, "pow2")) {
        res = pow(atof(argv[1]), 2);
        printf("%f\n", res);
        return 0;
    }

    printf("Invalid program: %s\n", program);

    return 1;
}

O truque consiste em analisar o primeiro argumento que corresponde ao caminho do binário do programa. No exemplo, decidimos qual ação tomar comparando o nome do programa com “sqrt” e “pow2”. Para não fazer múltiplas cópias do binário gerado, fazemos links simbólicos.

$ gcc -Wall -lm -o test test.c
$ ln -s test sqrt
$ ln -s test pow2

$ ./test 5
Invalid program: test

$ ./pow2 5
25.000000

$ ./sqrt 5
2.236068

A técnica é extensamente utilizada no BusyBox e pode facilmente ser implementada em qualquer outra linguagem de programação.

This entry was posted in C and tagged , , . Bookmark the permalink.

5 Responses to C: Múltiplos programas no mesmo binário

  1. Segue o exemplo em python:

    #!/usr/bin/python

    import sys
    from os.path import basename

    nome = basename(sys.argv[0])

    numero1 = int(sys.argv[1])
    numero2 = int(sys.argv[2])

    if nome == ‘soma’:
    print “Resultado da soma:”,numero1 + numero2

    if nome == ‘subtracao’:
    print “Resultado da subtracao:”,numero1 – numero2

    ————————-
    No Windows não achei como fazer isto, por nao ter os links, mas deve ter como…

    \o/

  2. Vinícius says:

    Não consigo ver a real utilidade.

    • Em um sistema embarcado que não suporta shared libraries é uma forma interessante de diminuir o footprint de uma aplicação.

      Imagine 10 aplicações que fazem algo semelhante linkando estaticamente com a mesma biblioteca.

      • Ulisses Furquim says:

        Aliás, busybox funciona exatamente assim, para aqueles que nunca olharam.

        — Ulisses

  3. Eu já havia feito algo parecido, porém nunca soube uma real utilidade para isso.

Leave a Reply

Your email address will not be published. Required fields are marked *