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