[jnr-netdb] 01/02: Merge fix from master for 'Use _r() versions of getservbyname, getservbyport, etc for linux'
Miguel Landaeta
nomadium at moszumanska.debian.org
Thu Feb 12 02:40:44 UTC 2015
This is an automated email from the git hooks/post-receive script.
nomadium pushed a commit to tag 1.0.7
in repository jnr-netdb.
commit 0b0c5af3ebd23454d39ba6bf5f198736bbc46644
Author: Wayne Meissner <wmeissner at gmail.com>
Date: Tue Jul 10 23:21:49 2012 +1000
Merge fix from master for 'Use _r() versions of getservbyname, getservbyport, etc for linux'
---
src/jnr/netdb/NativeProtocolsDB.java | 131 +++++++++++++++++++-------
src/jnr/netdb/NativeServicesDB.java | 174 ++++++++++++++++++++++++++---------
2 files changed, 228 insertions(+), 77 deletions(-)
diff --git a/src/jnr/netdb/NativeProtocolsDB.java b/src/jnr/netdb/NativeProtocolsDB.java
index ac9e61e..80dbd5e 100644
--- a/src/jnr/netdb/NativeProtocolsDB.java
+++ b/src/jnr/netdb/NativeProtocolsDB.java
@@ -18,11 +18,9 @@
package jnr.netdb;
-import com.kenai.jaffl.CallingConvention;
-import com.kenai.jaffl.Library;
-import com.kenai.jaffl.LibraryOption;
-import com.kenai.jaffl.Platform;
-import com.kenai.jaffl.Pointer;
+import com.kenai.jaffl.*;
+import com.kenai.jaffl.annotations.Direct;
+
import java.util.ArrayList;
import java.util.Collection;
@@ -38,9 +36,7 @@ import static com.kenai.jaffl.Platform.OS.*;
/**
*
*/
-final class NativeProtocolsDB implements ProtocolsDB {
-
- private final LibProto lib;
+abstract class NativeProtocolsDB implements ProtocolsDB {
public static final NativeProtocolsDB getInstance() {
return SingletonHolder.INSTANCE;
@@ -50,10 +46,6 @@ final class NativeProtocolsDB implements ProtocolsDB {
public static final NativeProtocolsDB INSTANCE = load();
}
- NativeProtocolsDB(LibProto lib) {
- this.lib = lib;
- }
-
private static final NativeProtocolsDB load() {
try {
Platform.OS os = Platform.getPlatform().getOS();
@@ -75,14 +67,19 @@ final class NativeProtocolsDB implements ProtocolsDB {
String[] libnames = os.equals(SOLARIS)
? new String[] { "socket", "nsl", "c" }
: new String[] { "c" };
- lib = Library.loadLibrary(LibProto.class, libnames);
+ lib = os.equals(LINUX)
+ ? Library.loadLibrary(LinuxLibProto.class, libnames)
+ : Library.loadLibrary(LibProto.class, libnames);
}
-
+
+ NativeProtocolsDB protocolsDB = os.equals(LINUX)
+ ? new LinuxNativeProtocolsDB((LinuxLibProto) lib)
+ : new DefaultNativeProtocolsDB(lib);
// Try to lookup a protocol to make sure the library loaded and found the functions
- lib.getprotobyname("ip");
- lib.getprotobynumber(0);
-
- return new NativeProtocolsDB(lib);
+ protocolsDB.getProtocolByName("ip");
+ protocolsDB.getProtocolByNumber(0);
+
+ return protocolsDB;
} catch (Throwable t) {
Logger.getLogger(NativeProtocolsDB.class.getName()).log(Level.WARNING, "Failed to load native protocols db", t);
return null;
@@ -99,10 +96,17 @@ final class NativeProtocolsDB implements ProtocolsDB {
UnixProtoent getprotobyname(String name);
UnixProtoent getprotobynumber(int proto);
UnixProtoent getprotoent();
+ void setprotoent(int stayopen);
void endprotoent();
}
-
- private final Protocol protocolFromNative(UnixProtoent p) {
+
+ public static interface LinuxLibProto extends LibProto{
+ int getprotobyname_r(String proto, @Direct UnixProtoent protoent, Pointer buf, NativeLong buflen, Pointer result);
+ int getprotobynumber_r(int proto, @Direct UnixProtoent protoent, Pointer buf, NativeLong buflen, Pointer result);
+ int getprotoent_r(@Direct UnixProtoent protoent, Pointer buf, NativeLong buflen, Pointer result);
+ }
+
+ static Protocol protocolFromNative(UnixProtoent p) {
if (p == null) {
return null;
}
@@ -116,26 +120,85 @@ final class NativeProtocolsDB implements ProtocolsDB {
return new Protocol(p.name.get(), (short) p.proto.get(), aliases);
}
- public Protocol getProtocolByName(String name) {
- return protocolFromNative(lib.getprotobyname(name));
- }
+ static final class DefaultNativeProtocolsDB extends NativeProtocolsDB {
+ private final LibProto lib;
+
+ DefaultNativeProtocolsDB(LibProto lib) {
+ this.lib = lib;
+ }
+
+ public synchronized Protocol getProtocolByName(String name) {
+ return protocolFromNative(lib.getprotobyname(name));
+ }
+
+ public synchronized Protocol getProtocolByNumber(Integer proto) {
+ return protocolFromNative(lib.getprotobynumber(proto));
+ }
- public Protocol getProtocolByNumber(Integer proto) {
- return protocolFromNative(lib.getprotobynumber(proto));
+ public synchronized Collection<Protocol> getAllProtocols() {
+ UnixProtoent p;
+ List<Protocol> allProtocols = new ArrayList<Protocol>();
+
+ lib.setprotoent(0);
+ try {
+ while ((p = lib.getprotoent()) != null) {
+ allProtocols.add(protocolFromNative(p));
+ }
+ } finally {
+ lib.endprotoent();
+ }
+
+ return allProtocols;
+ }
}
- public Collection<Protocol> getAllProtocols() {
- UnixProtoent p;
- List<Protocol> allProtocols = new ArrayList<Protocol>();
+ static final class LinuxNativeProtocolsDB extends NativeProtocolsDB {
+ private static final int BUFLEN = 4096;
+ private final Pointer buf;
+ private final LinuxLibProto lib;
- try {
- while ((p = lib.getprotoent()) != null) {
- allProtocols.add(protocolFromNative(p));
+
+ LinuxNativeProtocolsDB(LinuxLibProto lib) {
+ this.lib = lib;
+ this.buf = MemoryIO.allocateDirect(BUFLEN);
+ }
+
+ public synchronized Protocol getProtocolByName(String name) {
+ UnixProtoent protoent = new UnixProtoent();
+ Pointer result = MemoryIO.allocateDirect(8);
+ if (lib.getprotobyname_r(name, protoent, buf, new NativeLong(BUFLEN), result) == 0) {
+ return result.getPointer(0) != null ? protocolFromNative(protoent) : null;
}
- } finally {
- lib.endprotoent();
+
+ throw new RuntimeException("getprotobyname_r failed");
}
- return allProtocols;
+ public synchronized Protocol getProtocolByNumber(Integer number) {
+ UnixProtoent protoent = new UnixProtoent();
+ Pointer result = MemoryIO.allocateDirect(8);
+ if (lib.getprotobynumber_r(number, protoent, buf, new NativeLong(BUFLEN), result) == 0) {
+ return result.getPointer(0) != null ? protocolFromNative(protoent) : null;
+ }
+
+ throw new RuntimeException("getprotobynumber_r failed");
+ }
+
+ public synchronized Collection<Protocol> getAllProtocols() {
+ UnixProtoent p = new UnixProtoent();
+ List<Protocol> allProtocols = new ArrayList<Protocol>();
+ Pointer result = MemoryIO.allocateDirect(8);
+ NativeLong buflen = new NativeLong(BUFLEN);
+
+ lib.setprotoent(0);
+ try {
+ while (lib.getprotoent_r(p, buf, buflen, result) == 0 && result.getPointer(0) != null) {
+ allProtocols.add(protocolFromNative(p));
+ }
+ } finally {
+ lib.endprotoent();
+ }
+
+ return allProtocols;
+ }
}
}
diff --git a/src/jnr/netdb/NativeServicesDB.java b/src/jnr/netdb/NativeServicesDB.java
index a45d9ae..ac47860 100644
--- a/src/jnr/netdb/NativeServicesDB.java
+++ b/src/jnr/netdb/NativeServicesDB.java
@@ -18,11 +18,10 @@
package jnr.netdb;
-import com.kenai.jaffl.CallingConvention;
-import com.kenai.jaffl.Library;
-import com.kenai.jaffl.LibraryOption;
-import com.kenai.jaffl.Platform;
-import com.kenai.jaffl.Pointer;
+import com.kenai.jaffl.*;
+import com.kenai.jaffl.annotations.Direct;
+import com.kenai.jaffl.annotations.Out;
+
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Collection;
@@ -38,9 +37,9 @@ import static com.kenai.jaffl.Platform.OS.*;
/**
*
*/
-final class NativeServicesDB implements ServicesDB {
+abstract class NativeServicesDB implements ServicesDB {
- private final LibServices lib;
+ protected final LibServices lib;
public NativeServicesDB(LibServices lib) {
this.lib = lib;
@@ -71,18 +70,31 @@ final class NativeServicesDB implements ServicesDB {
Map<LibraryOption, Object> options = new HashMap<LibraryOption, Object>();
options.put(LibraryOption.CallingConvention, CallingConvention.STDCALL);
lib = Library.loadLibrary(LibServices.class, options, "Ws2_32");
+
} else {
String[] libnames = os.equals(SOLARIS)
- ? new String[] { "socket", "nsl", "c" }
- : new String[] { "c" };
- lib = Library.loadLibrary(LibServices.class, libnames);
+ ? new String[] { "socket", "nsl", "c" }
+ : new String[] { "c" };
+
+ if (os.equals(LINUX)) {
+ lib = Library.loadLibrary(LinuxLibServices.class, libnames);
+ } else {
+ lib = Library.loadLibrary(LibServices.class, libnames);
+ }
}
+ NativeServicesDB services = os.equals(LINUX)
+ ? new LinuxServicesDB(lib)
+ : new DefaultNativeServicesDB(lib);
// Try to lookup a service to make sure the library loaded and found the functions
- lib.getservbyname("bootps", "udp");
- lib.getservbyport(67, "udp");
+ if (services.getServiceByName("comsat", "udp") == null) {
+ return null;
+ }
+ services.getServiceByName("bootps", "udp");
+ services.getServiceByPort(67, "udp");
+
+ return services;
- return new NativeServicesDB(lib);
} catch (Throwable t) {
Logger.getLogger(NativeServicesDB.class.getName()).log(Level.WARNING, "Failed to load native services db", t);
return null;
@@ -96,60 +108,136 @@ final class NativeServicesDB implements ServicesDB {
public final String proto = new UTF8StringRef();
}
+ public static class LinuxServent extends UnixServent {
+ public static final int BUFLEN = 4096;
+ public final MemoryIO buf;
+
+ public LinuxServent() {
+ this.buf = MemoryIO.allocateDirect(BUFLEN, true);
+ }
+ }
+
public static interface LibServices {
UnixServent getservbyname(String name, String proto);
UnixServent getservbyport(Integer port, String proto);
UnixServent getservent();
void endservent();
}
-
- public Collection<Service> getAllServices() {
- UnixServent s;
- List<Service> allServices = new ArrayList<Service>();
- try {
- while ((s = lib.getservent()) != null) {
- allServices.add(serviceFromNative(s));
- }
- } finally {
- lib.endservent();
+ public static interface LinuxLibServices extends LibServices {
+ int getservbyname_r(String name, String proto, @Direct UnixServent servent,
+ Pointer buf, NativeLong buflen, @Out Pointer result);
+ int getservbyport_r(Integer port, String proto, @Direct UnixServent servent,
+ Pointer buf, NativeLong buflen, @Out Pointer result);
+ int getservent_r(@Direct UnixServent servent,
+ Pointer buf, NativeLong buflen, Pointer result);
+ }
+
+ static int ntohs(int value) {
+ int hostValue = ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN) ? Short.reverseBytes((short) value) : value;
+ if (hostValue < 0) {
+ // The byte flipping above will return numbers >= 32768 as a negative value,
+ // so they need to be converted back to a unsigned 16 bit value.
+ hostValue = ((hostValue & 0x7FFF) + 0x8000);
}
- return allServices;
+ return hostValue;
+ }
+
+ static int htons(int value) {
+ return ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN) ? Short.reverseBytes((short) value) : value;
}
- private final Service serviceFromNative(UnixServent s) {
+ static Service serviceFromNative(UnixServent s) {
if (s == null) {
return null;
}
- // servent#port is in network byte order - but jaffl will assume it is in host byte order
- // so it needs to be reversed again to be correct.
- int port = ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN) ? Short.reverseBytes((short) s.port.get()) : s.port.get();
- if (port < 0) {
- // The s_port field is really an unsigned 16 bit quantity, but the
- // byte flipping above will return numbers >= 32768 as a negative value,
- // so they need to be converted back to a unsigned 16 bit value.
- port = (int) ((port & 0x7FFF) + 0x8000);
- }
-
List<String> emptyAliases = Collections.emptyList();
Pointer ptr;
final Collection<String> aliases = ((ptr = s.aliases.get()) != null)
? StringUtil.getNullTerminatedStringArray(ptr) : emptyAliases;
- return s != null ? new Service(s.name.get(), port, s.proto.get(), aliases) : null;
+ return new Service(s.name.get(), ntohs(s.port.get()), s.proto.get(), aliases);
}
- public Service getServiceByName(String name, String proto) {
- return serviceFromNative(lib.getservbyname(name, proto));
- }
+ static final class DefaultNativeServicesDB extends NativeServicesDB {
+ DefaultNativeServicesDB(LibServices lib) {
+ super(lib);
+ }
- public Service getServiceByPort(Integer port, String proto) {
- int nport = ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN) ? Short.reverseBytes(port.shortValue()) : port.shortValue();
-
- return serviceFromNative(lib.getservbyport(nport, proto));
+ public Collection<Service> getAllServices() {
+ UnixServent s;
+ List<Service> allServices = new ArrayList<Service>();
+
+ try {
+ while ((s = lib.getservent()) != null) {
+ allServices.add(serviceFromNative(s));
+ }
+ } finally {
+ lib.endservent();
+ }
+
+ return allServices;
+ }
+
+
+ public Service getServiceByName(String name, String proto) {
+ return serviceFromNative(lib.getservbyname(name, proto));
+ }
+
+ public Service getServiceByPort(Integer port, String proto) {
+ return serviceFromNative(lib.getservbyport(htons(port), proto));
+ }
}
+ static final class LinuxServicesDB extends NativeServicesDB {
+ private static final int BUFLEN = 4096;
+ private final LinuxLibServices lib;
+ private final Pointer buf;
+
+ LinuxServicesDB(LibServices lib) {
+ super(lib);
+ this.lib = (LinuxLibServices) lib;
+ this.buf = MemoryIO.allocateDirect(BUFLEN);
+ }
+
+ public synchronized Service getServiceByName(String name, String proto) {
+ UnixServent servent = new UnixServent();
+ Pointer result = MemoryIO.allocateDirect(8);
+ if (lib.getservbyname_r(name, proto, servent, buf, new NativeLong(BUFLEN), result) == 0) {
+ return result.getPointer(0) != null ? serviceFromNative(servent) : null;
+ }
+
+ throw new RuntimeException("getservbyname_r failed");
+ }
+
+ public synchronized Service getServiceByPort(Integer port, String proto) {
+ UnixServent servent = new UnixServent();
+ Pointer result = MemoryIO.allocateDirect(8);
+ if (lib.getservbyport_r(htons(port), proto, servent, buf, new NativeLong(BUFLEN), result) == 0) {
+ return result.getPointer(0) != null ? serviceFromNative(servent) : null;
+ }
+
+ throw new RuntimeException("getservbyport_r failed");
+ }
+
+ public synchronized Collection<Service> getAllServices() {
+ UnixServent s = new UnixServent();
+ List<Service> allServices = new ArrayList<Service>();
+ Pointer result = MemoryIO.allocateDirect(8);
+ NativeLong buflen = new NativeLong(BUFLEN);
+
+ try {
+ while (lib.getservent_r(s, buf, buflen, result) == 0 && result.getPointer(0) != null) {
+ allServices.add(serviceFromNative(s));
+ }
+ } finally {
+ lib.endservent();
+ }
+
+ return allServices;
+ }
+ }
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/jnr-netdb.git
More information about the pkg-java-commits
mailing list