What could possible by the problem when the errno value is not updated during successive calls to socket functions?
socket (AF_INET, -1, 0);
socket (AF_INET, SOCK_STREAM, -1);
The first should have errno = EINVAL
The second should have errno = EPROTONOSUPPORT
From the code provided below by @JonathanLeffler, output from cygwin is as follows:
*$ ./socket.exe
Error from socket(AF_INET, -1, 0): 124 (Socket type not supported)
-- errno = 124 (Socket type not supported)
Error from socket(AF_INET, SOCK_STREAM, -1): 123 (Protocol not supported)
-- errno = 123 (Protocol not supported)
socket(AF_INET, SOCK_STREAM, 0) succeeded (fd = 3)
-- errno = 123 (Protocol not supported)*
The said code below was edited to create a socket fd0 before creating the socket
int fd0 = socket(AF_INET, SOCK_STREAM, 0);
if (fd0 < 0)
printf("Error from socket(AF_INET, SOCK_STREAM, 0): %d (%s)\n", errno, strerror(errno));
else
{
printf("socket(AF_INET, SOCK_STREAM, 0) succeeded (fd = %d)\n", fd0);
close(fd0);
}
printf("-- errno = %d (%s)\n", errno, strerror(errno));
int fd1 = socket(AF_INET, -1, 0);
.....
And the result is as follows:
*$ ./socket.exe
socket(AF_INET, SOCK_STREAM, 0) succeeded (fd = 3)
-- errno = 0 (No error)
Error from socket(AF_INET, -1, 0): 124 (Socket type not supported)
-- errno = 124 (Socket type not supported)
Error from socket(AF_INET, SOCK_STREAM, -1): 123 (Protocol not supported)
-- errno = 123 (Protocol not supported)
socket(AF_INET, SOCK_STREAM, 0) succeeded (fd = 3)
-- errno = 123 (Protocol not supported)*
It is expected that the first and the last socket creation should have the same errno values.
But how can this output be explained? 5th and 6th socket creation have the same errno value but the cause of the error is different.
$ ./test_select.exe
[1] ierr = 124, iSocket = -1 socket(AF_INET, -1, 0);
: Socket type not supported
[2] ierr = 124, iSocket = -1 socket(AF_INET, -1, 0);
: Socket type not supported
[3] ierr = 124, iSocket = 3 socket(AF_INET, SOCK_STREAM, 0);
: Socket type not supported
[4] ierr = 124, iSocket = -1 socket (AF_INET, -1, 0);
: Socket type not supported
[5] ierr = 123, iSocket = -1 socket (AF_INET, SOCK_STREAM, -1);
: Protocol not supported
[6] ierr = 123, iSocket = -1 socket (AF_INET, -1, 0)
: Protocol not supported
[7] ierr = 124, iSocket = -1 socket(AF_INET, SOCK_STREAM, -1)
: Protocol not supported
Actual code is as follows:
sockfd = socket(AF_INET, -1, 0);
err = errno;
printf("[1] err = %d, sockfd = %d socket(AF_INET, -1, 0);\n", err, sockfd);
perror(" ");
sockfd = socket(AF_INET, -1, 0);
err = errno;
printf("[2] err = %d, sockfd = %d socket(AF_INET, -1, 0);\n", err, sockfd);
perror(" ");
sockfd = socket(AF_INET, SOCK_STREAM, 0);
err = errno;
printf("[3] err = %d, sockfd = %d socket(AF_INET, SOCK_STREAM, 0);\n", err, sockfd);
perror(" ");
close(sockfd);
sockfd = socket(AF_INET, -1, 0);
err = errno;
printf("[4] err = %d, sockfd = %d socket (AF_INET, -1, 0);\n", err, sockfd);
perror(" ");
sockfd = socket(AF_INET, SOCK_STREAM, -1);
err = errno;
printf("[5] err = %d, sockfd = %d socket (AF_INET, SOCK_STREAM, -1);\n", err, sockfd);
perror(" ");
sockfd = socket(AF_INET, -1, 0);
err = errno;
printf("[6] err = %d, sockfd = %d socket (AF_INET, -1, 0)\n", err, sockfd);
perror(" ");
err = errno;
sockfd = socket(AF_INET, SOCK_STREAM, -1);
printf("[7] err = %d, sockfd = %d socket(AF_INET, SOCK_STREAM, -1)\n", err, sockfd);
perror(" ");
No library function sets
errnoto zero. If you want it zeroed, your program must do it.You can only meaningfully test
errnofor information when a function says it has failed (and even then, only if its manual page indicates that it setserrno). You can finderrnoset to non-zero by a successful function. For example, on Solaris, you’ll often find ENOTTY inerrnoafter a standard I/O call when writing to a file instead of a terminal.In your example, there’s no guarantee about which of multiple possible error values will be set by a given erroneous call to a function. As long as one valid error condition is reported, it is up to the system to decide which error it reports. So, you’d need to give a compelling example of why the second call should return EINVAL instead of EBADF; your question as written doesn’t include enough information to let us pontificate.
Also note that the only safe way to declare
errnois via the header:#include <errno.h>. In threaded environments in particular, it is often not simplyextern int errno;. For example, on Mac OS X, it can be defined as:That is,
__erroris a function returning a pointer to an integer, anderrnois a macro that dereferences that pointer, becoming a modifiable lvalue.Code Analysis
The given code is:
Converted into runnable code, this might become:
Running on Mac OS X 10.7.3, this produces:
As I said earlier, the error returned depends on the system.