关于glibc wordexp 接口的实现,有一处不太明白,请教大神。
接口如下:
int wordexp (const char *words, wordexp_t *pwordexp, int flags)
看了一下glibc的实现,当flag为WRDE_REUSE时,会先释放pwordexp,然后再调用calloc重新申请内存,这种操作时如何做到复用pwordexp原来的内存的?
代码段如下:
int
wordexp (const char *words, wordexp_t *pwordexp, int flags)
{
size_t words_offset;
size_t word_length;
size_t max_length;
char *word = w_newword (&word_length, &max_length);
int error;
char *ifs;
char ifs_white[4];
wordexp_t old_word = *pwordexp;
if (flags & WRDE_REUSE) /*** 这里会释放pwordexp->we_wordv ***/
{
/* Minimal implementation of WRDE_REUSE for now */
wordfree (pwordexp);
old_word.we_wordv = NULL;
}
if ((flags & WRDE_APPEND) == 0)
{
pwordexp->we_wordc = 0;
if (flags & WRDE_DOOFFS)
{
pwordexp->we_wordv = calloc (1 + pwordexp->we_offs, sizeof (char *));
if (pwordexp->we_wordv == NULL)
{
error = WRDE_NOSPACE;
goto do_error;
}
}
else
{
pwordexp->we_wordv = calloc (1, sizeof (char *)); /*** 此处调用calloc重新为we_wordv申请内存 ***/
if (pwordexp->we_wordv == NULL)
{
error = WRDE_NOSPACE;
goto do_error;
}
pwordexp->we_offs = 0;
}
}
wordfree的实现源码如下:
void
wordfree (wordexp_t *pwordexp)
{
/* wordexp can set pwordexp to NULL */
if (pwordexp && pwordexp->we_wordv)
{
char **wordv = pwordexp->we_wordv;
for (wordv += pwordexp->we_offs; *wordv; ++wordv)
free (*wordv);
free (pwordexp->we_wordv);
pwordexp->we_wordv = NULL;
}
}
flags枚举:
enum
{
WRDE_DOOFFS = (1 << 0), /* Insert PWORDEXP->we_offs NULLs. */
WRDE_APPEND = (1 << 1), /* Append to results of a previous call. */
WRDE_NOCMD = (1 << 2), /* Don't do command substitution. */
WRDE_REUSE = (1 << 3), /* Reuse storage in PWORDEXP. */
WRDE_SHOWERR = (1 << 4), /* Don't redirect stderr to /dev/null. */
WRDE_UNDEF = (1 << 5), /* Error for expanding undefined variables. */
__WRDE_FLAGS = (WRDE_DOOFFS | WRDE_APPEND | WRDE_NOCMD |
WRDE_REUSE | WRDE_SHOWERR | WRDE_UNDEF)
};