GetLastError(), errno, FormatMessageA() and strerror_s()?
Asked Answered
D

1

22

I'm confused as to the exact relationship between GetLastError() and errno. Are they the same numerical values, or something completely different? How do I know which one I should check?

And if I want to convert an error code to a string for debugging, can I use FormatMessageA() interchangeably with strerror_s()?

Lastly, is it true that WSAGetLastError() always returns the same as GetLastError(), or could they both return different values?

Dalessio answered 18/11, 2013 at 20:8 Comment(6)
GetLastError and FormatMessage are for Win32 errors. errno and strerror are for C runtime errors. They are unrelated. Each function documents which error code it sets.Gunzburg
possible duplicate of Is WSAGetLastError() just an alias for GetLastError()?Gunzburg
@RaymondChen but a socket errors are not c-runtime. Anyway I successfully use errnorelated functions in my program. Does this means that on Windows the perror() and strerror() is different from one's Win32 API? It is really interesting question: I am porting right now a little application from a GNU/Linux, and it wouldn't be good if strerror() suddenly refused to print a network errors.Anthracene
@Anthracene The FormatMessage function can be used to obtain the message string for the returned error.Blatt
@Blatt I know it, that wasn't what I meant. I was wondering if I could use errno to get at least an error of a sockets. But now I already know, that isn't. Tbh I have no idea why someone could use a errno at all in Windows. What kind of errors in principle could I got? In *nix I can got via errno almost everything, but Windows doesn't seem to use it at all. Although it is a standard. This is sad.Anthracene
@Anthracene if you call a C function fopen in a way like this: fopen("test.txt", "ABC"), then EINVAL might be set to errno... (I haven't tested it by myself, sorry)Blatt
B
25

There is no relationship between GetLastError and errno.

GetLastError gets the last error that was set by a Windows API function (for the current thread), while errno contains the last error that was stored into it by a C runtime library function (also for the current thread).

Almost all WinAPI functions, that return errors to their callers, will indicate in some way when an error occurs, and then set the error for the caller to get by calling GetLastError. NOTE: Not all WinAPI functions return errors to their callers.

For example, the documentation for the WinAPI function CreateFile says:

If the function succeeds, the return value is an open handle to the specified file, device, named pipe, or mail slot. If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError.

The C runtime library functions that return errors to their callers, will indicate in some way when an error occurs and then store a value in errno. NOTE: Not all C runtime library functions return errors to their callers.

For example, the documentation for the C runtime library function sqrt says:

The sqrt function computes the nonnegative square root of its argument. A domain error occurs if its argument is negative.

The documentation on domain errors says:

On a domain error, the function returns an implementation-defined value; and the value EDOM is stored in errno.

The values returned by GetLastError are not the same as the values stored in errno, so I think that answers the question about using FormatMessage and strerror_s.

I don't know if WSAGetLastError always returns the same values as GetLastError (although I notice that the list of error codes returned by GetLastError does include the error codes that WSAGetLastError can return). See System Error Codes (9000-11999). If you look at the error codes starting at around 10000 you will see the WSAGetLastError error codes.

In any case, I personally would not rely on them returning the same values. Why would that be useful? Just follow the documentation and call WSAGetLastError for Winsock2 functions, and GetLastError for other WinAPI functions. NOTE: You can use FormatMessage on the error codes returned by either function.

Bluetongue answered 18/11, 2013 at 20:37 Comment(6)
I know that the original question didn't have Linux in mind but since C Runtime is common in both Windows and Linux and Win32 API obviously doesn't exist on Linux, would using errno be useful in that case?Caddric
@Caddric I'm sorry, I don't understand. What do you mean by "would using errno be useful in that case".Bluetongue
What I mean to ask is 'does errno replace GetLastError() on Linux'?Caddric
@Caddric I don't understand what you mean by "replace", there are two sets of functions with two different ways of indicating errors. As I said in the answer to the original question, "if you call a winapi function, like CreateFile, you check GetLastError (assuming that the function call failed), while if you call a C Standard Library function, like sqrt, you check errno (again assuming that the call failed)".Bluetongue
Sorry, what I mean is apparently there is no Win32 API on Linux, so we are left with C Standard Library functions for fetching the error. Seems like that is the only way to do it as an alternative. And I was just asking if there is anything else that can be used in Linux.Caddric
@Caddric yes, on Linux and other UNIX-likes, errno is generally the API we use to get the last operating system error.Inequity

© 2022 - 2024 — McMap. All rights reserved.