Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does `gethostbyname` return `struct hostent *` without requiring the caller to release the resource?

struct hostent *gethostbyname(const char *name)

Note that hostent.h_addr_list is a field with variant length.

How does the function gethostbyname have the implementation that returns a pointer pointing to a struct but doesn't require the caller to release the resource?

All examples used in the famous book Unix Network Programming Vol 1 by R. Stevens do not contain code to release those returned pointers and I assume that these are not ignorance. Also one example from MSDN does the same thing example of usage

like image 222
q0987 Avatar asked Jul 18 '12 15:07

q0987


2 Answers

The man page you link to holds the answer:

When non-NULL, the return value may point at static data, see the notes below.

And a little later:

The functions gethostbyname() and gethostbyaddr() may return pointers to static data, which may be overwritten by later calls.

like image 191
twalberg Avatar answered Nov 03 '22 09:11

twalberg


Supposing that an implementation wants to to handle arbitrarily large lists of addresses, it could do something like this:

struct hostent *gethostbyname(const char *name) {
    static struct hostent *results = 0;
    static size_t resultsize = 0;
    size_t count = get_count_of_addresses(name)
    if (count > resultsize) {
        struct hostent *tmp = realloc(results, N * count + M);
        if (tmp) {
            results = tmp;
            resultsize = count;
        } else {
            // handle error, I can't remember what the docs say
        }
    }
    fill_in_hostent(results, name);
    return results;
};

Optionally, the sockets library could do something to free results on exit (such as install an atexit handler), to avoid debugging tools reporting a memory leak.

I've ignored the possibility that the count of addresses could change in between sizeing the structure and filling it in -- in practice you'd get the DNS result back and then do stuff with it, so that would not be possible. I've left it as two separate calls to avoid introducing a pseudo-code representation for the DNS result.

like image 25
Steve Jessop Avatar answered Nov 03 '22 07:11

Steve Jessop