Why Can't I Use Strerror

Why can't I use strerror?

strerror is deprecated because it's not thread-safe. strerror works on an internal static buffer, which may be overwritten by other, concurrent threads. You should use a secure variant called strerror_s.

The secure variant requires that the buffer size be passed to the function in order to validate that the buffer is large enough before writing to it, helping to avoid buffer overruns that could allow malicious code to execute.

Why can't the result of strerror() be returned

You are missing the inclusion of the <string.h> header file.

Documentation.

The compiler even tells you what exactly your problem is:

return makes pointer from integer without a cast

If there's no prototype present for a function, then it's assumed to return int. And it appears that on your platform, a pointer to char does not fit into an int, hence its truncated, and then printf() tries to dereference the thus invalid pointer.

Do I need to free the result of strerror() in C?

Not only do you not need to; you must not. The only things you can pass to free are pointers to memory you obtained by malloc or a function specified to return memory obtain by malloc or "as if by malloc". There is no such text in the specification of strerror, so passing the string it returns to free would produce undefined behavior. In particular, if the implementation uses malloc internally to obtain the memory, you would be freeing that memory out from under it, causing it to perform use-after-free or double-free, which are some of the most dangerous types of memory bugs.

In practice, strerror usually returns immutable strings from libc .rodata or from a mmapped translation file, and it's likely that the error would immediately be caught as a crash.

Why doesn't strerror return a const-qualified pointer?

Same as for the type of string literals: It was already like that in C89, describing a practice dating back to before the introduction of const in the language. Changing it would make current valid program invalid.

perror and strerror with close(2) involved

Standard error is where error messages are supposed to be printed. So perror() prints its error message on standard error. If you close standard error, it can't print the message.

Why is "main: Success" printed? Shouldn't every directory have the "." dir that can be opened?

Yes, it does. You didn't get an error when calling fopen(), so errno == 0, and the message for this is Success.

If you want to print an error message when fopen() fails, you need to test for NULL:

if (fopen(".") == NULL) {
printf("main: %s \n", strerror(errno));
}

Note that when opening files, the FD that's used is the lowest available FD. Since you've closed FD 2, that will most likely be used when opening .. So standard error now points to the . directory, which you can't write to, and perror() will get an error when it tries to write there. But it can't report this error (where would it report it?).

Why can't I save the numeric value of errno?

The call to printf or possibly strerror itself reset* the errno variable so the second printf prints the result of the first one, not read. Good practice is to save it as soon as possible, before any other function call.

Correct example:

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

int main(){
errno=EPERM; // An example
int read_errno = errno;
printf("errno was %s\n", strerror(read_errno));
printf("errno was %s\n", strerror(read_errno));
}

Output:

errno was Operation not permitted
errno was Operation not permitted

*They do not have to reset it, furthermore successfull call to strerror must not modify it.



Related Topics



Leave a reply



Submit