snprintf(surprise, BUFSIZ, “prout%s”, surprise);

Tags: , ,
No Comments »

Cet après midi, j’ai eu une mauvaise surprise. Je fus en effet étonné de constater qu’en compilant pkgin sous GNU/Linux, les appels du type :

snprintf(a, size, "unechaine/%s", a);

tronquaient a avec uniquement unechaine.

Evidemment, mon premier reflexe fut de blâmer GNU/Linux puisque ce code passait sans aucun soucis sur NetBSD, DragonFly BSD et même Solaris. Et pourtant. C’est gl qui m’informa que ce document issu de l’ISO et l’IEC explique clairement que le fait d’appeler snprintf() de la sorte rendait le résultat “imprévisible”. Dont acte.

Ainsi, j’ai imaginé la parade suivante :

Faire renvoyer le resultat malloc‘é du format string

char *
safe_snprintf(int size, const char *fmt, ...)
{
    char *p;
    va_list ap;

    XMALLOC(p, size * sizeof(char));
    va_start(ap, fmt);
    (void) vsnprintf(p, size, fmt, ap);
    va_end(ap);

    return p;
}

Puis simuler le précédent appel à snprintf via un define qui s’occuppera de libérer la destination et la faire pointer vers la chaine allouée précédemment renvoyée par safe_printf().

#define XSNPRINTF(dst, size, fmt...)            \
    do {                                        \
        char *pdst;                             \
        pdst = safe_snprintf(size, fmt);        \
        XFREE(dst);                             \
        dst = pdst;                             \
} while (/* CONSTCOND */ 0)

Je teste ce workaround en ce moment, et le résultat semble probant.

La magie de l’ELF

Tags: , ,
1 Comment »

En comparant le projet qui m’obsède jour et nuit et les outils similaires déjà existants (crunchgen(1), rescue), j’en suis venu à me poser des questions sur le cas d’un mode “full static”. Pour mémoire, BeastieBox “trouve” la fonction à appeler fonction de argv[0], et je pars du principe que chaque nom de fonction doit être construit dynamiquement. Ce tour de passe-passe est facilement geré par les fonctions dlopen(3) / dlsym(3) dans le cas d’un binaire compilé dynamiquement, mais quid d’un binaire beastiebox compilé à l’aide du swtich -static ? Point de ld.so_elf à la rescousse ici, la seule solution qui m’est apparue… c’est d’attaquer le binaire comme le fait précisemment ld.so_elf, en mmap‘ant le binaire et en l’adressant via les structures ELF.

J’ai posté l’explication dans la Mollacademy, et le code associé de BeastieBox est visible ici, ici et .

Marty, ressors la Delorean (update)

Tags: , , ,
8 Comments »

Y’a quelques jours, je me suis lancé dans un nouveau projet. Plus pour le fun que par réelle nécéssité, je me suis mis en tête d’ecrire un BusyBox-like orienté BSD. J’en suis pour le moment aux balbutiements du projet, mais quelques commandes sont déjà fonctionnelles.

Mon approche est un tantinet differente du fonctionnement de BusyBox. Afin de permettre l’écriture simple et rapide de plugins, je supporte deux modes, un mode statique (ala BB), et un mode dynamique grace aux interfaces DLFCN(3).

Ainsi, toujours sur le modèle de BB, un ln -s du programme principal vers la fonction souhaitée appellera :

  • dans le cas d’une compilation dynamique, le symbole “fonction” dans la librairie libfonction.so, par exemple command_ifconfig dans libifconfig.so
  • dans le cas d’une compilation statique, le symbole souhaité dans le propre executable en utilisant une astuce décrite ici

Afin de viser la plus petite taille possible pour l’ensemble, je suis en train de porter les outils de base d’un NetBSD 1.0, et aussi surprenant que cela puisse paraitre, le portage est relativement simple.

Si d’aucuns dans l’assemblée sont interessés par le projet, au doux nom de BeastieBox, les premiers morceaux de code sont disponibles sur SourceForge.

Update

Et maintenant, ça boot !

Update

Le projet a maintenant sa page officielle

WP Theme & Icons based on GlossyBlue by N.Design Studio
Banner from www.trynthlas.com
Entries RSS Comments RSS Log in