implement socket.getservbyname
@@ -498,6 +498,25 @@ fn socket_inet_ntoa(packed_ip: PyBytesRef, vm: &VirtualMachine) -> PyResult {
Ok(vm.ctx.new_str(Ipv4Addr::from(ip_num).to_string()))
}
+fn socket_getservbyname(
+ servicename: PyStrRef,
+ protocolname: OptionalArg<PyStrRef>,
+ vm: &VirtualMachine,
+) -> PyResult {
+ use std::ffi::CString;
+ let cstr_name = CString::new(servicename.borrow_value())
+ .map_err(|_| vm.new_value_error("embedded null character".to_owned()))?;
+ let protocolname = protocolname.as_ref().map_or("", |s| s.borrow_value());
+ let cstr_proto = CString::new(protocolname)
+ .map_err(|_| vm.new_value_error("embedded null character".to_owned()))?;
+ let serv = unsafe { c::getservbyname(cstr_name.as_ptr(), cstr_proto.as_ptr()) };
+ if serv.is_null() {
+ return Err(vm.new_os_error("service/proto not found".to_owned()));
+ }
+ let port = unsafe { (*serv).s_port };
+ Ok(vm.ctx.new_int(u16::from_be(port as u16)))
+}
+
#[derive(FromArgs)]
struct GAIOptions {
#[pyarg(positional)]
@@ -795,6 +814,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
"inet_ntop" => ctx.new_function(socket_inet_ntop),
"getprotobyname" => ctx.new_function(socket_getprotobyname),
"getnameinfo" => ctx.new_function(socket_getnameinfo),
+ "getservbyname" => ctx.new_function(socket_getservbyname),
// constants
"AF_UNSPEC" => ctx.new_int(0),
"AF_INET" => ctx.new_int(c::AF_INET),
