# Symbolic links with relative path

**URL:** <https://forum.hdfgroup.org/t/symbolic-links-with-relative-path/9552>\
**Category:** HDF5 Library\
**Created:** [March 24, 2022, 10:27pm UTC](https://forum.hdfgroup.org/t/symbolic-links-with-relative-path/9552 "2022-03-24T22:27:14Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![kerim.khemraev](https://forum.hdfgroup.org/letter_avatar_proxy/v4/letter/k/b9bd4f/32.png) [@kerim.khemraev](https://forum.hdfgroup.org/u/kerim.khemraev)\
**Post date:** [March 24, 2022, 10:27pm UTC](https://forum.hdfgroup.org/t/symbolic-links-with-relative-path/9552/1 "2022-03-24T22:27:14Z")

</div>

Hi,

I know that it is possible to set relative path to the target when creating soft link for example.  
But what if the target is one level above in the hierarchy?  
For example the target dataset is located `/dset`.  
And the soft link are going to be placed to `/group/dset_link`.  
What will be the relative path in that case? I ve tried to set it as `../dset` but it seem not to work…

Also is there any restricted symbols for link names? Or is there some rules like the link name must not start with space…

---

<div class="post-metadata">

**Author:** ![gheber](https://forum.hdfgroup.org/user_avatar/forum.hdfgroup.org/gheber/32/1919_2.png) [@gheber](https://forum.hdfgroup.org/u/gheber)\
**Post date:** [March 26, 2022, 1:55am UTC](https://forum.hdfgroup.org/t/symbolic-links-with-relative-path/9552/2 "2022-03-26T01:55:23Z")

</div>

In HDF5 path names, `..` does not have the meaning it does in a shell. `..` is a legitimate link name. In the example below, two groups are created. The first is linked as `..` under the root group, the second is linked as `...` in the first group.

In HDF5, `..` cannot have the meaning of “one level above in the hierarchy”, because we are dealing with multi-graphs. A node can have multiple (direct) parents, and the concept of level is meaningful only for tree-like structures.

> [@kerim.khemraev](#):
>
> Also is there any restricted symbols for link names? Or is there some rules like the link name must not start with spac

Only the path separator `/` and the combination `./` and `/./` are special. A single space or multiple spaces are legitimate link names.

G.

### Example

```auto
#include "hdf5.h"
#include <stdlib.h>

int main()
{
  __label__ fail_group, fail_prop, fail_lcpl, fail_file;
  int ret_val = EXIT_SUCCESS;
  hid_t file, lcpl, group;
  char fname[] = "g2.h5";
  char path[] = "./../...";

  if ((file = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) ==
      H5I_INVALID_HID) {
    ret_val = EXIT_FAILURE;
    goto fail_file;
  }

  if ((lcpl = H5Pcreate(H5P_LINK_CREATE)) == H5I_INVALID_HID) {
    ret_val = EXIT_FAILURE;
    goto fail_lcpl;
  }
  // ensure that intermediate groups are created automatically
  if (H5Pset_create_intermediate_group(lcpl, 1) < 0) {
    ret_val = EXIT_FAILURE;
    goto fail_prop;
  }
  // create two groups
  if ((group = H5Gcreate(file, path, lcpl, H5P_DEFAULT, H5P_DEFAULT)) ==
      H5I_INVALID_HID) {
    ret_val = EXIT_FAILURE;
    goto fail_group;
  }
  H5Gclose(group);
fail_group:
fail_prop:
  H5Pclose(lcpl);
fail_lcpl:
  H5Fclose(file);
fail_file:
  return ret_val;
}

```

```auto
$ h5dump g2.h5 
HDF5 "g2.h5" {
GROUP "/" {
   GROUP ".." {
      GROUP "..." {
      }
   }
}

```

---

<div class="post-metadata">

**Author:** ![gheber](https://forum.hdfgroup.org/user_avatar/forum.hdfgroup.org/gheber/32/1919_2.png) [@gheber](https://forum.hdfgroup.org/u/gheber)\
**Post date:** [March 27, 2022, 12:30am UTC](https://forum.hdfgroup.org/t/symbolic-links-with-relative-path/9552/3 "2022-03-27T00:30:21Z")

</div>

I forgot to mention that in HDF5 the ‘relative’ in ‘relative path’ always means relative to the accompanying handle `loc_id`, e.g., file handle, group handle, etc.

G.

---

<div class="post-metadata">

**Author:** ![kerim.khemraev](https://forum.hdfgroup.org/letter_avatar_proxy/v4/letter/k/b9bd4f/32.png) [@kerim.khemraev](https://forum.hdfgroup.org/u/kerim.khemraev)\
**Post date:** [March 27, 2022, 2:14am UTC](https://forum.hdfgroup.org/t/symbolic-links-with-relative-path/9552/4 "2022-03-27T02:14:57Z")

</div>

Thank you very much for such comprehensive answer.

> [@gheber](#):
>
> A single space or multiple spaces are legitimate link names.

Very interesting, good to know

---

<div class="post-metadata">

**Author:** ![brian.maranville](https://forum.hdfgroup.org/letter_avatar_proxy/v4/letter/b/a698b9/32.png) [@brian.maranville](https://forum.hdfgroup.org/u/brian.maranville)\
**Post date:** [May 10, 2023, 1:46pm UTC](https://forum.hdfgroup.org/t/symbolic-links-with-relative-path/9552/5 "2023-05-10T13:46:36Z")

</div>

While a node can have multiple parents, if it is retrieved by name the names are in a tree structure, so one could construct a function that takes a in input path and resolves a soft link stored in that node relative to that input path. It seems like that might have value.

---

<div class="post-metadata">

**Author:** ![gheber](https://forum.hdfgroup.org/user_avatar/forum.hdfgroup.org/gheber/32/1919_2.png) [@gheber](https://forum.hdfgroup.org/u/gheber)\
**Post date:** [May 11, 2023, 12:56pm UTC](https://forum.hdfgroup.org/t/symbolic-links-with-relative-path/9552/6 "2023-05-11T12:56:53Z")

</div>

When you say ‘node,’ you mean ‘group,’ right? (Because that’s the only type of place where we store links…) So you are asking for a function that retrieves the soft link’s value and, if it’s a relative path, normalizes it w.r.t. to the given input path and returns that path?

G.

---

<div class="post-metadata">

**Author:** ![brian.maranville](https://forum.hdfgroup.org/letter_avatar_proxy/v4/letter/b/a698b9/32.png) [@brian.maranville](https://forum.hdfgroup.org/u/brian.maranville)\
**Post date:** [May 11, 2023, 2:04pm UTC](https://forum.hdfgroup.org/t/symbolic-links-with-relative-path/9552/7 "2023-05-11T14:04:39Z")

</div>

Yes - I mean like doing like what POSIX filesystems do, where you can make soft links and hard links, and relative soft links are supported there. You can make a soft relative link and then make a hard link to that soft link somewhere else in the tree, and the filesystem will try to resolve it relative to the path through which it is accessed.

---

<div class="post-metadata">

**Author:** ![gheber](https://forum.hdfgroup.org/user_avatar/forum.hdfgroup.org/gheber/32/1919_2.png) [@gheber](https://forum.hdfgroup.org/u/gheber)\
**Post date:** [May 11, 2023, 4:32pm UTC](https://forum.hdfgroup.org/t/symbolic-links-with-relative-path/9552/8 "2023-05-11T16:32:10Z")

</div>

> [@brian.maranville](#):
>
> You can make a soft relative link and then make a hard link to that soft link somewhere else in the tree

You mean a hard link to the group that contains that soft link? (There is no such thing as a hard link to a soft link in HDF5…)

G.

---

<div class="post-metadata">

**Author:** ![brian.maranville](https://forum.hdfgroup.org/letter_avatar_proxy/v4/letter/b/a698b9/32.png) [@brian.maranville](https://forum.hdfgroup.org/u/brian.maranville)\
**Post date:** [May 11, 2023, 5:26pm UTC](https://forum.hdfgroup.org/t/symbolic-links-with-relative-path/9552/9 "2023-05-11T17:26:32Z")

</div>

Ah - I see. So it would necessarily be different from a POSIX system

---

<div class="post-metadata">

**Author:** ![gheber](https://forum.hdfgroup.org/user_avatar/forum.hdfgroup.org/gheber/32/1919_2.png) [@gheber](https://forum.hdfgroup.org/u/gheber)\
**Post date:** [May 11, 2023, 11:58pm UTC](https://forum.hdfgroup.org/t/symbolic-links-with-relative-path/9552/10 "2023-05-11T23:58:52Z")

</div>

Just to recap:

```auto
mkdir -p test/test1
echo "Hello, World!" > test/foo
ln -s ../foo test/test1/foo

```

This references three inodes, as can be seen by

```auto
ls -Ri test

```

The relative symbolic link resolves correctly.

```auto
:~ cat test/test1/foo
Hello, World!

```

I think what you are suggesting is to mimic this behavior. Correct?

Like hard links/inode numbers in POSIX, HDF5 hard links have object header addresses (`haddr_t`) as their values/destinations. The difference is that if we use the analogy _inode “=” object header_, only two inodes (HDF5 object headers) exist in the HDF5 case.

1. The object header of the group `test/test1`
2. The object header of the “file” `test/foo`

There is no object header for `test/test1/foo`, because that is stored as a (soft) link in the group `test/test1` with destination `../foo`. Nevertheless, the function you are suggesting could be implemented.

Can you give us a use case?

G.

---

<div class="post-metadata">

**Author:** ![brian.maranville](https://forum.hdfgroup.org/letter_avatar_proxy/v4/letter/b/a698b9/32.png) [@brian.maranville](https://forum.hdfgroup.org/u/brian.maranville)\
**Post date:** [May 12, 2023, 1:31pm UTC](https://forum.hdfgroup.org/t/symbolic-links-with-relative-path/9552/11 "2023-05-12T13:31:16Z")

</div>

Sometimes soft links are very useful for pre-templating a file for us (we have a schema that is known ahead of time for links, e.g. NeXus, and it is convenient to make the links before the data is written)

But then we also would like to be able to embed those groups into another file, and if we use soft links they will no longer be valid if the group is moved to a new base path (we can walk the tree and rewrite all the soft links of course, but it would be nice if we didn’t have to).

---

<div class="post-metadata">

**Author:** ![henrymateo0609](https://forum.hdfgroup.org/letter_avatar_proxy/v4/letter/h/e99b99/32.png) [@henrymateo0609](https://forum.hdfgroup.org/u/henrymateo0609)\
**Post date:** [May 15, 2023, 1:14pm UTC](https://forum.hdfgroup.org/t/symbolic-links-with-relative-path/9552/12 "2023-05-15T13:14:14Z")

</div>

The relative path for linking to a target dataset one level above the soft link would be “…/…/dset”.

---

<div class="post-metadata">

**Author:** ![gheber](https://forum.hdfgroup.org/user_avatar/forum.hdfgroup.org/gheber/32/1919_2.png) [@gheber](https://forum.hdfgroup.org/u/gheber)\
**Post date:** [May 17, 2023, 1:09am UTC](https://forum.hdfgroup.org/t/symbolic-links-with-relative-path/9552/13 "2023-05-17T01:09:00Z")

</div>

I see the use case, but `..` is a legitimate link name and the proposed _convention_ deviates from that interpretation, which makes it more problematic and inherently ambiguous. The symbolic resolver function can be implemented using a simple combination of `H5Lget_val`, `strncat`, and `realpath` (or Win32 `_fullpath`). Taking this beyond the symbolic level, and with an expectation of robustness, will easily balloon into a real monster: Most of the code will just be dealing w/ corner cases, and a maintenance nightmare.But maybe I’m too pessimistic…

G.
