hdfs.c
上传用户:quxuerui
上传日期:2018-01-08
资源大小:41811k
文件大小:59k
源码类别:

网格计算

开发平台:

Java

  1. /**
  2.  * Licensed to the Apache Software Foundation (ASF) under one
  3.  * or more contributor license agreements.  See the NOTICE file
  4.  * distributed with this work for additional information
  5.  * regarding copyright ownership.  The ASF licenses this file
  6.  * to you under the Apache License, Version 2.0 (the
  7.  * "License"); you may not use this file except in compliance
  8.  * with the License.  You may obtain a copy of the License at
  9.  *
  10.  *     http://www.apache.org/licenses/LICENSE-2.0
  11.  *
  12.  * Unless required by applicable law or agreed to in writing, software
  13.  * distributed under the License is distributed on an "AS IS" BASIS,
  14.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15.  * See the License for the specific language governing permissions and
  16.  * limitations under the License.
  17.  */
  18. #include "hdfs.h"
  19. #include "hdfsJniHelper.h"
  20. /* Some frequently used Java paths */
  21. #define HADOOP_CONF     "org/apache/hadoop/conf/Configuration"
  22. #define HADOOP_PATH     "org/apache/hadoop/fs/Path"
  23. #define HADOOP_LOCALFS  "org/apache/hadoop/fs/LocalFileSystem"
  24. #define HADOOP_FS       "org/apache/hadoop/fs/FileSystem"
  25. #define HADOOP_BLK_LOC  "org/apache/hadoop/fs/BlockLocation"
  26. #define HADOOP_DFS      "org/apache/hadoop/hdfs/DistributedFileSystem"
  27. #define HADOOP_ISTRM    "org/apache/hadoop/fs/FSDataInputStream"
  28. #define HADOOP_OSTRM    "org/apache/hadoop/fs/FSDataOutputStream"
  29. #define HADOOP_STAT     "org/apache/hadoop/fs/FileStatus"
  30. #define HADOOP_FSPERM   "org/apache/hadoop/fs/permission/FsPermission"
  31. #define HADOOP_UNIX_USER_GROUP_INFO "org/apache/hadoop/security/UnixUserGroupInformation"
  32. #define HADOOP_USER_GROUP_INFO "org/apache/hadoop/security/UserGroupInformation"
  33. #define JAVA_NET_ISA    "java/net/InetSocketAddress"
  34. #define JAVA_NET_URI    "java/net/URI"
  35. #define JAVA_STRING     "java/lang/String"
  36. #define JAVA_VOID       "V"
  37. /* Macros for constructing method signatures */
  38. #define JPARAM(X)           "L" X ";"
  39. #define JARRPARAM(X)        "[L" X ";"
  40. #define JMETHOD1(X, R)      "(" X ")" R
  41. #define JMETHOD2(X, Y, R)   "(" X Y ")" R
  42. #define JMETHOD3(X, Y, Z, R)   "(" X Y Z")" R
  43. /**
  44.  * hdfsJniEnv: A wrapper struct to be used as 'value'
  45.  * while saving thread -> JNIEnv* mappings
  46.  */
  47. typedef struct
  48. {
  49.     JNIEnv* env;
  50. } hdfsJniEnv;
  51. /**
  52.  * Helper function to destroy a local reference of java.lang.Object
  53.  * @param env: The JNIEnv pointer. 
  54.  * @param jFile: The local reference of java.lang.Object object
  55.  * @return None.
  56.  */
  57. static void destroyLocalReference(JNIEnv *env, jobject jObject)
  58. {
  59.   if (jObject)
  60.     (*env)->DeleteLocalRef(env, jObject);
  61. }
  62. /**
  63.  * Helper function to create a org.apache.hadoop.fs.Path object.
  64.  * @param env: The JNIEnv pointer. 
  65.  * @param path: The file-path for which to construct org.apache.hadoop.fs.Path
  66.  * object.
  67.  * @return Returns a jobject on success and NULL on error.
  68.  */
  69. static jobject constructNewObjectOfPath(JNIEnv *env, const char *path)
  70. {
  71.     //Construct a java.lang.String object
  72.     jstring jPathString = (*env)->NewStringUTF(env, path); 
  73.     //Construct the org.apache.hadoop.fs.Path object
  74.     jobject jPath =
  75.         constructNewObjectOfClass(env, NULL, "org/apache/hadoop/fs/Path",
  76.                                   "(Ljava/lang/String;)V", jPathString);
  77.     if (jPath == NULL) {
  78.         fprintf(stderr, "Can't construct instance of class "
  79.                 "org.apache.hadoop.fs.Path for %sn", path);
  80.         errno = EINTERNAL;
  81.         return NULL;
  82.     }
  83.     // Destroy the local reference to the java.lang.String object
  84.     destroyLocalReference(env, jPathString);
  85.     return jPath;
  86. }
  87. /**
  88.  * Helper function to translate an exception into a meaningful errno value.
  89.  * @param exc: The exception.
  90.  * @param env: The JNIEnv Pointer.
  91.  * @param method: The name of the method that threw the exception. This
  92.  * may be format string to be used in conjuction with additional arguments.
  93.  * @return Returns a meaningful errno value if possible, or EINTERNAL if not.
  94.  */
  95. static int errnoFromException(jthrowable exc, JNIEnv *env,
  96.                               const char *method, ...)
  97. {
  98.     va_list ap;
  99.     int errnum = 0;
  100.     char *excClass = NULL;
  101.     if (exc == NULL)
  102.         goto default_error;
  103.     if ((excClass = classNameOfObject((jobject) exc, env)) == NULL) {
  104.       errnum = EINTERNAL;
  105.       goto done;
  106.     }
  107.     if (!strcmp(excClass, "org.apache.hadoop.fs.permission."
  108.                 "AccessControlException")) {
  109.         errnum = EACCES;
  110.         goto done;
  111.     }
  112.     //TODO: interpret more exceptions; maybe examine exc.getMessage()
  113. default_error:
  114.     //Can't tell what went wrong, so just punt
  115.     (*env)->ExceptionDescribe(env);
  116.     fprintf(stderr, "Call to ");
  117.     va_start(ap, method);
  118.     vfprintf(stderr, method, ap);
  119.     va_end(ap);
  120.     fprintf(stderr, " failed!n");
  121.     errnum = EINTERNAL;
  122. done:
  123.     (*env)->ExceptionClear(env);
  124.     if (excClass != NULL)
  125.         free(excClass);
  126.     return errnum;
  127. }
  128. hdfsFS hdfsConnect(const char* host, tPort port) {
  129.   // conect with NULL as user name/groups
  130.   return hdfsConnectAsUser(host, port, NULL, NULL, 0);
  131. }
  132. hdfsFS hdfsConnectAsUser(const char* host, tPort port, const char *user , const char **groups, int groups_size )
  133. {
  134.     // JAVA EQUIVALENT:
  135.     //  FileSystem fs = FileSystem.get(new Configuration());
  136.     //  return fs;
  137.     JNIEnv *env = 0;
  138.     jobject jConfiguration = NULL;
  139.     jobject jFS = NULL;
  140.     jobject jURI = NULL;
  141.     jstring jURIString = NULL;
  142.     jvalue  jVal;
  143.     jthrowable jExc = NULL;
  144.     char    *cURI = 0;
  145.     jobject gFsRef = NULL;
  146.     //Get the JNIEnv* corresponding to current thread
  147.     env = getJNIEnv();
  148.     if (env == NULL) {
  149.       errno = EINTERNAL;
  150.       return NULL;
  151.     }
  152.     //Create the org.apache.hadoop.conf.Configuration object
  153.     jConfiguration =
  154.         constructNewObjectOfClass(env, NULL, HADOOP_CONF, "()V");
  155.     if (jConfiguration == NULL) {
  156.         fprintf(stderr, "Can't construct instance of class "
  157.                 "org.apache.hadoop.conf.Configurationn");
  158.         errno = EINTERNAL;
  159.         return NULL;
  160.     }
  161.  
  162.     if (user != NULL) {
  163.       if (groups == NULL || groups_size <= 0) {
  164.         fprintf(stderr, "ERROR: groups must not be empty/nulln");
  165.         errno = EINVAL;
  166.         return NULL;
  167.       }
  168.       jstring jUserString = (*env)->NewStringUTF(env, user);
  169.       jarray jGroups = constructNewArrayString(env, &jExc, groups, groups_size);
  170.       if (jGroups == NULL) {
  171.         errno = EINTERNAL;
  172.         fprintf(stderr, "ERROR: could not construct groups arrayn");
  173.         return NULL;
  174.       }
  175.       jobject jUgi;
  176.       if ((jUgi = constructNewObjectOfClass(env, &jExc, HADOOP_UNIX_USER_GROUP_INFO, JMETHOD2(JPARAM(JAVA_STRING), JARRPARAM(JAVA_STRING), JAVA_VOID), jUserString, jGroups)) == NULL) {
  177.         fprintf(stderr,"failed to construct hadoop user unix group info objectn");
  178.         errno = errnoFromException(jExc, env, HADOOP_UNIX_USER_GROUP_INFO,
  179.                                    "init");
  180.         destroyLocalReference(env, jConfiguration);
  181.         destroyLocalReference(env, jUserString);
  182.         if (jGroups != NULL) {
  183.           destroyLocalReference(env, jGroups);
  184.         }          
  185.         return NULL;
  186.       }
  187. #define USE_UUGI
  188. #ifdef USE_UUGI
  189.       // UnixUserGroupInformation.UGI_PROPERTY_NAME
  190.       jstring jAttrString = (*env)->NewStringUTF(env,"hadoop.job.ugi");
  191.       
  192.       if (invokeMethod(env, &jVal, &jExc, STATIC, NULL, HADOOP_UNIX_USER_GROUP_INFO, "saveToConf",
  193.                        JMETHOD3(JPARAM(HADOOP_CONF), JPARAM(JAVA_STRING), JPARAM(HADOOP_UNIX_USER_GROUP_INFO), JAVA_VOID),
  194.                        jConfiguration, jAttrString, jUgi) != 0) {
  195.         errno = errnoFromException(jExc, env, HADOOP_FSPERM,
  196.                                    "init");
  197.         destroyLocalReference(env, jConfiguration);
  198.         destroyLocalReference(env, jUserString);
  199.         if (jGroups != NULL) {
  200.           destroyLocalReference(env, jGroups);
  201.         }          
  202.         destroyLocalReference(env, jUgi);
  203.         return NULL;
  204.       }
  205.       destroyLocalReference(env, jUserString);
  206.       destroyLocalReference(env, jGroups);
  207.       destroyLocalReference(env, jUgi);
  208.     }
  209. #else
  210.     
  211.     // what does "current" mean in the context of libhdfs ? does it mean for the last hdfs connection we used?
  212.     // that's why this code cannot be activated. We know the above use of the conf object should work well with 
  213.     // multiple connections.
  214.       if (invokeMethod(env, &jVal, &jExc, STATIC, NULL, HADOOP_USER_GROUP_INFO, "setCurrentUGI",
  215.                        JMETHOD1(JPARAM(HADOOP_USER_GROUP_INFO), JAVA_VOID),
  216.                        jUgi) != 0) {
  217.         errno = errnoFromException(jExc, env, HADOOP_USER_GROUP_INFO,
  218.                                    "setCurrentUGI");
  219.         destroyLocalReference(env, jConfiguration);
  220.         destroyLocalReference(env, jUserString);
  221.         if (jGroups != NULL) {
  222.           destroyLocalReference(env, jGroups);
  223.         }          
  224.         destroyLocalReference(env, jUgi);
  225.         return NULL;
  226.       }
  227.       destroyLocalReference(env, jUserString);
  228.       destroyLocalReference(env, jGroups);
  229.       destroyLocalReference(env, jUgi);
  230.     }
  231. #endif      
  232.     //Check what type of FileSystem the caller wants...
  233.     if (host == NULL) {
  234.         // fs = FileSytem::getLocal(conf);
  235.         if (invokeMethod(env, &jVal, &jExc, STATIC, NULL, HADOOP_FS, "getLocal",
  236.                          JMETHOD1(JPARAM(HADOOP_CONF),
  237.                                   JPARAM(HADOOP_LOCALFS)),
  238.                          jConfiguration) != 0) {
  239.             errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  240.                                        "FileSystem::getLocal");
  241.             goto done;
  242.         }
  243.         jFS = jVal.l;
  244.     }
  245.     else if (!strcmp(host, "default") && port == 0) {
  246.         //fs = FileSystem::get(conf); 
  247.         if (invokeMethod(env, &jVal, &jExc, STATIC, NULL,
  248.                          HADOOP_FS, "get",
  249.                          JMETHOD1(JPARAM(HADOOP_CONF),
  250.                                   JPARAM(HADOOP_FS)),
  251.                          jConfiguration) != 0) {
  252.             errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  253.                                        "FileSystem::get");
  254.             goto done;
  255.         }
  256.         jFS = jVal.l;
  257.     }
  258.     else {
  259.         // fs = FileSystem::get(URI, conf);
  260.         cURI = malloc(strlen(host)+16);
  261.         sprintf(cURI, "hdfs://%s:%d", host, (int)(port));
  262.         jURIString = (*env)->NewStringUTF(env, cURI);
  263.         if (invokeMethod(env, &jVal, &jExc, STATIC, NULL, JAVA_NET_URI,
  264.                          "create", "(Ljava/lang/String;)Ljava/net/URI;",
  265.                          jURIString) != 0) {
  266.             errno = errnoFromException(jExc, env, "java.net.URI::create");
  267.             goto done;
  268.         }
  269.         jURI = jVal.l;
  270.         if (invokeMethod(env, &jVal, &jExc, STATIC, NULL, HADOOP_FS, "get",
  271.                          JMETHOD2(JPARAM(JAVA_NET_URI),
  272.                                   JPARAM(HADOOP_CONF), JPARAM(HADOOP_FS)),
  273.                          jURI, jConfiguration) != 0) {
  274.             errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  275.                                        "Filesystem::get(URI, Configuration)");
  276.             goto done;
  277.         }
  278.         jFS = jVal.l;
  279.     }
  280.   done:
  281.     
  282.     // Release unnecessary local references
  283.     destroyLocalReference(env, jConfiguration);
  284.     destroyLocalReference(env, jURIString);
  285.     destroyLocalReference(env, jURI);
  286.     if (cURI) free(cURI);
  287.     /* Create a global reference for this fs */
  288.     if (jFS) {
  289.         gFsRef = (*env)->NewGlobalRef(env, jFS);
  290.         destroyLocalReference(env, jFS);
  291.     }
  292.     return gFsRef;
  293. }
  294. int hdfsDisconnect(hdfsFS fs)
  295. {
  296.     // JAVA EQUIVALENT:
  297.     //  fs.close()
  298.     //Get the JNIEnv* corresponding to current thread
  299.     JNIEnv* env = getJNIEnv();
  300.     if (env == NULL) {
  301.       errno = EINTERNAL;
  302.       return -2;
  303.     }
  304.     //Parameters
  305.     jobject jFS = (jobject)fs;
  306.     //Caught exception
  307.     jthrowable jExc = NULL;
  308.     //Sanity check
  309.     if (fs == NULL) {
  310.         errno = EBADF;
  311.         return -1;
  312.     }
  313.     if (invokeMethod(env, NULL, &jExc, INSTANCE, jFS, HADOOP_FS,
  314.                      "close", "()V") != 0) {
  315.         errno = errnoFromException(jExc, env, "Filesystem::close");
  316.         return -1;
  317.     }
  318.     //Release unnecessary references
  319.     (*env)->DeleteGlobalRef(env, fs);
  320.     return 0;
  321. }
  322. hdfsFile hdfsOpenFile(hdfsFS fs, const char* path, int flags, 
  323.                       int bufferSize, short replication, tSize blockSize)
  324. {
  325.     /*
  326.       JAVA EQUIVALENT:
  327.        File f = new File(path);
  328.        FSData{Input|Output}Stream f{is|os} = fs.create(f);
  329.        return f{is|os};
  330.     */
  331.     /* Get the JNIEnv* corresponding to current thread */
  332.     JNIEnv* env = getJNIEnv();
  333.     if (env == NULL) {
  334.       errno = EINTERNAL;
  335.       return NULL;
  336.     }
  337.     jobject jFS = (jobject)fs;
  338.     if (flags & O_RDWR) {
  339.       fprintf(stderr, "ERROR: cannot open an hdfs file in O_RDWR moden");
  340.       errno = ENOTSUP;
  341.       return NULL;
  342.     }
  343.     if ((flags & O_CREAT) && (flags & O_EXCL)) {
  344.       fprintf(stderr, "WARN: hdfs does not truly support O_CREATE && O_EXCLn");
  345.     }
  346.     /* The hadoop java api/signature */
  347.     const char* method = ((flags & O_WRONLY) == 0) ? "open" : (flags & O_APPEND) ? "append" : "create";
  348.     const char* signature = ((flags & O_WRONLY) == 0) ?
  349.         JMETHOD2(JPARAM(HADOOP_PATH), "I", JPARAM(HADOOP_ISTRM)) :
  350.       (flags & O_APPEND) ?
  351.       JMETHOD1(JPARAM(HADOOP_PATH), JPARAM(HADOOP_OSTRM)) :
  352.       JMETHOD2(JPARAM(HADOOP_PATH), "ZISJ", JPARAM(HADOOP_OSTRM));
  353.     /* Return value */
  354.     hdfsFile file = NULL;
  355.     /* Create an object of org.apache.hadoop.fs.Path */
  356.     jobject jPath = constructNewObjectOfPath(env, path);
  357.     if (jPath == NULL) {
  358.         return NULL; 
  359.     }
  360.     /* Get the Configuration object from the FileSystem object */
  361.     jvalue  jVal;
  362.     jobject jConfiguration = NULL;
  363.     jthrowable jExc = NULL;
  364.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jFS, HADOOP_FS,
  365.                      "getConf", JMETHOD1("", JPARAM(HADOOP_CONF))) != 0) {
  366.         errno = errnoFromException(jExc, env, "get configuration object "
  367.                                    "from filesystem");
  368.         destroyLocalReference(env, jPath);
  369.         return NULL;
  370.     }
  371.     jConfiguration = jVal.l;
  372.     jint jBufferSize = bufferSize;
  373.     jshort jReplication = replication;
  374.     jlong jBlockSize = blockSize;
  375.     jstring jStrBufferSize = (*env)->NewStringUTF(env, "io.file.buffer.size"); 
  376.     jstring jStrReplication = (*env)->NewStringUTF(env, "dfs.replication");
  377.     jstring jStrBlockSize = (*env)->NewStringUTF(env, "dfs.block.size");
  378.     //bufferSize
  379.     if (!bufferSize) {
  380.         if (invokeMethod(env, &jVal, &jExc, INSTANCE, jConfiguration, 
  381.                          HADOOP_CONF, "getInt", "(Ljava/lang/String;I)I",
  382.                          jStrBufferSize, 4096) != 0) {
  383.             errno = errnoFromException(jExc, env, "org.apache.hadoop.conf."
  384.                                        "Configuration::getInt");
  385.             goto done;
  386.         }
  387.         jBufferSize = jVal.i;
  388.     }
  389.     if ((flags & O_WRONLY) && (flags & O_APPEND) == 0) {
  390.         //replication
  391.         if (!replication) {
  392.             if (invokeMethod(env, &jVal, &jExc, INSTANCE, jConfiguration, 
  393.                              HADOOP_CONF, "getInt", "(Ljava/lang/String;I)I",
  394.                              jStrReplication, 1) != 0) {
  395.                 errno = errnoFromException(jExc, env, "org.apache.hadoop.conf."
  396.                                            "Configuration::getInt");
  397.                 goto done;
  398.             }
  399.             jReplication = jVal.i;
  400.         }
  401.         
  402.         //blockSize
  403.         if (!blockSize) {
  404.             if (invokeMethod(env, &jVal, &jExc, INSTANCE, jConfiguration, 
  405.                              HADOOP_CONF, "getLong", "(Ljava/lang/String;J)J",
  406.                              jStrBlockSize, 67108864)) {
  407.                 errno = errnoFromException(jExc, env, "org.apache.hadoop.conf."
  408.                                            "FileSystem::%s(%s)", method,
  409.                                            signature);
  410.                 goto done;
  411.             }
  412.             jBlockSize = jVal.j;
  413.         }
  414.     }
  415.  
  416.     /* Create and return either the FSDataInputStream or
  417.        FSDataOutputStream references jobject jStream */
  418.     // READ?
  419.     if ((flags & O_WRONLY) == 0) {
  420.       if (invokeMethod(env, &jVal, &jExc, INSTANCE, jFS, HADOOP_FS,
  421.                        method, signature, jPath, jBufferSize)) {
  422.         errno = errnoFromException(jExc, env, "org.apache.hadoop.conf."
  423.                                    "FileSystem::%s(%s)", method,
  424.                                    signature);
  425.         goto done;
  426.       }
  427.     }  else if ((flags & O_WRONLY) && (flags & O_APPEND)) {
  428.       // WRITE/APPEND?
  429.        if (invokeMethod(env, &jVal, &jExc, INSTANCE, jFS, HADOOP_FS,
  430.                        method, signature, jPath)) {
  431.         errno = errnoFromException(jExc, env, "org.apache.hadoop.conf."
  432.                                    "FileSystem::%s(%s)", method,
  433.                                    signature);
  434.         goto done;
  435.       }
  436.     } else {
  437.         // WRITE/CREATE
  438.         jboolean jOverWrite = 1;
  439.         if (invokeMethod(env, &jVal, &jExc, INSTANCE, jFS, HADOOP_FS,
  440.                          method, signature, jPath, jOverWrite,
  441.                          jBufferSize, jReplication, jBlockSize)) {
  442.             errno = errnoFromException(jExc, env, "org.apache.hadoop.conf."
  443.                                        "FileSystem::%s(%s)", method,
  444.                                        signature);
  445.             goto done;
  446.         }
  447.     }
  448.   
  449.     file = malloc(sizeof(struct hdfsFile_internal));
  450.     if (!file) {
  451.         errno = ENOMEM;
  452.         return NULL;
  453.     }
  454.     file->file = (*env)->NewGlobalRef(env, jVal.l);
  455.     file->type = (((flags & O_WRONLY) == 0) ? INPUT : OUTPUT);
  456.     destroyLocalReference(env, jVal.l);
  457.     done:
  458.     //Delete unnecessary local references
  459.     destroyLocalReference(env, jStrBufferSize);
  460.     destroyLocalReference(env, jStrReplication);
  461.     destroyLocalReference(env, jStrBlockSize);
  462.     destroyLocalReference(env, jConfiguration); 
  463.     destroyLocalReference(env, jPath); 
  464.     return file;
  465. }
  466. int hdfsCloseFile(hdfsFS fs, hdfsFile file)
  467. {
  468.     // JAVA EQUIVALENT:
  469.     //  file.close 
  470.     //Get the JNIEnv* corresponding to current thread
  471.     JNIEnv* env = getJNIEnv();
  472.     if (env == NULL) {
  473.       errno = EINTERNAL;
  474.       return -2;
  475.     }
  476.     //Parameters
  477.     jobject jStream = (jobject)(file ? file->file : NULL);
  478.     //Caught exception
  479.     jthrowable jExc = NULL;
  480.     //Sanity check
  481.     if (!file || file->type == UNINITIALIZED) {
  482.         errno = EBADF;
  483.         return -1;
  484.     }
  485.     //The interface whose 'close' method to be called
  486.     const char* interface = (file->type == INPUT) ? 
  487.         HADOOP_ISTRM : HADOOP_OSTRM;
  488.   
  489.     if (invokeMethod(env, NULL, &jExc, INSTANCE, jStream, interface,
  490.                      "close", "()V") != 0) {
  491.         errno = errnoFromException(jExc, env, "%s::close", interface);
  492.         return -1;
  493.     }
  494.     //De-allocate memory
  495.     free(file);
  496.     (*env)->DeleteGlobalRef(env, jStream);
  497.     return 0;
  498. }
  499. int hdfsExists(hdfsFS fs, const char *path)
  500. {
  501.     JNIEnv *env = getJNIEnv();
  502.     if (env == NULL) {
  503.       errno = EINTERNAL;
  504.       return -2;
  505.     }
  506.     jobject jPath = constructNewObjectOfPath(env, path);
  507.     jvalue  jVal;
  508.     jthrowable jExc = NULL;
  509.     jobject jFS = (jobject)fs;
  510.     if (jPath == NULL) {
  511.         return -1;
  512.     }
  513.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jFS, HADOOP_FS,
  514.                      "exists", JMETHOD1(JPARAM(HADOOP_PATH), "Z"),
  515.                      jPath) != 0) {
  516.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  517.                                    "FileSystem::exists");
  518.         return -1;
  519.     }
  520.     return jVal.z ? 0 : -1;
  521. }
  522. tSize hdfsRead(hdfsFS fs, hdfsFile f, void* buffer, tSize length)
  523. {
  524.     // JAVA EQUIVALENT:
  525.     //  byte [] bR = new byte[length];
  526.     //  fis.read(bR);
  527.     //Get the JNIEnv* corresponding to current thread
  528.     JNIEnv* env = getJNIEnv();
  529.     if (env == NULL) {
  530.       errno = EINTERNAL;
  531.       return -1;
  532.     }
  533.     //Parameters
  534.     jobject jInputStream = (jobject)(f ? f->file : NULL);
  535.     jbyteArray jbRarray;
  536.     jint noReadBytes = 0;
  537.     jvalue jVal;
  538.     jthrowable jExc = NULL;
  539.     //Sanity check
  540.     if (!f || f->type == UNINITIALIZED) {
  541.         errno = EBADF;
  542.         return -1;
  543.     }
  544.     //Error checking... make sure that this file is 'readable'
  545.     if (f->type != INPUT) {
  546.         fprintf(stderr, "Cannot read from a non-InputStream object!n");
  547.         errno = EINVAL;
  548.         return -1;
  549.     }
  550.     //Read the requisite bytes
  551.     jbRarray = (*env)->NewByteArray(env, length);
  552.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jInputStream, HADOOP_ISTRM,
  553.                      "read", "([B)I", jbRarray) != 0) {
  554.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  555.                                    "FSDataInputStream::read");
  556.         noReadBytes = -1;
  557.     }
  558.     else {
  559.         noReadBytes = jVal.i;
  560.         if (noReadBytes > 0) {
  561.             (*env)->GetByteArrayRegion(env, jbRarray, 0, noReadBytes, buffer);
  562.         }  else {
  563.             //This is a valid case: there aren't any bytes left to read!
  564.           if (noReadBytes == 0 || noReadBytes < -1) {
  565.             fprintf(stderr, "WARN: FSDataInputStream.read returned invalid return code - libhdfs returning EOF, i.e., 0: %dn", noReadBytes);
  566.           }
  567.             noReadBytes = 0;
  568.         }
  569.         errno = 0;
  570.     }
  571.     destroyLocalReference(env, jbRarray);
  572.     return noReadBytes;
  573. }
  574.   
  575. tSize hdfsPread(hdfsFS fs, hdfsFile f, tOffset position,
  576.                 void* buffer, tSize length)
  577. {
  578.     // JAVA EQUIVALENT:
  579.     //  byte [] bR = new byte[length];
  580.     //  fis.read(pos, bR, 0, length);
  581.     //Get the JNIEnv* corresponding to current thread
  582.     JNIEnv* env = getJNIEnv();
  583.     if (env == NULL) {
  584.       errno = EINTERNAL;
  585.       return -1;
  586.     }
  587.     //Parameters
  588.     jobject jInputStream = (jobject)(f ? f->file : NULL);
  589.     jbyteArray jbRarray;
  590.     jint noReadBytes = 0;
  591.     jvalue jVal;
  592.     jthrowable jExc = NULL;
  593.     //Sanity check
  594.     if (!f || f->type == UNINITIALIZED) {
  595.         errno = EBADF;
  596.         return -1;
  597.     }
  598.     //Error checking... make sure that this file is 'readable'
  599.     if (f->type != INPUT) {
  600.         fprintf(stderr, "Cannot read from a non-InputStream object!n");
  601.         errno = EINVAL;
  602.         return -1;
  603.     }
  604.     //Read the requisite bytes
  605.     jbRarray = (*env)->NewByteArray(env, length);
  606.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jInputStream, HADOOP_ISTRM,
  607.                      "read", "(J[BII)I", position, jbRarray, 0, length) != 0) {
  608.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  609.                                    "FSDataInputStream::read");
  610.         noReadBytes = -1;
  611.     }
  612.     else {
  613.         noReadBytes = jVal.i;
  614.         if (noReadBytes > 0) {
  615.             (*env)->GetByteArrayRegion(env, jbRarray, 0, noReadBytes, buffer);
  616.         }  else {
  617.             //This is a valid case: there aren't any bytes left to read!
  618.           if (noReadBytes == 0 || noReadBytes < -1) {
  619.             fprintf(stderr, "WARN: FSDataInputStream.read returned invalid return code - libhdfs returning EOF, i.e., 0: %dn", noReadBytes);
  620.           }
  621.             noReadBytes = 0;
  622.         }
  623.         errno = 0;
  624.     }
  625.     destroyLocalReference(env, jbRarray);
  626.     return noReadBytes;
  627. }
  628. tSize hdfsWrite(hdfsFS fs, hdfsFile f, const void* buffer, tSize length)
  629. {
  630.     // JAVA EQUIVALENT
  631.     // byte b[] = str.getBytes();
  632.     // fso.write(b);
  633.     //Get the JNIEnv* corresponding to current thread
  634.     JNIEnv* env = getJNIEnv();
  635.     if (env == NULL) {
  636.       errno = EINTERNAL;
  637.       return -1;
  638.     }
  639.     //Parameters
  640.     jobject jOutputStream = (jobject)(f ? f->file : 0);
  641.     jbyteArray jbWarray;
  642.     //Caught exception
  643.     jthrowable jExc = NULL;
  644.     //Sanity check
  645.     if (!f || f->type == UNINITIALIZED) {
  646.         errno = EBADF;
  647.         return -1;
  648.     }
  649.     
  650.     if (length < 0) {
  651.      errno = EINVAL;
  652.      return -1;
  653.     }
  654.     //Error checking... make sure that this file is 'writable'
  655.     if (f->type != OUTPUT) {
  656.         fprintf(stderr, "Cannot write into a non-OutputStream object!n");
  657.         errno = EINVAL;
  658.         return -1;
  659.     }
  660.     // 'length' equals 'zero' is a valid use-case according to Posix!
  661.     if (length != 0) {
  662.         //Write the requisite bytes into the file
  663.         jbWarray = (*env)->NewByteArray(env, length);
  664.         (*env)->SetByteArrayRegion(env, jbWarray, 0, length, buffer);
  665.         if (invokeMethod(env, NULL, &jExc, INSTANCE, jOutputStream,
  666.                          HADOOP_OSTRM, "write",
  667.                          "([B)V", jbWarray) != 0) {
  668.             errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  669.                                        "FSDataOutputStream::write");
  670.             length = -1;
  671.         }
  672.         destroyLocalReference(env, jbWarray);
  673.     }
  674.     //Return no. of bytes succesfully written (libc way)
  675.     //i.e. 'length' itself! ;-)
  676.     return length;
  677. }
  678. int hdfsSeek(hdfsFS fs, hdfsFile f, tOffset desiredPos) 
  679. {
  680.     // JAVA EQUIVALENT
  681.     //  fis.seek(pos);
  682.     //Get the JNIEnv* corresponding to current thread
  683.     JNIEnv* env = getJNIEnv();
  684.     if (env == NULL) {
  685.       errno = EINTERNAL;
  686.       return -1;
  687.     }
  688.     //Parameters
  689.     jobject jInputStream = (jobject)(f ? f->file : 0);
  690.     //Caught exception
  691.     jthrowable jExc = NULL;
  692.     //Sanity check
  693.     if (!f || f->type != INPUT) {
  694.         errno = EBADF;
  695.         return -1;
  696.     }
  697.     if (invokeMethod(env, NULL, &jExc, INSTANCE, jInputStream, HADOOP_ISTRM,
  698.                      "seek", "(J)V", desiredPos) != 0) {
  699.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  700.                                    "FSDataInputStream::seek");
  701.         return -1;
  702.     }
  703.     return 0;
  704. }
  705. tOffset hdfsTell(hdfsFS fs, hdfsFile f)
  706. {
  707.     // JAVA EQUIVALENT
  708.     //  pos = f.getPos();
  709.     //Get the JNIEnv* corresponding to current thread
  710.     JNIEnv* env = getJNIEnv();
  711.     if (env == NULL) {
  712.       errno = EINTERNAL;
  713.       return -1;
  714.     }
  715.     //Parameters
  716.     jobject jStream = (jobject)(f ? f->file : 0);
  717.     //Sanity check
  718.     if (!f || f->type == UNINITIALIZED) {
  719.         errno = EBADF;
  720.         return -1;
  721.     }
  722.     const char* interface = (f->type == INPUT) ?
  723.         HADOOP_ISTRM : HADOOP_OSTRM;
  724.     jlong currentPos  = -1;
  725.     jvalue jVal;
  726.     jthrowable jExc = NULL;
  727.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jStream,
  728.                      interface, "getPos", "()J") != 0) {
  729.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  730.                                    "FSDataInputStream::getPos");
  731.         return -1;
  732.     }
  733.     currentPos = jVal.j;
  734.     return (tOffset)currentPos;
  735. }
  736. int hdfsFlush(hdfsFS fs, hdfsFile f) 
  737. {
  738.     // JAVA EQUIVALENT
  739.     //  fos.flush();
  740.     //Get the JNIEnv* corresponding to current thread
  741.     JNIEnv* env = getJNIEnv();
  742.     if (env == NULL) {
  743.       errno = EINTERNAL;
  744.       return -1;
  745.     }
  746.     //Parameters
  747.     jobject jOutputStream = (jobject)(f ? f->file : 0);
  748.     //Caught exception
  749.     jthrowable jExc = NULL;
  750.     //Sanity check
  751.     if (!f || f->type != OUTPUT) {
  752.         errno = EBADF;
  753.         return -1;
  754.     }
  755.     if (invokeMethod(env, NULL, &jExc, INSTANCE, jOutputStream, 
  756.                      HADOOP_OSTRM, "flush", "()V") != 0) {
  757.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  758.                                    "FSDataInputStream::flush");
  759.         return -1;
  760.     }
  761.     return 0;
  762. }
  763. int hdfsAvailable(hdfsFS fs, hdfsFile f)
  764. {
  765.     // JAVA EQUIVALENT
  766.     //  fis.available();
  767.     //Get the JNIEnv* corresponding to current thread
  768.     JNIEnv* env = getJNIEnv();
  769.     if (env == NULL) {
  770.       errno = EINTERNAL;
  771.       return -1;
  772.     }
  773.     //Parameters
  774.     jobject jInputStream = (jobject)(f ? f->file : 0);
  775.     //Caught exception
  776.     jthrowable jExc = NULL;
  777.     //Sanity check
  778.     if (!f || f->type != INPUT) {
  779.         errno = EBADF;
  780.         return -1;
  781.     }
  782.     jint available = -1;
  783.     jvalue jVal;
  784.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jInputStream, 
  785.                      HADOOP_ISTRM, "available", "()I") != 0) {
  786.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  787.                                    "FSDataInputStream::available");
  788.         return -1;
  789.     }
  790.     available = jVal.i;
  791.     return available;
  792. }
  793. int hdfsCopy(hdfsFS srcFS, const char* src, hdfsFS dstFS, const char* dst)
  794. {
  795.     //JAVA EQUIVALENT
  796.     //  FileUtil::copy(srcFS, srcPath, dstFS, dstPath,
  797.     //                 deleteSource = false, conf)
  798.     //Get the JNIEnv* corresponding to current thread
  799.     JNIEnv* env = getJNIEnv();
  800.     if (env == NULL) {
  801.       errno = EINTERNAL;
  802.       return -1;
  803.     }
  804.     //Parameters
  805.     jobject jSrcFS = (jobject)srcFS;
  806.     jobject jDstFS = (jobject)dstFS;
  807.     jobject jSrcPath = NULL;
  808.     jobject jDstPath = NULL;
  809.     jSrcPath = constructNewObjectOfPath(env, src);
  810.     if (jSrcPath == NULL) {
  811.         return -1;
  812.     }
  813.     jDstPath = constructNewObjectOfPath(env, dst);
  814.     if (jDstPath == NULL) {
  815.         destroyLocalReference(env, jSrcPath);
  816.         return -1;
  817.     }
  818.     int retval = 0;
  819.     //Create the org.apache.hadoop.conf.Configuration object
  820.     jobject jConfiguration =
  821.         constructNewObjectOfClass(env, NULL, HADOOP_CONF, "()V");
  822.     if (jConfiguration == NULL) {
  823.         fprintf(stderr, "Can't construct instance of class "
  824.                 "org.apache.hadoop.conf.Configurationn");
  825.         errno = EINTERNAL;
  826.         destroyLocalReference(env, jSrcPath);
  827.         destroyLocalReference(env, jDstPath);
  828.         return -1;
  829.     }
  830.     //FileUtil::copy
  831.     jboolean deleteSource = 0; //Only copy
  832.     jvalue jVal;
  833.     jthrowable jExc = NULL;
  834.     if (invokeMethod(env, &jVal, &jExc, STATIC, 
  835.                      NULL, "org/apache/hadoop/fs/FileUtil", "copy",
  836.                      "(Lorg/apache/hadoop/fs/FileSystem;Lorg/apache/hadoop/fs/Path;Lorg/apache/hadoop/fs/FileSystem;Lorg/apache/hadoop/fs/Path;ZLorg/apache/hadoop/conf/Configuration;)Z",
  837.                      jSrcFS, jSrcPath, jDstFS, jDstPath, deleteSource, 
  838.                      jConfiguration) != 0) {
  839.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  840.                                    "FileUtil::copy");
  841.         retval = -1;
  842.         goto done;
  843.     }
  844.     done:
  845.     //Delete unnecessary local references
  846.     destroyLocalReference(env, jConfiguration);
  847.     destroyLocalReference(env, jSrcPath);
  848.     destroyLocalReference(env, jDstPath);
  849.   
  850.     return retval;
  851. }
  852. int hdfsMove(hdfsFS srcFS, const char* src, hdfsFS dstFS, const char* dst)
  853. {
  854.     //JAVA EQUIVALENT
  855.     //  FileUtil::copy(srcFS, srcPath, dstFS, dstPath,
  856.     //                 deleteSource = true, conf)
  857.     //Get the JNIEnv* corresponding to current thread
  858.     JNIEnv* env = getJNIEnv();
  859.     if (env == NULL) {
  860.       errno = EINTERNAL;
  861.       return -1;
  862.     }
  863.     //Parameters
  864.     jobject jSrcFS = (jobject)srcFS;
  865.     jobject jDstFS = (jobject)dstFS;
  866.     jobject jSrcPath = NULL;
  867.     jobject jDstPath = NULL;
  868.     jSrcPath = constructNewObjectOfPath(env, src);
  869.     if (jSrcPath == NULL) {
  870.         return -1;
  871.     }
  872.     jDstPath = constructNewObjectOfPath(env, dst);
  873.     if (jDstPath == NULL) {
  874.         destroyLocalReference(env, jSrcPath);
  875.         return -1;
  876.     }
  877.     int retval = 0;
  878.     //Create the org.apache.hadoop.conf.Configuration object
  879.     jobject jConfiguration =
  880.         constructNewObjectOfClass(env, NULL, HADOOP_CONF, "()V");
  881.     if (jConfiguration == NULL) {
  882.         fprintf(stderr, "Can't construct instance of class "
  883.                 "org.apache.hadoop.conf.Configurationn");
  884.         errno = EINTERNAL;
  885.         destroyLocalReference(env, jSrcPath);
  886.         destroyLocalReference(env, jDstPath);
  887.         return -1;
  888.     }
  889.     //FileUtil::copy
  890.     jboolean deleteSource = 1; //Delete src after copy
  891.     jvalue jVal;
  892.     jthrowable jExc = NULL;
  893.     if (invokeMethod(env, &jVal, &jExc, STATIC, NULL,
  894.                      "org/apache/hadoop/fs/FileUtil", "copy",
  895.                 "(Lorg/apache/hadoop/fs/FileSystem;Lorg/apache/hadoop/fs/Path;Lorg/apache/hadoop/fs/FileSystem;Lorg/apache/hadoop/fs/Path;ZLorg/apache/hadoop/conf/Configuration;)Z",
  896.                      jSrcFS, jSrcPath, jDstFS, jDstPath, deleteSource, 
  897.                      jConfiguration) != 0) {
  898.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  899.                                    "FileUtil::copy(move)");
  900.         retval = -1;
  901.         goto done;
  902.     }
  903.     done:
  904.     //Delete unnecessary local references
  905.     destroyLocalReference(env, jConfiguration);
  906.     destroyLocalReference(env, jSrcPath);
  907.     destroyLocalReference(env, jDstPath);
  908.   
  909.     return retval;
  910. }
  911. int hdfsDelete(hdfsFS fs, const char* path)
  912. {
  913.     // JAVA EQUIVALENT:
  914.     //  File f = new File(path);
  915.     //  bool retval = fs.delete(f);
  916.     //Get the JNIEnv* corresponding to current thread
  917.     JNIEnv* env = getJNIEnv();
  918.     if (env == NULL) {
  919.       errno = EINTERNAL;
  920.       return -1;
  921.     }
  922.     jobject jFS = (jobject)fs;
  923.     //Create an object of java.io.File
  924.     jobject jPath = constructNewObjectOfPath(env, path);
  925.     if (jPath == NULL) {
  926.         return -1;
  927.     }
  928.     //Delete the file
  929.     jvalue jVal;
  930.     jthrowable jExc = NULL;
  931.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jFS, HADOOP_FS,
  932.                      "delete", "(Lorg/apache/hadoop/fs/Path;)Z",
  933.                      jPath) != 0) {
  934.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  935.                                    "FileSystem::delete");
  936.         return -1;
  937.     }
  938.     //Delete unnecessary local references
  939.     destroyLocalReference(env, jPath);
  940.     return (jVal.z) ? 0 : -1;
  941. }
  942. int hdfsRename(hdfsFS fs, const char* oldPath, const char* newPath)
  943. {
  944.     // JAVA EQUIVALENT:
  945.     //  Path old = new Path(oldPath);
  946.     //  Path new = new Path(newPath);
  947.     //  fs.rename(old, new);
  948.     //Get the JNIEnv* corresponding to current thread
  949.     JNIEnv* env = getJNIEnv();
  950.     if (env == NULL) {
  951.       errno = EINTERNAL;
  952.       return -1;
  953.     }
  954.     jobject jFS = (jobject)fs;
  955.     //Create objects of org.apache.hadoop.fs.Path
  956.     jobject jOldPath = NULL;
  957.     jobject jNewPath = NULL;
  958.     jOldPath = constructNewObjectOfPath(env, oldPath);
  959.     if (jOldPath == NULL) {
  960.         return -1;
  961.     }
  962.     jNewPath = constructNewObjectOfPath(env, newPath);
  963.     if (jNewPath == NULL) {
  964.         destroyLocalReference(env, jOldPath);
  965.         return -1;
  966.     }
  967.     //Rename the file
  968.     jvalue jVal;
  969.     jthrowable jExc = NULL;
  970.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jFS, HADOOP_FS, "rename",
  971.                      JMETHOD2(JPARAM(HADOOP_PATH), JPARAM(HADOOP_PATH), "Z"),
  972.                      jOldPath, jNewPath) != 0) {
  973.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  974.                                    "FileSystem::rename");
  975.         return -1;
  976.     }
  977.     //Delete unnecessary local references
  978.     destroyLocalReference(env, jOldPath);
  979.     destroyLocalReference(env, jNewPath);
  980.     return (jVal.z) ? 0 : -1;
  981. }
  982. char* hdfsGetWorkingDirectory(hdfsFS fs, char* buffer, size_t bufferSize)
  983. {
  984.     // JAVA EQUIVALENT:
  985.     //  Path p = fs.getWorkingDirectory(); 
  986.     //  return p.toString()
  987.     //Get the JNIEnv* corresponding to current thread
  988.     JNIEnv* env = getJNIEnv();
  989.     if (env == NULL) {
  990.       errno = EINTERNAL;
  991.       return NULL;
  992.     }
  993.     jobject jFS = (jobject)fs;
  994.     jobject jPath = NULL;
  995.     jvalue jVal;
  996.     jthrowable jExc = NULL;
  997.     //FileSystem::getWorkingDirectory()
  998.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jFS,
  999.                      HADOOP_FS, "getWorkingDirectory",
  1000.                      "()Lorg/apache/hadoop/fs/Path;") != 0 ||
  1001.         jVal.l == NULL) {
  1002.         errno = errnoFromException(jExc, env, "FileSystem::"
  1003.                                    "getWorkingDirectory");
  1004.         return NULL;
  1005.     }
  1006.     jPath = jVal.l;
  1007.     //Path::toString()
  1008.     jstring jPathString;
  1009.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jPath, 
  1010.                      "org/apache/hadoop/fs/Path", "toString",
  1011.                      "()Ljava/lang/String;") != 0) { 
  1012.         errno = errnoFromException(jExc, env, "Path::toString");
  1013.         destroyLocalReference(env, jPath);
  1014.         return NULL;
  1015.     }
  1016.     jPathString = jVal.l;
  1017.     const char *jPathChars = (const char*)
  1018.         ((*env)->GetStringUTFChars(env, jPathString, NULL));
  1019.     //Copy to user-provided buffer
  1020.     strncpy(buffer, jPathChars, bufferSize);
  1021.     //Delete unnecessary local references
  1022.     (*env)->ReleaseStringUTFChars(env, jPathString, jPathChars);
  1023.     destroyLocalReference(env, jPathString);
  1024.     destroyLocalReference(env, jPath);
  1025.     return buffer;
  1026. }
  1027. int hdfsSetWorkingDirectory(hdfsFS fs, const char* path)
  1028. {
  1029.     // JAVA EQUIVALENT:
  1030.     //  fs.setWorkingDirectory(Path(path)); 
  1031.     //Get the JNIEnv* corresponding to current thread
  1032.     JNIEnv* env = getJNIEnv();
  1033.     if (env == NULL) {
  1034.       errno = EINTERNAL;
  1035.       return -1;
  1036.     }
  1037.     jobject jFS = (jobject)fs;
  1038.     int retval = 0;
  1039.     jthrowable jExc = NULL;
  1040.     //Create an object of org.apache.hadoop.fs.Path
  1041.     jobject jPath = constructNewObjectOfPath(env, path);
  1042.     if (jPath == NULL) {
  1043.         return -1;
  1044.     }
  1045.     //FileSystem::setWorkingDirectory()
  1046.     if (invokeMethod(env, NULL, &jExc, INSTANCE, jFS, HADOOP_FS,
  1047.                      "setWorkingDirectory", 
  1048.                      "(Lorg/apache/hadoop/fs/Path;)V", jPath) != 0) {
  1049.         errno = errnoFromException(jExc, env, "FileSystem::"
  1050.                                    "setWorkingDirectory");
  1051.         retval = -1;
  1052.     }
  1053.     //Delete unnecessary local references
  1054.     destroyLocalReference(env, jPath);
  1055.     return retval;
  1056. }
  1057. int hdfsCreateDirectory(hdfsFS fs, const char* path)
  1058. {
  1059.     // JAVA EQUIVALENT:
  1060.     //  fs.mkdirs(new Path(path));
  1061.     //Get the JNIEnv* corresponding to current thread
  1062.     JNIEnv* env = getJNIEnv();
  1063.     if (env == NULL) {
  1064.       errno = EINTERNAL;
  1065.       return -1;
  1066.     }
  1067.     jobject jFS = (jobject)fs;
  1068.     //Create an object of org.apache.hadoop.fs.Path
  1069.     jobject jPath = constructNewObjectOfPath(env, path);
  1070.     if (jPath == NULL) {
  1071.         return -1;
  1072.     }
  1073.     //Create the directory
  1074.     jvalue jVal;
  1075.     jVal.z = 0;
  1076.     jthrowable jExc = NULL;
  1077.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jFS, HADOOP_FS,
  1078.                      "mkdirs", "(Lorg/apache/hadoop/fs/Path;)Z",
  1079.                      jPath) != 0) {
  1080.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  1081.                                    "FileSystem::mkdirs");
  1082.         goto done;
  1083.     }
  1084.  done:
  1085.     //Delete unnecessary local references
  1086.     destroyLocalReference(env, jPath);
  1087.     return (jVal.z) ? 0 : -1;
  1088. }
  1089. int hdfsSetReplication(hdfsFS fs, const char* path, int16_t replication)
  1090. {
  1091.     // JAVA EQUIVALENT:
  1092.     //  fs.setReplication(new Path(path), replication);
  1093.     //Get the JNIEnv* corresponding to current thread
  1094.     JNIEnv* env = getJNIEnv();
  1095.     if (env == NULL) {
  1096.       errno = EINTERNAL;
  1097.       return -1;
  1098.     }
  1099.     jobject jFS = (jobject)fs;
  1100.     //Create an object of org.apache.hadoop.fs.Path
  1101.     jobject jPath = constructNewObjectOfPath(env, path);
  1102.     if (jPath == NULL) {
  1103.         return -1;
  1104.     }
  1105.     //Create the directory
  1106.     jvalue jVal;
  1107.     jthrowable jExc = NULL;
  1108.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jFS, HADOOP_FS,
  1109.                      "setReplication", "(Lorg/apache/hadoop/fs/Path;S)Z",
  1110.                      jPath, replication) != 0) {
  1111.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  1112.                                    "FileSystem::setReplication");
  1113.         goto done;
  1114.     }
  1115.  done:
  1116.     //Delete unnecessary local references
  1117.     destroyLocalReference(env, jPath);
  1118.     return (jVal.z) ? 0 : -1;
  1119. }
  1120. int hdfsChown(hdfsFS fs, const char* path, const char *owner, const char *group)
  1121. {
  1122.     // JAVA EQUIVALENT:
  1123.     //  fs.setOwner(path, owner, group)
  1124.     //Get the JNIEnv* corresponding to current thread
  1125.     JNIEnv* env = getJNIEnv();
  1126.     if (env == NULL) {
  1127.       errno = EINTERNAL;
  1128.       return -1;
  1129.     }
  1130.     if (owner == NULL && group == NULL) {
  1131.       fprintf(stderr, "Both owner and group cannot be null in chown");
  1132.       errno = EINVAL;
  1133.       return -1;
  1134.     }
  1135.     jobject jFS = (jobject)fs;
  1136.     jobject jPath = constructNewObjectOfPath(env, path);
  1137.     if (jPath == NULL) {
  1138.         return -1;
  1139.     }
  1140.     jstring jOwnerString = (*env)->NewStringUTF(env, owner); 
  1141.     jstring jGroupString = (*env)->NewStringUTF(env, group); 
  1142.     //Create the directory
  1143.     int ret = 0;
  1144.     jthrowable jExc = NULL;
  1145.     if (invokeMethod(env, NULL, &jExc, INSTANCE, jFS, HADOOP_FS,
  1146.                      "setOwner", JMETHOD3(JPARAM(HADOOP_PATH), JPARAM(JAVA_STRING), JPARAM(JAVA_STRING), JAVA_VOID),
  1147.                      jPath, jOwnerString, jGroupString) != 0) {
  1148.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  1149.                                    "FileSystem::setOwner");
  1150.         ret = -1;
  1151.         goto done;
  1152.     }
  1153.  done:
  1154.     destroyLocalReference(env, jPath);
  1155.     destroyLocalReference(env, jOwnerString);
  1156.     destroyLocalReference(env, jGroupString);
  1157.     return ret;
  1158. }
  1159. int hdfsChmod(hdfsFS fs, const char* path, short mode)
  1160. {
  1161.     // JAVA EQUIVALENT:
  1162.     //  fs.setPermission(path, FsPermission)
  1163.     //Get the JNIEnv* corresponding to current thread
  1164.     JNIEnv* env = getJNIEnv();
  1165.     if (env == NULL) {
  1166.       errno = EINTERNAL;
  1167.       return -1;
  1168.     }
  1169.     jobject jFS = (jobject)fs;
  1170.     // construct jPerm = FsPermission.createImmutable(short mode);
  1171.     jshort jmode = mode;
  1172.     jobject jPermObj =
  1173.       constructNewObjectOfClass(env, NULL, HADOOP_FSPERM,"(S)V",jmode);
  1174.     if (jPermObj == NULL) {
  1175.       return -2;
  1176.     }
  1177.     //Create an object of org.apache.hadoop.fs.Path
  1178.     jobject jPath = constructNewObjectOfPath(env, path);
  1179.     if (jPath == NULL) {
  1180.       return -3;
  1181.     }
  1182.     //Create the directory
  1183.     int ret = 0;
  1184.     jthrowable jExc = NULL;
  1185.     if (invokeMethod(env, NULL, &jExc, INSTANCE, jFS, HADOOP_FS,
  1186.                      "setPermission", JMETHOD2(JPARAM(HADOOP_PATH), JPARAM(HADOOP_FSPERM), JAVA_VOID),
  1187.                      jPath, jPermObj) != 0) {
  1188.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  1189.                                    "FileSystem::setPermission");
  1190.         ret = -1;
  1191.         goto done;
  1192.     }
  1193.  done:
  1194.     destroyLocalReference(env, jPath);
  1195.     destroyLocalReference(env, jPermObj);
  1196.     return ret;
  1197. }
  1198. int hdfsUtime(hdfsFS fs, const char* path, tTime mtime, tTime atime)
  1199. {
  1200.     // JAVA EQUIVALENT:
  1201.     //  fs.setTimes(src, mtime, atime)
  1202.     //Get the JNIEnv* corresponding to current thread
  1203.     JNIEnv* env = getJNIEnv();
  1204.     if (env == NULL) {
  1205.       errno = EINTERNAL;
  1206.       return -1;
  1207.     }
  1208.     jobject jFS = (jobject)fs;
  1209.     //Create an object of org.apache.hadoop.fs.Path
  1210.     jobject jPath = constructNewObjectOfPath(env, path);
  1211.     if (jPath == NULL) {
  1212.       fprintf(stderr, "could not construct path objectn");
  1213.       return -2;
  1214.     }
  1215.     jlong jmtime = mtime * (jlong)1000;
  1216.     jlong jatime = atime * (jlong)1000;
  1217.     int ret = 0;
  1218.     jthrowable jExc = NULL;
  1219.     if (invokeMethod(env, NULL, &jExc, INSTANCE, jFS, HADOOP_FS,
  1220.                      "setTimes", JMETHOD3(JPARAM(HADOOP_PATH), "J", "J", JAVA_VOID),
  1221.                      jPath, jmtime, jatime) != 0) {
  1222.       fprintf(stderr, "call to setTime failedn");
  1223.       errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  1224.                                  "FileSystem::setTimes");
  1225.       ret = -1;
  1226.       goto done;
  1227.     }
  1228.  done:
  1229.     destroyLocalReference(env, jPath);
  1230.     return ret;
  1231. }
  1232. char***
  1233. hdfsGetHosts(hdfsFS fs, const char* path, tOffset start, tOffset length)
  1234. {
  1235.     // JAVA EQUIVALENT:
  1236.     //  fs.getFileBlockLoctions(new Path(path), start, length);
  1237.     //Get the JNIEnv* corresponding to current thread
  1238.     JNIEnv* env = getJNIEnv();
  1239.     if (env == NULL) {
  1240.       errno = EINTERNAL;
  1241.       return NULL;
  1242.     }
  1243.     jobject jFS = (jobject)fs;
  1244.     //Create an object of org.apache.hadoop.fs.Path
  1245.     jobject jPath = constructNewObjectOfPath(env, path);
  1246.     if (jPath == NULL) {
  1247.         return NULL;
  1248.     }
  1249.     jvalue jFSVal;
  1250.     jthrowable jFSExc = NULL;
  1251.     if (invokeMethod(env, &jFSVal, &jFSExc, INSTANCE, jFS,
  1252.                      HADOOP_FS, "getFileStatus", 
  1253.                      "(Lorg/apache/hadoop/fs/Path;)"
  1254.                      "Lorg/apache/hadoop/fs/FileStatus;",
  1255.                      jPath) != 0) {
  1256.         errno = errnoFromException(jFSExc, env, "org.apache.hadoop.fs."
  1257.                                    "FileSystem::getFileStatus");
  1258.         destroyLocalReference(env, jPath);
  1259.         return NULL;
  1260.     }
  1261.     jobject jFileStatus = jFSVal.l;
  1262.     //org.apache.hadoop.fs.FileSystem::getFileBlockLocations
  1263.     char*** blockHosts = NULL;
  1264.     jobjectArray jBlockLocations;;
  1265.     jvalue jVal;
  1266.     jthrowable jExc = NULL;
  1267.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jFS,
  1268.                      HADOOP_FS, "getFileBlockLocations", 
  1269.                      "(Lorg/apache/hadoop/fs/FileStatus;JJ)"
  1270.                      "[Lorg/apache/hadoop/fs/BlockLocation;",
  1271.                      jFileStatus, start, length) != 0) {
  1272.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  1273.                                    "FileSystem::getFileBlockLocations");
  1274.         destroyLocalReference(env, jPath);
  1275.         destroyLocalReference(env, jFileStatus);
  1276.         return NULL;
  1277.     }
  1278.     jBlockLocations = jVal.l;
  1279.     //Figure out no of entries in jBlockLocations
  1280.     //Allocate memory and add NULL at the end
  1281.     jsize jNumFileBlocks = (*env)->GetArrayLength(env, jBlockLocations);
  1282.     blockHosts = malloc(sizeof(char**) * (jNumFileBlocks+1));
  1283.     if (blockHosts == NULL) {
  1284.         errno = ENOMEM;
  1285.         goto done;
  1286.     }
  1287.     blockHosts[jNumFileBlocks] = NULL;
  1288.     if (jNumFileBlocks == 0) {
  1289.         errno = 0;
  1290.         goto done;
  1291.     }
  1292.     //Now parse each block to get hostnames
  1293.     int i = 0;
  1294.     for (i=0; i < jNumFileBlocks; ++i) {
  1295.         jobject jFileBlock =
  1296.             (*env)->GetObjectArrayElement(env, jBlockLocations, i);
  1297.         
  1298.         jvalue jVal;
  1299.         jobjectArray jFileBlockHosts;
  1300.         if (invokeMethod(env, &jVal, &jExc, INSTANCE, jFileBlock, HADOOP_BLK_LOC,
  1301.                          "getHosts", "()[Ljava/lang/String;") ||
  1302.                 jVal.l == NULL) {
  1303.             errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  1304.                                        "BlockLocation::getHosts");
  1305.             destroyLocalReference(env, jPath);
  1306.             destroyLocalReference(env, jFileStatus);
  1307.             destroyLocalReference(env, jBlockLocations);
  1308.             return NULL;
  1309.         }
  1310.         
  1311.         jFileBlockHosts = jVal.l;
  1312.         //Figure out no of hosts in jFileBlockHosts
  1313.         //Allocate memory and add NULL at the end
  1314.         jsize jNumBlockHosts = (*env)->GetArrayLength(env, jFileBlockHosts);
  1315.         blockHosts[i] = malloc(sizeof(char*) * (jNumBlockHosts+1));
  1316.         if (blockHosts[i] == NULL) {
  1317.             int x = 0;
  1318.             for (x=0; x < i; ++x) {
  1319.                 free(blockHosts[x]);
  1320.             }
  1321.             free(blockHosts);
  1322.             errno = ENOMEM;
  1323.             goto done;
  1324.         }
  1325.         blockHosts[i][jNumBlockHosts] = NULL;
  1326.         //Now parse each hostname
  1327.         int j = 0;
  1328.         const char *hostName;
  1329.         for (j=0; j < jNumBlockHosts; ++j) {
  1330.             jstring jHost =
  1331.                 (*env)->GetObjectArrayElement(env, jFileBlockHosts, j);
  1332.            
  1333.             hostName =
  1334.                 (const char*)((*env)->GetStringUTFChars(env, jHost, NULL));
  1335.             blockHosts[i][j] = strdup(hostName);
  1336.             (*env)->ReleaseStringUTFChars(env, jHost, hostName);
  1337.             destroyLocalReference(env, jHost);
  1338.         }
  1339.         destroyLocalReference(env, jFileBlockHosts);
  1340.     }
  1341.   
  1342.     done:
  1343.     //Delete unnecessary local references
  1344.     destroyLocalReference(env, jPath);
  1345.     destroyLocalReference(env, jFileStatus);
  1346.     destroyLocalReference(env, jBlockLocations);
  1347.     return blockHosts;
  1348. }
  1349. void hdfsFreeHosts(char ***blockHosts)
  1350. {
  1351.     int i, j;
  1352.     for (i=0; blockHosts[i]; i++) {
  1353.         for (j=0; blockHosts[i][j]; j++) {
  1354.             free(blockHosts[i][j]);
  1355.         }
  1356.         free(blockHosts[i]);
  1357.     }
  1358.     free(blockHosts);
  1359. }
  1360. tOffset hdfsGetDefaultBlockSize(hdfsFS fs)
  1361. {
  1362.     // JAVA EQUIVALENT:
  1363.     //  fs.getDefaultBlockSize();
  1364.     //Get the JNIEnv* corresponding to current thread
  1365.     JNIEnv* env = getJNIEnv();
  1366.     if (env == NULL) {
  1367.       errno = EINTERNAL;
  1368.       return -1;
  1369.     }
  1370.     jobject jFS = (jobject)fs;
  1371.     //FileSystem::getDefaultBlockSize()
  1372.     tOffset blockSize = -1;
  1373.     jvalue jVal;
  1374.     jthrowable jExc = NULL;
  1375.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jFS, HADOOP_FS,
  1376.                      "getDefaultBlockSize", "()J") != 0) {
  1377.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  1378.                                    "FileSystem::getDefaultBlockSize");
  1379.         return -1;
  1380.     }
  1381.     blockSize = jVal.j;
  1382.     return blockSize;
  1383. }
  1384. tOffset hdfsGetCapacity(hdfsFS fs)
  1385. {
  1386.     // JAVA EQUIVALENT:
  1387.     //  fs.getRawCapacity();
  1388.     //Get the JNIEnv* corresponding to current thread
  1389.     JNIEnv* env = getJNIEnv();
  1390.     if (env == NULL) {
  1391.       errno = EINTERNAL;
  1392.       return -1;
  1393.     }
  1394.     jobject jFS = (jobject)fs;
  1395.     if (!((*env)->IsInstanceOf(env, jFS, 
  1396.                                globalClassReference(HADOOP_DFS, env)))) {
  1397.         fprintf(stderr, "hdfsGetCapacity works only on a "
  1398.                 "DistributedFileSystem!n");
  1399.         return -1;
  1400.     }
  1401.     //FileSystem::getRawCapacity()
  1402.     jvalue  jVal;
  1403.     jthrowable jExc = NULL;
  1404.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jFS, HADOOP_DFS,
  1405.                      "getRawCapacity", "()J") != 0) {
  1406.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  1407.                                    "FileSystem::getRawCapacity");
  1408.         return -1;
  1409.     }
  1410.     return jVal.j;
  1411. }
  1412.   
  1413. tOffset hdfsGetUsed(hdfsFS fs)
  1414. {
  1415.     // JAVA EQUIVALENT:
  1416.     //  fs.getRawUsed();
  1417.     //Get the JNIEnv* corresponding to current thread
  1418.     JNIEnv* env = getJNIEnv();
  1419.     if (env == NULL) {
  1420.       errno = EINTERNAL;
  1421.       return -1;
  1422.     }
  1423.     jobject jFS = (jobject)fs;
  1424.     if (!((*env)->IsInstanceOf(env, jFS, 
  1425.                                globalClassReference(HADOOP_DFS, env)))) {
  1426.         fprintf(stderr, "hdfsGetUsed works only on a "
  1427.                 "DistributedFileSystem!n");
  1428.         return -1;
  1429.     }
  1430.     //FileSystem::getRawUsed()
  1431.     jvalue jVal;
  1432.     jthrowable jExc = NULL;
  1433.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jFS, HADOOP_DFS,
  1434.                      "getRawUsed", "()J") != 0) {
  1435.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  1436.                                    "FileSystem::getRawUsed");
  1437.         return -1;
  1438.     }
  1439.     return jVal.j;
  1440. }
  1441.  
  1442. static int
  1443. getFileInfoFromStat(JNIEnv *env, jobject jStat, hdfsFileInfo *fileInfo)
  1444. {
  1445.     jvalue jVal;
  1446.     jthrowable jExc = NULL;
  1447.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jStat,
  1448.                      HADOOP_STAT, "isDir", "()Z") != 0) {
  1449.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  1450.                                    "FileStatus::isDir");
  1451.         return -1;
  1452.     }
  1453.     fileInfo->mKind = jVal.z ? kObjectKindDirectory : kObjectKindFile;
  1454.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jStat,
  1455.                      HADOOP_STAT, "getReplication", "()S") != 0) {
  1456.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  1457.                                    "FileStatus::getReplication");
  1458.         return -1;
  1459.     }
  1460.     fileInfo->mReplication = jVal.s;
  1461.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jStat,
  1462.                      HADOOP_STAT, "getBlockSize", "()J") != 0) {
  1463.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  1464.                                    "FileStatus::getBlockSize");
  1465.         return -1;
  1466.     }
  1467.     fileInfo->mBlockSize = jVal.j;
  1468.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jStat,
  1469.                      HADOOP_STAT, "getModificationTime", "()J") != 0) {
  1470.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  1471.                                    "FileStatus::getModificationTime");
  1472.         return -1;
  1473.     }
  1474.     fileInfo->mLastMod = (tTime) (jVal.j / 1000);
  1475.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jStat,
  1476.                      HADOOP_STAT, "getAccessTime", "()J") != 0) {
  1477.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  1478.                                    "FileStatus::getAccessTime");
  1479.         return -1;
  1480.     }
  1481.     fileInfo->mLastAccess = (tTime) (jVal.j / 1000);
  1482.     if (fileInfo->mKind == kObjectKindFile) {
  1483.         if (invokeMethod(env, &jVal, &jExc, INSTANCE, jStat,
  1484.                          HADOOP_STAT, "getLen", "()J") != 0) {
  1485.             errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  1486.                                        "FileStatus::getLen");
  1487.             return -1;
  1488.         }
  1489.         fileInfo->mSize = jVal.j;
  1490.     }
  1491.     jobject jPath;
  1492.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jStat, HADOOP_STAT,
  1493.                      "getPath", "()Lorg/apache/hadoop/fs/Path;") ||
  1494.             jVal.l == NULL) { 
  1495.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  1496.                                    "Path::getPath");
  1497.         return -1;
  1498.     }
  1499.     jPath = jVal.l;
  1500.     jstring     jPathName;
  1501.     const char *cPathName;
  1502.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jPath, HADOOP_PATH,
  1503.                      "toString", "()Ljava/lang/String;")) { 
  1504.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  1505.                                    "Path::toString");
  1506.         destroyLocalReference(env, jPath);
  1507.         return -1;
  1508.     }
  1509.     jPathName = jVal.l;
  1510.     cPathName = (const char*) ((*env)->GetStringUTFChars(env, jPathName, NULL));
  1511.     fileInfo->mName = strdup(cPathName);
  1512.     (*env)->ReleaseStringUTFChars(env, jPathName, cPathName);
  1513.     destroyLocalReference(env, jPath);
  1514.     destroyLocalReference(env, jPathName);
  1515.     jstring     jUserName;
  1516.     const char* cUserName;
  1517.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jStat, HADOOP_STAT,
  1518.                     "getOwner", "()Ljava/lang/String;")) {
  1519.         fprintf(stderr, "Call to org.apache.hadoop.fs."
  1520.                 "FileStatus::getOwner failed!n");
  1521.         errno = EINTERNAL;
  1522.         return -1;
  1523.     }
  1524.     jUserName = jVal.l;
  1525.     cUserName = (const char*) ((*env)->GetStringUTFChars(env, jUserName, NULL));
  1526.     fileInfo->mOwner = strdup(cUserName);
  1527.     (*env)->ReleaseStringUTFChars(env, jUserName, cUserName);
  1528.     destroyLocalReference(env, jUserName);
  1529.     jstring     jGroupName;
  1530.     const char* cGroupName;
  1531.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jStat, HADOOP_STAT,
  1532.                     "getGroup", "()Ljava/lang/String;")) {
  1533.         fprintf(stderr, "Call to org.apache.hadoop.fs."
  1534.                 "FileStatus::getGroup failed!n");
  1535.         errno = EINTERNAL;
  1536.         return -1;
  1537.     }
  1538.     jGroupName = jVal.l;
  1539.     cGroupName = (const char*) ((*env)->GetStringUTFChars(env, jGroupName, NULL));
  1540.     fileInfo->mGroup = strdup(cGroupName);
  1541.     (*env)->ReleaseStringUTFChars(env, jGroupName, cGroupName);
  1542.     destroyLocalReference(env, jGroupName);
  1543.     jobject jPermission;
  1544.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jStat, HADOOP_STAT,
  1545.                      "getPermission", "()Lorg/apache/hadoop/fs/permission/FsPermission;") ||
  1546.             jVal.l == NULL) {
  1547.         fprintf(stderr, "Call to org.apache.hadoop.fs."
  1548.                 "FileStatus::getPermission failed!n");
  1549.         errno = EINTERNAL;
  1550.         return -1;
  1551.     }
  1552.     jPermission = jVal.l;
  1553.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jPermission, HADOOP_FSPERM,
  1554.                          "toShort", "()S") != 0) {
  1555.             fprintf(stderr, "Call to org.apache.hadoop.fs.permission."
  1556.                     "FsPermission::toShort failed!n");
  1557.             errno = EINTERNAL;
  1558.             return -1;
  1559.     }
  1560.     fileInfo->mPermissions = jVal.s;
  1561.     destroyLocalReference(env, jPermission);
  1562.     return 0;
  1563. }
  1564. static int
  1565. getFileInfo(JNIEnv *env, jobject jFS, jobject jPath, hdfsFileInfo *fileInfo)
  1566. {
  1567.     // JAVA EQUIVALENT:
  1568.     //  fs.isDirectory(f)
  1569.     //  fs.getModificationTime()
  1570.     //  fs.getAccessTime()
  1571.     //  fs.getLength(f)
  1572.     //  f.getPath()
  1573.     //  f.getOwner()
  1574.     //  f.getGroup()
  1575.     //  f.getPermission().toShort()
  1576.     jobject jStat;
  1577.     jvalue  jVal;
  1578.     jthrowable jExc = NULL;
  1579.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jFS, HADOOP_FS,
  1580.                      "exists", JMETHOD1(JPARAM(HADOOP_PATH), "Z"),
  1581.                      jPath) != 0) {
  1582.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  1583.                                    "FileSystem::exists");
  1584.         return -1;
  1585.     }
  1586.     if (jVal.z == 0) {
  1587.       errno = ENOENT;
  1588.       return -1;
  1589.     }
  1590.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jFS, HADOOP_FS,
  1591.                      "getFileStatus", JMETHOD1(JPARAM(HADOOP_PATH), JPARAM(HADOOP_STAT)),
  1592.                      jPath) != 0) {
  1593.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  1594.                                    "FileSystem::getFileStatus");
  1595.         return -1;
  1596.     }
  1597.     jStat = jVal.l;
  1598.     int ret =  getFileInfoFromStat(env, jStat, fileInfo); 
  1599.     destroyLocalReference(env, jStat);
  1600.     return ret;
  1601. }
  1602. hdfsFileInfo* hdfsListDirectory(hdfsFS fs, const char* path, int *numEntries)
  1603. {
  1604.     // JAVA EQUIVALENT:
  1605.     //  Path p(path);
  1606.     //  Path []pathList = fs.listPaths(p)
  1607.     //  foreach path in pathList 
  1608.     //    getFileInfo(path)
  1609.     //Get the JNIEnv* corresponding to current thread
  1610.     JNIEnv* env = getJNIEnv();
  1611.     if (env == NULL) {
  1612.       errno = EINTERNAL;
  1613.       return NULL;
  1614.     }
  1615.     jobject jFS = (jobject)fs;
  1616.     //Create an object of org.apache.hadoop.fs.Path
  1617.     jobject jPath = constructNewObjectOfPath(env, path);
  1618.     if (jPath == NULL) {
  1619.         return NULL;
  1620.     }
  1621.     hdfsFileInfo *pathList = 0; 
  1622.     jobjectArray jPathList = NULL;
  1623.     jvalue jVal;
  1624.     jthrowable jExc = NULL;
  1625.     if (invokeMethod(env, &jVal, &jExc, INSTANCE, jFS, HADOOP_DFS, "listStatus",
  1626.                      JMETHOD1(JPARAM(HADOOP_PATH), JARRPARAM(HADOOP_STAT)),
  1627.                      jPath) != 0) {
  1628.         errno = errnoFromException(jExc, env, "org.apache.hadoop.fs."
  1629.                                    "FileSystem::listStatus");
  1630.         destroyLocalReference(env, jPath);
  1631.         return NULL;
  1632.     }
  1633.     jPathList = jVal.l;
  1634.     //Figure out no of entries in that directory
  1635.     jsize jPathListSize = (*env)->GetArrayLength(env, jPathList);
  1636.     *numEntries = jPathListSize;
  1637.     if (jPathListSize == 0) {
  1638.         errno = 0;
  1639.         goto done;
  1640.     }
  1641.     //Allocate memory
  1642.     pathList = calloc(jPathListSize, sizeof(hdfsFileInfo));
  1643.     if (pathList == NULL) {
  1644.         errno = ENOMEM;
  1645.         goto done;
  1646.     }
  1647.     //Save path information in pathList
  1648.     jsize i;
  1649.     jobject tmpStat;
  1650.     for (i=0; i < jPathListSize; ++i) {
  1651.         tmpStat = (*env)->GetObjectArrayElement(env, jPathList, i);
  1652.         if (getFileInfoFromStat(env, tmpStat, &pathList[i])) {
  1653.             hdfsFreeFileInfo(pathList, jPathListSize);
  1654.             destroyLocalReference(env, tmpStat);
  1655.             pathList = NULL;
  1656.             goto done;
  1657.         }
  1658.         destroyLocalReference(env, tmpStat);
  1659.     }
  1660.     done:
  1661.     //Delete unnecessary local references
  1662.     destroyLocalReference(env, jPath);
  1663.     destroyLocalReference(env, jPathList);
  1664.     return pathList;
  1665. }
  1666. hdfsFileInfo *hdfsGetPathInfo(hdfsFS fs, const char* path)
  1667. {
  1668.     // JAVA EQUIVALENT:
  1669.     //  File f(path);
  1670.     //  fs.isDirectory(f)
  1671.     //  fs.lastModified() ??
  1672.     //  fs.getLength(f)
  1673.     //  f.getPath()
  1674.     //Get the JNIEnv* corresponding to current thread
  1675.     JNIEnv* env = getJNIEnv();
  1676.     if (env == NULL) {
  1677.       errno = EINTERNAL;
  1678.       return NULL;
  1679.     }
  1680.     jobject jFS = (jobject)fs;
  1681.     //Create an object of org.apache.hadoop.fs.Path
  1682.     jobject jPath = constructNewObjectOfPath(env, path);
  1683.     if (jPath == NULL) {
  1684.         return NULL;
  1685.     }
  1686.     hdfsFileInfo *fileInfo = calloc(1, sizeof(hdfsFileInfo));
  1687.     if (getFileInfo(env, jFS, jPath, fileInfo)) {
  1688.         hdfsFreeFileInfo(fileInfo, 1);
  1689.         fileInfo = NULL;
  1690.         goto done;
  1691.     }
  1692.     done:
  1693.     //Delete unnecessary local references
  1694.     destroyLocalReference(env, jPath);
  1695.     return fileInfo;
  1696. }
  1697. void hdfsFreeFileInfo(hdfsFileInfo *hdfsFileInfo, int numEntries)
  1698. {
  1699.     //Free the mName
  1700.     int i;
  1701.     for (i=0; i < numEntries; ++i) {
  1702.         if (hdfsFileInfo[i].mName) {
  1703.             free(hdfsFileInfo[i].mName);
  1704.         }
  1705.     }
  1706.     //Free entire block
  1707.     free(hdfsFileInfo);
  1708. }
  1709. /**
  1710.  * vim: ts=4: sw=4: et:
  1711.  */