views:

147

answers:

3

Normally to change a symlink target one will first unlink the file and then re-creating the symlink with the new target path. However it will be assigned a new inode number.

Maybe there is a private Mac api with an update_target_for_symlink() function, so the inode can stay the same?

In case you wonder what I need it for.. a file manager. I doubt that this is possible at all. Anyways thats what makes it interesting.

+4  A: 

It looks a lot like this isn't possible at all.

bukzor
yeah, that is exactly the problem :-)
neoneye
+2  A: 

A link is an additional name associated with the inode. So there is no possibility to retarget a link since the link is not a unique object targeting a file. It is more a secondary name of a file.

Thats why you have to unlink it first (delete the name associated with the file) and then create a new link (add a additional name) to the new file.

The Inode of the link does not belong to the link, it belongs to the file. A file consists of list of names("links"), an identifier (inode) and a bunch of data blocks containing the file contents.

A symlink should be possible to rename, cause it only refers to the text name of a file.

From manual: There are nine system calls that do not follow links, and which operate on the symbolic link itself. They are: lchflags(2), lchmod(2), lchown(2), lstat(2), lutimes(2), readlink(2), rename(2), rmdir(2), and unlink(2).

UnixShadow
The first part is true for hardlinks, but is more or less irrelevant as the OP is asking about symlink.
BCS
+2  A: 

Upon looking closer, ln -sf seems to do what you want.

The first column is the inode number. Note it doesn't change:

$ ln -s foo bar
$ ls -li bar
    16503 lrwxrwxrwx 1 golemon golemon 3 2010-08-21 12:29 bar -> foo
$ ln -sf buz bar
$ ls -li bar
    16503 lrwxrwxrwx 1 golemon golemon 3 2010-08-21 12:29 bar -> buz

It looks like ln-sf uses simply unlink() and symlink() to accomplish this:

$ strace ln -sf quux bar
    <snip>
    symlink("quux", "bar")                  = -1 EEXIST (File exists)
    unlink("bar")                           = 0
    symlink("quux", "bar")                  = 0

$ ls -li bar
    16503 lrwxrwxrwx 1 golemon golemon 4 2010-08-21 12:31 bar -> quux
bukzor
I feel like I'm missing something because @neoneye sounds like he already tried this, and it seems to completely contradict what @UnixShadow said.
bukzor
I see you get the same inode. This is really interesting. However I get different inodes when I try the same. I guess you are not on Mac. What platform are you on?
neoneye
Does it work if you do other ops in between?
BCS
@neoneye: This is linux. I had hoped it was similar ..
bukzor