Skip to content

Commit

Permalink
linkat: implement wrapper
Browse files Browse the repository at this point in the history
I observe the following here in a qt5 build:

linkat(AT_FDCWD, "/proc/self/fd/4", AT_FDCWD, "/usr/...", AT_SYMLINK_FOLLOW) = 0

link("/proc/self/fd/4", "/usr/...") = -1 EXDEV (Invalid cross-device link)

So link and linkat behave differently these days.
This is annoying, but it also means we cannot implement linkat via link anymore.
  • Loading branch information
v4hn committed Sep 6, 2018
1 parent 6891944 commit 6300f8c
Showing 1 changed file with 17 additions and 33 deletions.
50 changes: 17 additions & 33 deletions installwatch.c
Original file line number Diff line number Diff line change
Expand Up @@ -4247,62 +4247,46 @@ int __fxstatat64 (int version, int dirfd, const char *path, struct stat64 *s, in

int linkat (int olddirfd, const char *oldpath,
int newdirfd, const char *newpath, int flags) {

int result;
instw_t instwold;
instw_t instwnew;

/* If all we are doing is normal open, forgo refcounting, etc. */
if( (olddirfd == AT_FDCWD || *oldpath == '/') &&
(newdirfd == AT_FDCWD || *newpath == '/') )
{
#if DEBUG
debug(2, "linkat(%d, %s, %d, %s, 0%o)\n", olddirfd, oldpath, newdirfd, newpath, flags );
#endif

return link(oldpath, newpath);

/*** FIXME: If we have AT_SYMLINK_NOFOLLOW we need to dereference the links
if ( flags & AT_SYMLINK_NOFOLLOW ) {
return link(oldpath, newpath);
}
else {
return link(oldpath, newpath);
}
***************************************************************** FIXME */

}

REFCOUNT;

if (!libc_handle)
initialize();

#if DEBUG
debug(2, "linkat(%d, %s, %d, %s, 0%o)\n", olddirfd, oldpath, newdirfd, newpath, flags );
#endif

/* We were asked to work in "real" mode */
if(!(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP))
return true_link(oldpath, newpath);
return true_linkat(olddirfd, oldpath, newdirfd, newpath, flags);

instw_new(&instwold);
instw_new(&instwnew);
instw_setpathrel(&instwold,olddirfd,oldpath);
instw_setpathrel(&instwnew,newdirfd,newpath);

#if DEBUG
instw_print(&instwold);
instw_print(&instwnew);
#endif

result=link(instwold.path, instwnew.path);


backup(instwold.truepath);
instw_apply(&instwold);
instw_apply(&instwnew);

result=true_linkat(olddirfd, oldpath, newdirfd, newpath, flags);
logg("%d\tlinkat\t%s\t%s\t#%s\n",result,
instwold.reslvpath,instwnew.reslvpath,error(result));

instw_delete(&instwold);
instw_delete(&instwnew);

return result;
}

Expand Down

0 comments on commit 6300f8c

Please sign in to comment.