Fix error mapping in gethostname

Renato Silva br.renatosilva@gmail.com
Tue Mar 31 18:24:00 GMT 2015


The gethostname function has a problem where a small buffer size will
not produce an accurate errno. This is because the Windows error is
not being appropriately mapped. This causes programs such as hostname
from coreutils to fail because they are not informed about the long
name.

Changelog entry:
2015-03-31  Renato Silva  <br.renatosilva@gmail.com>
    * net.cc: Fix buffer size error handling in cygwin_gethostname.

-----

/* Test case */

#include <errno.h>
#include <stdio.h>
#include <windows.h>

int main(int argc, char **argv) {

    if (argc < 2) {
        printf("Please provide a buffer length.\n");
        return 1;
    }
    DWORD HOSTNAME_LENGTH = atoi(argv[1]);
    char hostname[HOSTNAME_LENGTH];
    char error_message[256];
    int return_value;

    printf("gethostname %s\n", gethostname(hostname, HOSTNAME_LENGTH)?
"failed" : "succeeded");
    if (errno) printf("error is %d, %s\n\n", errno, strerror(errno));
          else printf("hostname is %s\n\n", hostname);

    printf("GetComputerNameEx %s\n", (return_value =
GetComputerNameEx(ComputerNameDnsFullyQualified, hostname,
&HOSTNAME_LENGTH))? "succeeded": "failed");
    FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), error_message, 256, NULL);
    if (!return_value) printf("error is %d, %s\n", GetLastError(),
error_message);
                  else printf("hostname is %s\n", hostname);
}

-----

>From d691d4b2ac75f00a752c5dc86ab63a4ba425beda Mon Sep 17 00:00:00 2001
From: Renato Silva <br.renatosilva@gmail.com>
Date: Mon, 30 Mar 2015 20:20:49 -0300
Subject: [PATCH] Fix buffer size error handling in gethostname.

GetComputerNameEx sets a generic ERROR_MORE_DATA when buffer is too small. This
is now more accurately mapped into ENAMETOOLONG instead of the generic EPERM.
---
 winsup/cygwin/net.cc | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc
index f9b317c..02fa142 100644
--- a/winsup/cygwin/net.cc
+++ b/winsup/cygwin/net.cc
@@ -1076,7 +1076,10 @@ cygwin_gethostname (char *name, size_t len)
       if (!GetComputerNameExA (ComputerNameDnsFullyQualified, name,
                    &local_len))
         {
-          set_winsock_errno ();
+          if (GetLastError () == ERROR_MORE_DATA)
+            set_errno (ENAMETOOLONG);
+          else
+            set_winsock_errno ();
           __leave;
         }
     }
-- 
2.3.4



More information about the Cygwin-patches mailing list