1 /*
   2  * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package java.nicl;
  24 
  25 import java.lang.invoke.MethodHandles.Lookup;
  26 import java.io.File;
  27 import java.util.Objects;
  28 import jdk.internal.nicl.LibrariesHelper;
  29 
  30 public final class Libraries {
  31     // don't create
  32     private Libraries() {}
  33 
  34     /**
  35      * Create a raw, uncivilized version of the interface
  36      *
  37      * @param c the interface class to bind
  38      * @param lib the library in which to look for native symbols
  39      * @return an object of class implementing the interfacce
  40      */
  41     public static <T> T bind(Class<T> c, Library lib) {
  42         SecurityManager security = System.getSecurityManager();
  43         if (security != null) {
  44             security.checkPermission(new RuntimePermission("java.nicl.bind"));
  45         }
  46         return LibrariesHelper.bind(Objects.requireNonNull(c), Objects.requireNonNull(lib));
  47     }
  48 
  49     /**
  50      * Create a raw, uncivilized version of the interface
  51      *
  52      * @param lookup the lookup object (used for implicit native library lookup)
  53      * @param c the class to bind
  54      * @return an object of class implementing the interfacce
  55      */
  56     public static <T> T bind(Lookup lookup, Class<T> c) {
  57         SecurityManager security = System.getSecurityManager();
  58         if (security != null) {
  59             security.checkPermission(new RuntimePermission("java.nicl.bind"));
  60         }
  61         return LibrariesHelper.bind(checkLookup(lookup), Objects.requireNonNull(c));
  62     }
  63 
  64     /**
  65      * Loads the native library specified by the <code>libname</code>
  66      * argument.  The <code>libname</code> argument must not contain any platform
  67      * specific prefix, file extension or path.
  68      *
  69      * Otherwise, the libname argument is loaded from a system library
  70      * location and mapped to a native library image in an implementation-
  71      * dependent manner.
  72      * <p>
  73      *
  74      * @param      lookup     the lookup object
  75      * @param      filename   the name of the library.
  76      * @exception  SecurityException  if a security manager exists and its
  77      *             <code>checkLink</code> method doesn't allow
  78      *             loading of the specified dynamic library
  79      * @exception  UnsatisfiedLinkError if either the libname argument
  80      *             contains a file path, the native library is not statically
  81      *             linked with the VM,  or the library cannot be mapped to a
  82      *             native library image by the host system.
  83      * @exception  NullPointerException if <code>libname</code> is
  84      *             <code>null</code>
  85      * @see        java.lang.SecurityManager#checkLink(java.lang.String)
  86      */
  87     public static Library loadLibrary(Lookup lookup, String filename) {
  88         Objects.requireNonNull(filename);
  89         SecurityManager security = System.getSecurityManager();
  90         if (security != null) {
  91             security.checkLink(filename);
  92         }
  93         if (filename.indexOf(File.separatorChar) != -1) {
  94             throw new UnsatisfiedLinkError(
  95                 "Directory separator should not appear in library name: " + filename);
  96         }
  97         return LibrariesHelper.loadLibrary(checkLookup(lookup), filename);
  98     }
  99 
 100     /**
 101      * Loads the native library specified by the filename argument.  The filename
 102      * argument must be an absolute path name.
 103      *
 104      * @param      lookup     the lookup object
 105      * @param      filename   the file to load.
 106      * @exception  SecurityException  if a security manager exists and its
 107      *             <code>checkLink</code> method doesn't allow
 108      *             loading of the specified dynamic library
 109      * @exception  UnsatisfiedLinkError  if either the filename is not an
 110      *             absolute path name, the native library is not statically
 111      *             linked with the VM, or the library cannot be mapped to
 112      *             a native library image by the host system.
 113      * @exception  NullPointerException if <code>filename</code> is
 114      *             <code>null</code>
 115      * @see        java.lang.SecurityManager#checkLink(java.lang.String)
 116      */
 117     public static Library load(Lookup lookup, String filename) {
 118         Objects.requireNonNull(filename);
 119         SecurityManager security = System.getSecurityManager();
 120         if (security != null) {
 121             security.checkLink(filename);
 122         }
 123         if (!(new File(filename).isAbsolute())) {
 124             throw new UnsatisfiedLinkError(
 125                 "Expecting an absolute path of the library: " + filename);
 126         }
 127         return LibrariesHelper.load(checkLookup(lookup), filename);
 128     }
 129 
 130     public static Library getDefaultLibrary() {
 131         SecurityManager security = System.getSecurityManager();
 132         if (security != null) {
 133             security.checkPermission(new RuntimePermission("java.nicl.getDefaultLibrary"));
 134         }
 135         return LibrariesHelper.getDefaultLibrary();
 136     }
 137 
 138     private static Lookup checkLookup(Lookup lookup) {
 139         if (!Objects.requireNonNull(lookup).hasPrivateAccess()) {
 140             throw new IllegalArgumentException("Attempt to use non-private lookup object");
 141         }
 142         return lookup;
 143     }
 144 }