Es soll ja alte Systeme geben, auf den die Funktion strdup() noch nicht vorhanden ist. Sun OS 3 ist angeblich so ein Kandidat. Nun, was macht man, wenn man diese Funktion nicht zur Verfuegung hat? Man implementiert sie selbst. Und hier ist das grosse Problem: kaum einer macht es richtig. Vor ein paar Wochen hab ich einen Patch an den fetchmail-Maintainer (gluecklicherweise hat ESR das abgegeben) deswegen geschickt. Und was sehe ich heute in der APR (die Apache Portable Runtime)? Dieses da:
#if !APR_HAVE_STRDUP
char *strdup(const char *str)
{
char *sdup;
size_t len = strlen(str) + 1;
sdup = (char *) malloc(len);
memcpy(sdup, str, len);
return sdup;
}
#endif
Zum Haare raufen. Also bin ich auf die Idee gekommen, einfach Google Codesearch zu verwenden, um eigene strdup()-Implementierungen zu finden. Tja, und das ging ziemlich schnell.
Hier z.B..
char*
enca_strdup(const char *s) {
if (s == NULL)
return NULL;
else
return strcpy(enca_malloc(strlen(s) + 1), s);
}
enca_malloc() enthaelt uebrigens keinerlei Pruefung auf NULL, ausser ein assert(), d.h. wenn man mit CFLAGS=-DNDEBUG compiled, und in eine OOM-Situation geraet, fuehrt das zum gleichen Mist. Und auch MySQL
sieht sehr vertrauenswuerdig aus:
#ifndef HAVE_STRDUP
char *
strdup(const char *s){
void *p2;
p2 = malloc(strlen(s)+1);
strcpy(p2, s);
return p2;
}
#endif
Und das in einer Datenbank von angeblicher Produktionsqualitaet. *ts*
Fazit: drei strdup()-Implementierungen begutachtet, keine einzige macht es richtig.