/* The example function.
 * Creates a file named "unix2win.h5" with an external link pointing to
 * the file "u2w/u2w_target.h5".
 *
 * Registers a new traversal function for external links and then
 * follows the external link to open the target file.
 */
static int
unix2win_example(void)
{
    hid_t  fid = (-1);         /* File ID */
    hid_t  gid = (-1);         /* Group ID */

    /* Create the target file. */
#ifdef H5_HAVE_WIN32_API
    if((fid=H5Fcreate("u2w\\u2w_target.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT))<0) goto error;
#else
    if((fid=H5Fcreate("u2w/u2w_target.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT))<0) goto error;
#endif
    if(H5Fclose(fid) < 0) goto error;

    /* Create the source file with an external link in Windows format */
    if((fid=H5Fcreate("unix2win.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT))<0) goto error;

    /* Create the external link */
    if(H5Lcreate_external("u2w/../u2w/u2w_target.h5", "/", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) goto error;

    /* If we are not on Windows, assume we are on a Unix-y filesystem and
     * follow the external link normally.
     * If we are on Windows, register the unix2win traversal function so
     * that external links can be traversed.
     */

#ifdef H5_HAVE_WIN32_API
    /* Register the elink_unix2win class defined above to replace default
     * external links
     */
    if(H5Lregister(elink_unix2win_class) < 0) goto error;
#endif

    /* Now follow the link */
    if((gid = H5Gopen2(fid, "ext_link", H5P_DEFAULT)) < 0) goto error;
    printf("Successfully followed external link.\n");

    /* Close the group and the file */
    if(H5Gclose(gid) <0) goto error;
    if(H5Fclose(fid) <0) goto error;

    return 0;

 error:
    printf("Error!\n");
    H5E_BEGIN_TRY {
      H5Gclose (gid);
      H5Fclose (fid);
    } H5E_END_TRY;
    return -1;
}
Beispiel #2
0
int
main (void)
{
  hid_t fid1=-1;
  hid_t fid2=-1;
  hid_t gid=-1;
  char filename1[NAME_BUF_SIZE];
  char filename2[NAME_BUF_SIZE];

  /* Name the files differently depending on the endianness of this platform */

  switch(H5Tget_order(H5T_NATIVE_INT))
  {
    case H5T_ORDER_LE:
      strcpy(filename1, NAME_LE_1);
      strcpy(filename2, NAME_LE_2);
      break;
    case H5T_ORDER_BE:
      strcpy(filename1, NAME_BE_1);
      strcpy(filename2, NAME_BE_2);
      break;
    default:
      goto error;
  }

  /* Create the two files */
  if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) goto error;
  if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) goto error;

  /* Create two groups in the second file */
  if((gid = H5Gcreate2(fid2, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) goto error;
  if((H5Gclose(gid)) < 0) goto error;
  if((gid = H5Gcreate2(fid2, "group/subgroup", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) goto error;
  if((H5Gclose(gid)) < 0) goto error;

  /* Create an external link in the first file pointing to the group in the second file */
  if(H5Lcreate_external(filename2, "group", fid1, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) goto error;

  if((H5Fclose(fid1)) < 0) goto error;
  if((H5Fclose(fid2)) < 0) goto error;

  return 0;

error:
  H5E_BEGIN_TRY {
    H5Fclose(fid1);
    H5Fclose(fid2);
    H5Gclose(gid);
  } H5E_END_TRY
  return 1;
}
Beispiel #3
0
/* Basic external link example
 *
 * Creates two files and uses an external link to access an object in the
 * second file from the first file.
 */
static void extlink_example(void)
{
    hid_t source_file_id, targ_file_id;
    hid_t group_id, group2_id;

    /* Create two files, a source and a target */
    source_file_id = H5Fcreate(SOURCE_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    targ_file_id = H5Fcreate(TARGET_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);

    /* Create a group in the target file for the external link to point to. */
    group_id = H5Gcreate2(targ_file_id, "target_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);

    /* Close the group and the target file */
    H5Gclose(group_id);

    /* Create an external link in the source file pointing to the target group.
     * We could instead have created the external link first, then created the
     * group it points to; the order doesn't matter.
     */
    H5Lcreate_external(TARGET_FILE, "target_group", source_file_id, "ext_link", H5P_DEFAULT, H5P_DEFAULT);

    /* Now we can use the external link to create a new group inside the
     * target group (even though the target file is closed!).  The external
     * link works just like a soft link.
     */
    group_id = H5Gcreate2(source_file_id, "ext_link/new_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);

    /* The group is inside the target file and we can access it normally.
     * Here, group_id and group2_id point to the same group inside the
     * target file.
     */
    group2_id = H5Gopen2(targ_file_id, "target_group/new_group", H5P_DEFAULT);

    /* Don't forget to close the IDs we opened. */
    H5Gclose(group2_id);
    H5Gclose(group_id);

    H5Fclose(targ_file_id);
    H5Fclose(source_file_id);

    /* The link from the source file to the target file will work as long as
     * the target file can be found.  If the target file is moved, renamed,
     * or deleted in the filesystem, HDF5 won't be able to find it and the
     * external link will "dangle."
     */
}
Beispiel #4
0
/*
 * Class:     hdf_hdf5lib_H5
 * Method:    H5Lcreate_external
 * Signature: (Ljava/lang/String;Ljava/lang/String;JLjava/lang/String;JJ)V
 */
JNIEXPORT void JNICALL
Java_hdf_hdf5lib_H5_H5Lcreate_1external
    (JNIEnv *env, jclass clss, jstring file_name, jstring cur_name,
        jlong dst_loc_id, jstring dst_name, jlong create_id, jlong access_id)
{
    herr_t      status = -1;
    const char *lFileName;
    const char *lCurName;
    const char *lDstName;

    PIN_JAVA_STRING_THREE(file_name, lFileName, cur_name, lCurName, dst_name, lDstName);
    if (lFileName != NULL && lCurName != NULL && lDstName != NULL) {
        status = H5Lcreate_external(lFileName, lCurName, (hid_t)dst_loc_id, lDstName, (hid_t)create_id, (hid_t)access_id);

        UNPIN_JAVA_STRING_THREE(file_name, lFileName, cur_name, lCurName, dst_name, lDstName);

        if (status < 0)
            h5libraryError(env);
    }
} /* end Java_hdf_hdf5lib_H5_H5Lcreate_1external */
Beispiel #5
0
/* External link prefix example
 *
 * Uses a group access property list to set a "prefix" for the filenames
 * accessed through an external link.
 *
 * Group access property lists inherit from link access property lists;
 * the external link prefix property is actually a property of LAPLs.
 *
 * This example requires a "red" directory and a "blue" directory to exist
 * where it is run (so to run this example on Unix, first mkdir red and mkdir
 * blue).
 */
static void extlink_prefix_example(void)
{
    hid_t source_file_id, red_file_id, blue_file_id;
    hid_t group_id, group2_id;
    hid_t gapl_id;

    /* Create three files, a source and two targets.  The targets will have
     * the same name, but one will be located in the red directory and one will
     * be located in the blue directory */
    source_file_id = H5Fcreate(PREFIX_SOURCE_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    red_file_id = H5Fcreate("red/prefix_target.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    blue_file_id = H5Fcreate("blue/prefix_target.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);

    /* This test needs a red and a blue directory in the filesystem. If they're not present,
     * trying to create the files above will fail.
     */
    if(red_file_id < 0 || blue_file_id < 0)
      printf("This test requires directories named 'red' and 'blue' to exist. Did you forget to create them?\n");

    /* Create an external link in the source file pointing to the root group of
     * a file named prefix_target.h5.  This file doesn't exist in the current
     * directory, but the files in the red and blue directories both have this
     * name.
     */
    H5Lcreate_external("prefix_target.h5", "/", source_file_id, "ext_link", H5P_DEFAULT, H5P_DEFAULT);

    /* If we tried to traverse the external link now, we would fail (since the
     * file it points to doesn't exist).  Instead, we'll create a group access
     * property list that will provide a prefix path to the external link.
     * Group access property lists inherit the properties of link access
     * property lists.
     */
    gapl_id = H5Pcreate(H5P_GROUP_ACCESS);
    H5Pset_elink_prefix(gapl_id, "red/");

    /* Now if we traverse the external link, HDF5 will look for an external
     * file named red/prefix_target.h5, which exists.
     * To pass the group access property list, we need to use H5Gopen2.
     */
    group_id = H5Gopen2(source_file_id, "ext_link", gapl_id);

    /* Now we can use the open group ID to create a new group inside the
     * "red" file.
     */
    group2_id = H5Gcreate2(group_id, "pink", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);

    /* Close both groups. */
    H5Gclose(group2_id);
    H5Gclose(group_id);

    /* If we change the prefix, the same external link can find a file in the blue
     * directory.
     */
    H5Pset_elink_prefix(gapl_id, "blue/");
    group_id = H5Gopen2(source_file_id, "ext_link", gapl_id);
    group2_id = H5Gcreate2(group_id, "sky blue", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);

    /* Close both groups. */
    H5Gclose(group2_id);
    H5Gclose(group_id);

    /* Each file has had a group created inside it using the same external link. */
    group_id = H5Gopen2(red_file_id, "pink", H5P_DEFAULT);
    group2_id = H5Gopen2(blue_file_id, "sky blue", H5P_DEFAULT);

    /* Clean up our open IDs */
    H5Gclose(group2_id);
    H5Gclose(group_id);
    H5Pclose(gapl_id);
    H5Fclose(blue_file_id);
    H5Fclose(red_file_id);
    H5Fclose(source_file_id);

    /* User-defined links can expand on the ability to pass in parameters
     * using an access property list; for instance, a user-defined link
     * might function like an external link but allow the full filename to be
     * passed in through the access property list.
     */
}
Beispiel #6
0
/*-------------------------------------------------------------------------
 * Function: gen_extlink_src
 *
 * Purpose: generate source external link objs
 *
 * Programmer: Jonathan Kim (March 03, 2010)
 *------------------------------------------------------------------------*/
static herr_t gen_extlink_src(hid_t loc_id)
{
    hid_t gid=0;
    int status;
    herr_t ret = SUCCEED;

    /*-----------------------------------------------------------------------
    * Groups
    *------------------------------------------------------------------------*/
    gid = H5Gcreate2(loc_id, "/group_ext", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    if (gid < 0)
    {
        fprintf(stderr, "Error: %s %d> H5Gcreate2 failed.\n", FUNC, __LINE__);
        ret = FAIL;
        goto out;
    }

    /*-----------------------------------------------------------------------
    * External links
    *------------------------------------------------------------------------*/
    /* link to dataset */
    status = H5Lcreate_external(HDF_EXT_TRG_FILE, "/simple", gid, "extlink_dset", H5P_DEFAULT, H5P_DEFAULT);
    if (status < 0)
    {
        fprintf(stderr, "Error: %s %d> H5Lcreate_external failed.\n", FUNC, __LINE__);
        ret = FAIL;
        goto out;
    }

    /* link to group */
    status = H5Lcreate_external(HDF_EXT_TRG_FILE, "/group", gid, "extlink_grp", H5P_DEFAULT, H5P_DEFAULT);
    if (status < 0)
    {
        fprintf(stderr, "Error: %s %d> H5Lcreate_external failed.\n", FUNC, __LINE__);
        ret = FAIL;
        goto out;
    }

    /* link to datatype */
    status = H5Lcreate_external(HDF_EXT_TRG_FILE, "/datatype", gid, "extlink_datatype", H5P_DEFAULT, H5P_DEFAULT);
    if (status < 0)
    {
        fprintf(stderr, "Error: %s %d> H5Lcreate_external failed.\n", FUNC, __LINE__);
        ret = FAIL;
        goto out;
    }

    /* dangling link - no obj*/
    status = H5Lcreate_external(HDF_EXT_TRG_FILE, "notyet", gid, "extlink_notyet1", H5P_DEFAULT, H5P_DEFAULT);
    if (status < 0)
    {
        fprintf(stderr, "Error: %s %d> H5Lcreate_external failed.\n", FUNC, __LINE__);
        ret = FAIL;
        goto out;
    }

    /* dangling link - no file */
    status = H5Lcreate_external("notyet_file.h5", "notyet", gid, "extlink_notyet2", H5P_DEFAULT, H5P_DEFAULT);
    if (status < 0)
    {
        fprintf(stderr, "Error: %s %d> H5Lcreate_external failed.\n", FUNC, __LINE__);
        ret = FAIL;
        goto out;
    }

out:
    if(gid > 0)
        H5Gclose(gid);

    return ret;
}
Beispiel #7
0
static void
gent_ub(const char * filename, size_t ub_size, size_t ub_fill)
{
    hid_t fid, group, attr, dataset, space;
    hid_t create_plist;
    hsize_t dims[2];
    int data[2][2], dset1[10][10], dset2[20];
    char buf[BUF_SIZE];
    int i, j;
    size_t u;
    float dset2_1[10], dset2_2[3][5];
    int fd;
    char *bp;

  if(ub_size > 0)
  {
      create_plist = H5Pcreate(H5P_FILE_CREATE);
      H5Pset_userblock(create_plist, (hsize_t)ub_size);
      fid = H5Fcreate(filename, H5F_ACC_TRUNC, create_plist, H5P_DEFAULT);
  }
  else
  {
      fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
  }

  /* create groups */
  group = H5Gcreate2(fid, "/g1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
  H5Gclose(group);

  group = H5Gcreate2(fid, "/g2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
  H5Gclose(group);

  group = H5Gcreate2(fid, "/g1/g1.1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
  H5Gclose(group);

  group = H5Gcreate2(fid, "/g1/g1.2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
  H5Gclose(group);

  group = H5Gcreate2(fid, "/g1/g1.2/g1.2.1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
  H5Gclose(group);

  /* root attributes */
  group = H5Gopen2(fid, "/", H5P_DEFAULT);

  dims[0] = 10;
  space = H5Screate_simple(1, dims, NULL);
  attr = H5Acreate2(group, "attr1", H5T_STD_I8BE, space, H5P_DEFAULT, H5P_DEFAULT);
  sprintf(buf, "abcdefghi");
  H5Awrite(attr, H5T_NATIVE_SCHAR, buf);
  H5Sclose(space);
  H5Aclose(attr);

  dims[0] = 2; dims[1] = 2;
  space = H5Screate_simple(2, dims, NULL);
  attr = H5Acreate2(group, "attr2", H5T_STD_I32BE, space, H5P_DEFAULT, H5P_DEFAULT);
  data[0][0] = 0; data[0][1] = 1; data[1][0] = 2; data[1][1] = 3;
  H5Awrite(attr, H5T_NATIVE_INT, data);
  H5Sclose(space);
  H5Aclose(attr);

  H5Gclose(group);

  group = H5Gopen2(fid, "/g1/g1.1", H5P_DEFAULT);

  /* dset1.1.1 */
  dims[0] = 10; dims[1] = 10;
  space = H5Screate_simple(2, dims, NULL);
  dataset = H5Dcreate2(group, "dset1.1.1", H5T_STD_I32BE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
  for (i = 0; i < 10; i++)
       for (j = 0; j < 10; j++)
            dset1[i][j] = j*i;
  H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset1);
  H5Sclose(space);

  /* attributes of dset1.1.1 */
  dims[0] = 27;
  space = H5Screate_simple(1, dims, NULL);
  attr = H5Acreate2(dataset, "attr1", H5T_STD_I8BE, space, H5P_DEFAULT, H5P_DEFAULT);
  sprintf(buf, "1st attribute of dset1.1.1");
  H5Awrite(attr, H5T_NATIVE_SCHAR, buf);
  H5Sclose(space);
  H5Aclose(attr);

  dims[0] = 27;
  space = H5Screate_simple(1, dims, NULL);
  attr = H5Acreate2(dataset, "attr2", H5T_STD_I8BE, space, H5P_DEFAULT, H5P_DEFAULT);
  sprintf(buf, "2nd attribute of dset1.1.1");
  H5Awrite(attr, H5T_NATIVE_SCHAR, buf);
  H5Sclose(space);
  H5Aclose(attr);

  H5Dclose(dataset);

  /* dset1.1.2 */
  dims[0] = 20;
  space = H5Screate_simple(1, dims, NULL);
  dataset = H5Dcreate2(group, "dset1.1.2", H5T_STD_I32BE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
  for (i = 0; i < 20; i++)
       dset2[i] = i;
  H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2);
  H5Sclose(space);
  H5Dclose(dataset);

  H5Gclose(group);

  /* external link */
  H5Lcreate_external("somefile", "somepath", fid, "/g1/g1.2/extlink", H5P_DEFAULT, H5P_DEFAULT);

  /* soft link */
  group = H5Gopen2(fid, "/g1/g1.2/g1.2.1", H5P_DEFAULT);
  H5Lcreate_soft("somevalue", group, "slink", H5P_DEFAULT, H5P_DEFAULT);
  H5Gclose(group);

  group = H5Gopen2(fid, "/g2", H5P_DEFAULT);

  /* dset2.1 */
  dims[0] = 10;
  space = H5Screate_simple(1, dims, NULL);
  dataset = H5Dcreate2(group, "dset2.1", H5T_IEEE_F32BE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
  for (i = 0; i < 10; i++)
       dset2_1[i] = (float)((float)i * 0.1F + 1.0F);
  H5Dwrite(dataset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2_1);
  H5Sclose(space);
  H5Dclose(dataset);

  /* dset2.2 */
  dims[0] = 3; dims[1] = 5;
  space = H5Screate_simple(2, dims, NULL);
  dataset = H5Dcreate2(group, "dset2.2", H5T_IEEE_F32BE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
  for (i = 0; i < 3; i++)
       for (j = 0; j < 5; j++)
            dset2_2[i][j] = (float)(((float)i + 1.0F) * (float)j * 0.1F);
  H5Dwrite(dataset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2_2);
  H5Sclose(space);
  H5Dclose(dataset);

  H5Gclose(group);

  /* user-defined link */
  H5Lregister(UD_link_class);
  H5Lcreate_ud(fid, "/g2/udlink", (H5L_type_t)MY_LINKCLASS, NULL, (size_t)0, H5P_DEFAULT, H5P_DEFAULT);

  H5Fclose(fid);

  /* If a user block is being used, write to it here */
  if(ub_size > 0)
  {
    ssize_t nbytes;

    HDassert(ub_size <= BUF_SIZE);

    fd = HDopen(filename, O_RDWR);
    HDassert(fd >= 0);

    /* fill buf with pattern */
    HDmemset(buf, '\0', ub_size);
    bp = buf;
    for (u = 0; u < ub_fill; u++)
      *bp++ = pattern[u % 10];

    nbytes = HDwrite(fd, buf, ub_size);
    HDassert(nbytes >= 0);

    HDclose(fd);
  }
}
Beispiel #8
0
int
main( void )
{
	hid_t       file1, file2, group, fapl;      /* Handles */
	herr_t      status;

	/*
	 * Create file access property list and set it to allow caching of open
	 * files visited through external links.
	 */
	fapl = H5Pcreate( H5P_FILE_ACCESS );
	status = H5Pset_elink_file_cache_size( fapl, 8 );

	/*
	 * Create a new file using the file access property list.
	 */
	file1 = H5Fcreate( FILE, H5F_ACC_TRUNC, H5P_DEFAULT, fapl );

	/*
	 * Create files to serve as targets for external links.
	 */
	file2 = H5Fcreate( EXT_FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT );
	status = H5Fclose( file2 );
	file2 = H5Fcreate( EXT_FILE2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT );
	status = H5Fclose( file2 );
	file2 = H5Fcreate( EXT_FILE3, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT );
	status = H5Fclose( file2 );

	/*
	 * Create external links to the target files.
	 */
	status = H5Lcreate_external( EXT_FILE1, "/", file1, "link_to_1",
	                             H5P_DEFAULT, H5P_DEFAULT );
	status = H5Lcreate_external( EXT_FILE2, "/", file1, "link_to_2",
	                             H5P_DEFAULT, H5P_DEFAULT );
	status = H5Lcreate_external( EXT_FILE3, "/", file1, "link_to_3",
	                             H5P_DEFAULT, H5P_DEFAULT );

	/*
	 * Open and close the targets of all three external links (these will be the
	 * root groups of the target files).  The target files should be held open
	 * by the root file's external file cache after traversal.
	 */
	group = H5Gopen( file1, "/link_to_1", H5P_DEFAULT );
	status = H5Gclose( group );
	group = H5Gopen( file1, "/link_to_2", H5P_DEFAULT );
	status = H5Gclose( group );
	group = H5Gopen( file1, "/link_to_3", H5P_DEFAULT );
	status = H5Gclose( group );

	/*
	 * Open and close the targets of all three external links again.  The target
	 * files should already be held open by the root file's external file cache,
	 * so the library will not actually have to issue an "open" system call.
	 */
	group = H5Gopen( file1, "/link_to_1", H5P_DEFAULT );
	status = H5Gclose( group );
	group = H5Gopen( file1, "/link_to_2", H5P_DEFAULT );
	status = H5Gclose( group );
	group = H5Gopen( file1, "/link_to_3", H5P_DEFAULT );
	status = H5Gclose( group );

	/*
	 * Release the root file's external file cache.  This will close all the
	 * external link target files.
	 */
	status = H5Frelease_file_cache( file1 );

	/*
	 * Close and release resources.
	 */
	status = H5Pclose( fapl );
	status = H5Fclose( file1 );

	return 0;
}
Beispiel #9
0
/*-------------------------------------------------------------------------
 * Function:	test_4
 *
 * Purpose:	Tests opening an external link twice.  It exposed a bug
 *              in the library.  This function tests the fix.  This test
 *              doesn't work with MULTI driver.
 *
 * Return:	Success:	0
 *
 * 		Failure:	number of errors
 *
 * Programmer:	Raymond Lu
 *              5 November 2007
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
test_4 (hid_t fapl)
{
    hid_t fid = -1;
    hid_t gid = -1;
    hid_t xid = -1;
    hid_t xid2 = -1;
    char  filename[1024];		/*file name			*/
    char  pathname[1024];
    char *srcdir = getenv("srcdir"); /*where the src code is located*/

    TESTING("opening external link twice");

    /* Make a copy of the FAPL, in order to switch to the sec2 driver */
    /* (useful when running test with another VFD) */
    if((fapl = H5Pcopy(fapl)) < 0) FAIL_STACK_ERROR;

    /* Switch local copy of the fapl to the sec2 driver */
    if(H5Pset_fapl_sec2(fapl) < 0) FAIL_STACK_ERROR;

    h5_fixname(FILENAME[3], fapl, filename, sizeof filename);

    if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
        goto error;

    if((gid = H5Gopen2(fid, "/", H5P_DEFAULT)) < 0)
        goto error;

    pathname[0] = '\0';
    /* Generate correct name for test file by prepending the source path */
    if(srcdir && ((HDstrlen(srcdir) + HDstrlen(LINKED_FILE) + 1) < sizeof(pathname))) {
        HDstrcpy(pathname, srcdir);
        HDstrcat(pathname, "/");
    }
    HDstrcat(pathname, LINKED_FILE);

    /* Create an external link to an existing file*/
    if(H5Lcreate_external(pathname, "/group", gid, " link", H5P_DEFAULT, H5P_DEFAULT) < 0)
        goto error;

    if(H5Gclose(gid) < 0)
        goto error;

    if(H5Fclose(fid) < 0)
        goto error;

    /* Reopen the file */
    if((fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
        goto error;

    /* Open the external link which is "/ link" as created previously via H5Lcreate_external() */
    if((xid = H5Gopen2(fid, "/ link", H5P_DEFAULT)) < 0)
        goto error;

    /* Open the external link twice */
    if((xid2 = H5Gopen2(xid, ".", H5P_DEFAULT)) < 0)
        goto error;

    if(H5Gclose(xid2) < 0)
        goto error;

    if(H5Gclose(xid) < 0)
        goto error;

    if(H5Fclose(fid) < 0)
        goto error;

    if(H5Pclose(fapl) < 0)
        TEST_ERROR

    PASSED();

    return 0;

 error:
    H5E_BEGIN_TRY {
        H5Gclose(gid);
        H5Gclose(xid);
        H5Gclose(xid2);
        H5Fclose(fid);
    } H5E_END_TRY;
    return 1;
}