Socket or file descriptor ?
-
1. What does "socket" function returns ? "socket " (# ?) or "file descriptor
for the new socket
"? 2. If it returns "error" - how can I actually read it / get it in human / verbose format ? ...and if my questions are so basic EVERYBODY knows the answer... do not bother - RTFM is not an answer I am looking for...
/* Create a new socket of type TYPE in domain DOMAIN, using
protocol PROTOCOL. If PROTOCOL is zero, one is chosen automatically.
Returns a file descriptor for the new socket, or -1 for errors. */
extern int socket (int __domain, int __type, int __protocol) __THROW; -
1. What does "socket" function returns ? "socket " (# ?) or "file descriptor
for the new socket
"? 2. If it returns "error" - how can I actually read it / get it in human / verbose format ? ...and if my questions are so basic EVERYBODY knows the answer... do not bother - RTFM is not an answer I am looking for...
/* Create a new socket of type TYPE in domain DOMAIN, using
protocol PROTOCOL. If PROTOCOL is zero, one is chosen automatically.
Returns a file descriptor for the new socket, or -1 for errors. */
extern int socket (int __domain, int __type, int __protocol) __THROW;It returns an
int
. That int is similar to what you would get fromopen(2)
, and can be used in many places any other file descriptor could be - e.gread(2)
,write(2)
, and, of course,close(2)
. I think that somefcntl(2)
operations are also valid for socket fds. But you'll probably get a error if you try to uselseek(2)
on a socket. If you prefer, its a file descriptor that describes a socket. Just likeopen("/dev/ttyS0", O_RDWR)
returns a file descriptor that describes a serial port andopen("data.txt", O_WRONY|O_CREAT, 0660)
returns a file descriptor that describes (presumbably) a text file in the CWD, oropen("/tmp/mypipe", O_RDONLY)
returns a file descriptor that might be a named pipe. NB: in the notationopen(2)
the(2)
refers to the manual section that describes the system. So for exampleman 1 stat
produces the man page for thestat
command, whereasman 2 stat
produces the man page for thestat
system call.Keep Calm and Carry On
-
1. What does "socket" function returns ? "socket " (# ?) or "file descriptor
for the new socket
"? 2. If it returns "error" - how can I actually read it / get it in human / verbose format ? ...and if my questions are so basic EVERYBODY knows the answer... do not bother - RTFM is not an answer I am looking for...
/* Create a new socket of type TYPE in domain DOMAIN, using
protocol PROTOCOL. If PROTOCOL is zero, one is chosen automatically.
Returns a file descriptor for the new socket, or -1 for errors. */
extern int socket (int __domain, int __type, int __protocol) __THROW; -
1. What does "socket" function returns ? "socket " (# ?) or "file descriptor
for the new socket
"? 2. If it returns "error" - how can I actually read it / get it in human / verbose format ? ...and if my questions are so basic EVERYBODY knows the answer... do not bother - RTFM is not an answer I am looking for...
/* Create a new socket of type TYPE in domain DOMAIN, using
protocol PROTOCOL. If PROTOCOL is zero, one is chosen automatically.
Returns a file descriptor for the new socket, or -1 for errors. */
extern int socket (int __domain, int __type, int __protocol) __THROW;Member 14968771 wrote:
If it returns "error" - how can I actually read it / get it in human / verbose format ?
Just noting that in my experience what the number means, even if you can map it, is very seldom useful. In general it can only mean about two things. 1. You passed in an incorrect parameter. But it will tell you nothing about what or why it is wrong. 2. The system is way overloaded. It too will tell you nothing about what is specifically overloaded. And just to be clear the error here has nothing to do with actually communicating.
-
Member 14968771 wrote:
If it returns "error" - how can I actually read it / get it in human / verbose format ?
Just noting that in my experience what the number means, even if you can map it, is very seldom useful. In general it can only mean about two things. 1. You passed in an incorrect parameter. But it will tell you nothing about what or why it is wrong. 2. The system is way overloaded. It too will tell you nothing about what is specifically overloaded. And just to be clear the error here has nothing to do with actually communicating.
I do appreciate all constructive replies, however , I need to further expand on the subject.
/* Create a new socket of type TYPE in domain DOMAIN, using
protocol PROTOCOL. If PROTOCOL is zero, one is chosen automatically.
Returns a file descriptor for the new socket, or -1 for errors. */
extern int socket (int __domain, int __type, int __protocol) __THROW;/* Create two new sockets, of type TYPE in domain DOMAIN and using
protocol PROTOCOL, which are connected to each other, and put file
descriptors for them in FDS[0] and FDS[1]. If PROTOCOL is zero,
one will be chosen automatically. Returns 0 on success, -1 for errors. */
extern int socketpair (int __domain, int __type, int __protocol,
int __fds[2]) __THROW;/* Give the socket FD the local address ADDR (which is LEN bytes long). */
extern int bind (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len)
__THROW;/* Put the local address of FD into *ADDR and its length in *LEN. */
extern int getsockname (int __fd, __SOCKADDR_ARG __addr,
socklen_t *__restrict __len) __THROW;The initial post was relatively pretty self explanatory - the return value IS indeed file descriptor... I am attempting to take another stab at the "replacing RS232 with Bluetooth "... and in the current example I could use some explanation. In the example - type / domain passed to "socket" is
AF_INET
, however the socket man clearly suggest to use
AF_BLUETOOTH
BUT if the "protocol" is NULL - the domain type will be "selected automatically ".... SO which way is up AF_BLUETOOTH or "automatic"? I am still missing how to get verbose error - how do I implement "_TROW"? I really need as much as info about what is missing in my code - the example I am using is of course undocumented... As far s the real code goes - after I get the initial "socket" the code fails to "bind " - my guess it is act8ually missing the address of the "end point".... to bind to...
-
I do appreciate all constructive replies, however , I need to further expand on the subject.
/* Create a new socket of type TYPE in domain DOMAIN, using
protocol PROTOCOL. If PROTOCOL is zero, one is chosen automatically.
Returns a file descriptor for the new socket, or -1 for errors. */
extern int socket (int __domain, int __type, int __protocol) __THROW;/* Create two new sockets, of type TYPE in domain DOMAIN and using
protocol PROTOCOL, which are connected to each other, and put file
descriptors for them in FDS[0] and FDS[1]. If PROTOCOL is zero,
one will be chosen automatically. Returns 0 on success, -1 for errors. */
extern int socketpair (int __domain, int __type, int __protocol,
int __fds[2]) __THROW;/* Give the socket FD the local address ADDR (which is LEN bytes long). */
extern int bind (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len)
__THROW;/* Put the local address of FD into *ADDR and its length in *LEN. */
extern int getsockname (int __fd, __SOCKADDR_ARG __addr,
socklen_t *__restrict __len) __THROW;The initial post was relatively pretty self explanatory - the return value IS indeed file descriptor... I am attempting to take another stab at the "replacing RS232 with Bluetooth "... and in the current example I could use some explanation. In the example - type / domain passed to "socket" is
AF_INET
, however the socket man clearly suggest to use
AF_BLUETOOTH
BUT if the "protocol" is NULL - the domain type will be "selected automatically ".... SO which way is up AF_BLUETOOTH or "automatic"? I am still missing how to get verbose error - how do I implement "_TROW"? I really need as much as info about what is missing in my code - the example I am using is of course undocumented... As far s the real code goes - after I get the initial "socket" the code fails to "bind " - my guess it is act8ually missing the address of the "end point".... to bind to...
Unless you're hacking on glibc, you really shouldn't be digging around in the system include files. Nevertheless, doing some googling around I learned this:
k5054@localhost]$ cpp -include stdlib.h -dM /dev/null | grep -E 'define __(THROW|LEAF)\>'
#define __LEAF , __leaf__
#define __THROW __attribute__ ((__nothrow__ __LEAF))
[k5054@localhost]$That means that the __THROW notation adds the attributes nothrow and leaf to the definition of the function. You can read up on them here:[Function Attributes - Using the GNU Compiler Collection (GCC)](https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Function-Attributes.html) Surely by now you know how to handle libc errors:
#include
#includeint ret = socket(foo, bar, baz); // socket() returns -1 on error and sets global var errno
if(ret == -1 ) {
switch (errno) {
case EACCES:
// handle EACCES issue
break;
// etc.
default:
// print out the text associated with the error using strerror()
std::cerr << "socket() returned error " << strerror(errno) << '\n';
}
}Note: It is perfectly possible for
errno
to be set by a system call, even when the system call is successful. That can happen when the system call itself makes another system call, which sets errno. I ran into this not so long ago with code like:errno = 0;
ret = somefn(blah, blah, blah);
if (errno) {
// do stuff
}In this case
somefn()
calledotherfn()
to do its work.otherfn()
failed, setting errno in the process, and thensomfn
handled the error, and perhaps calledanotherfn()
which succeded, but did not set errno back to zero. Moral of the story: you need to check if your system call returned an error (normally -1, but not neccesarily), and then check the value of errno.Keep Calm and Carry On