0

I am trying to compile the following program on linux

#include<stdio.h>
#include <netdb.h>

int main(){
    char *name="localhost";
    extern int h_errno;
    h_errno = 0;
    struct hostent *h;
    struct hostent **res;
    struct hostent hp_allocated;
    char buf[16384];
    int buf_len = (sizeof buf) - 1;
    int errnop;
    errnop = 0;
    char ** pch;

    h = gethostbyname(name);
    if(h_errno == HOST_NOT_FOUND){
        printf("HOST NOT FOUND\n");
    }

    if(h!=NULL){
        if (h->h_aliases) {
            printf("in this if now\n");
            for (pch = h->h_aliases; *pch != NULL; pch++) {
                printf("name of alias is %s\n", *pch);
                endhostent();
            }
            printf("end of this if now\n");
        }
    }

    return 0;
}

whenever I try to run, I get the following output,

HOST NOT FOUND
in this if now
name of alias is ip6-localhost
name of alias is ip6-loopback
end of this if now

even though it is populating the hostent structure(i.e h variable) returned by gethostbyname it is still raising host not found error. any suggestions on where this is going wrong or how to fix this?

Is it supposed to behave like this by default. If so how to resolve host not found error by correcting the program?

  • 2
    Like normal `errno`, the value of `h_errno` is *indeterminate* unless the call to `gethostbyname_r` actually fails. You need to check for it to fail *first*, and only then check `h_errno`. – Some programmer dude Feb 23 '23 at 09:03
  • 2
    And what's more, the error is set in the variable `errnop` (pointed to by the last argument to `gethostbyname_r`). – Some programmer dude Feb 23 '23 at 09:06
  • Lastly, `h_errno`, together with e.g. `gethostbyname`, were made obsolete in the POSIX.1-2008 standard, so you should not use the global `h_errno` at all. And really should not use `gethostbyname_r` either, in favor of [`getaddrinfo`](https://man7.org/linux/man-pages/man3/getaddrinfo.3.html) or [`getnameinfo`](https://man7.org/linux/man-pages/man3/getnameinfo.3.html). – Some programmer dude Feb 23 '23 at 09:07
  • errnop is also set to 1 in my case. how to get this program working for the name "localhost" without giving any errors. – 29_MOHAMMED_ZUHAIB Feb 23 '23 at 09:18
  • Like I said, the value is indeterminate (and should not be checked) unless the function actually fails and returns a `NULL` pointer. But what's worse is that is that you use the function wrongly. See e.g. [this manual page of `gethostbyname_r`](https://man7.org/linux/man-pages/man3/gethostbyname.3.html). The function does not return a pointer. Doesn't the compiler complain about mismatching types? – Some programmer dude Feb 23 '23 at 09:24
  • 1
    The version that I am using is from HAVE_GETHOSTBYNAME_R_5_ARG, which returns a struct hosent *. this gethostbyname_r has five arguments and it might be old implementation. Nevertheless I am facing the same issue with gethostbyname as well which returns struct hosent * as well. – 29_MOHAMMED_ZUHAIB Feb 23 '23 at 09:28
  • You should enable all compiler warnings and fix them. The return value of `gethostbyname_r` is `int` and you assign it to `struct hostent *h` and later dereference the invalid pointer. This is undefined behavior and probably leads to a segmentation fault. I just noticed your comment about returning a `struct hosent *`. Add your OS and version and compiler and library versions to the question. – Bodo Feb 23 '23 at 09:43
  • 1
    let us ignore gethostbyname_r altogether and focus only on gethostbyname. so since gethostbyname is working and also setting errnop should I ignore that and work as it is? – 29_MOHAMMED_ZUHAIB Feb 23 '23 at 09:53
  • Print the value of `struct hostent *h` and the address `&struct hostent hp_allocated` as pointers and show the result. – Bodo Feb 23 '23 at 09:54
  • 0x7f32c0bed1c0 this is h and 0x7ffca022efd0 this is &hp_allocated – 29_MOHAMMED_ZUHAIB Feb 23 '23 at 09:59
  • Please [edit] your question and add all requested information or clarification to the question. Please always copy&paste the code and the corresponding output. Add details about OS, compiler, library. Add details about what you want to achieve. Why don't you use `getaddrinfo` as already suggested? Regarding aliases see also https://stackoverflow.com/a/1474643/10622916 – Bodo Feb 23 '23 at 10:14
  • 1
    The OS I am currently using is Ubuntu 16.04.1. what I want to achieve is to have this program run fine without giving any value in h_errno. I am not using getaddrinfo because I am trying to build python from open source and my machine is using the call in python test case test_urllib, i.e call to gethostbyname from socketmodule.c. so I want this to work without giving h_errno as error for fetching details of host "localhost" from my machine. – 29_MOHAMMED_ZUHAIB Feb 23 '23 at 10:24
  • 1
    unless h is NULL, h_errno has no meaning. – stark Feb 23 '23 at 12:44
  • @29_MOHAMMED_ZUHAIB *what I want to achieve is to have this program run fine without giving any value in h_errno.* The value in `h_errno` is irrelevant unless the call to `gethostbyname()` fails. If the call returns a non-`NULL` value, you shouldn't even be accessing `h_errno` because it provides zero information after a successful call. – Andrew Henle Feb 23 '23 at 13:30

0 Answers0