class Socket < IO
enum Family : LibC::SaFamilyT
UNSPEC = LibC::AF_UNSPEC
UNIX = LibC::AF_UNIX
INET = LibC::AF_INET
INET6 = LibC::AF_INET6
end
def initialize(@family, @type, @protocol = Protocol::IP, blocking = false)
This is the list from man page:
Name Purpose Man page
AF_UNIX, AF_LOCAL Local communication unix(7)
AF_INET IPv4 Internet protocols ip(7)
AF_INET6 IPv6 Internet protocols ipv6(7)
AF_IPX IPX - Novell protocols
AF_NETLINK Kernel user interface device netlink(7)
AF_X25 ITU-T X.25 / ISO-8208 protocol x25(7)
AF_AX25 Amateur radio AX.25 protocol
AF_ATMPVC Access to raw ATM PVCs
AF_APPLETALK AppleTalk ddp(7)
AF_PACKET Low level packet interface packet(7)
AF_ALG Interface to kernel crypto API
My question is: what should I do to achieve the result of this call?
socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE) = 3
Is there an easy way to extend the enum with libc values?
Looking at other languages, it seems netlink isn’t provided in the standard library (maybe because it’s only a linux thing?). This is Ruby, This is Go. So my advice is to write a library for this.
However, I think the current Socket code is wrong. These things are not enums in C so they shouldn’t be enums in Crystal, exactly because their values shouldn’t be a fixed set (new types could be added in the future and we don’t want to fix the std to a fixed set).
Could you open an issue for this? And a PR would also be welcome (just turn those enum members into constants). Thank you!
(that way you could write a library and pass any Int32 as the value of @family and you could pass the one for AF_NETLINK without a problem)
Creating a PR would be a bit difficult for me, I never did this before and will have to learn how github works in this regard. I understand that it’s probably a trivial problem for you guys, maybe I will do that sometime in the future.
On a related note, I have another question. Is it possible to use C defines from Crystal? What I mean is do I have to track down the value of AF_NETLINK in header files to determine its int value (it’s 16 I think), or is there a wrapper of any type so that it gets looked up during the build?
Impossible, these aren’t exposed by C libraries, they are C compile-time values.
Maybe it would be possible using clang, but it would have to be run on each compilation… kind of. So for now we just manually copy the values.
Don’t worry about the PR, I might do it later.
1 Like
@asterite how should we proceed with this, it will be probably a compatibility break change.
How could we be solving it, the enums are being used for typing params like family : Family = Family::INET. Should we replace with family : SaFamilyT = INET)?
Yes, I don’t know. I started doing that and stumbled upon the same problem/decision-point. But I’ll do it soon, don’t worry.
1 Like
If it really needs to be hypertyped, how about something like this?
abstract struct Socket::Family
abstract def value : LibC::SaFamilyT
end
struct Socket::Family::INET < Socket::Family
def value
LibC::AF_INET
end
end