MCPcopy Create free account
hub / github.com/coreutils/coreutils / force_linkat

Function force_linkat

src/force-link.c:94–126  ·  view source on GitHub ↗

Hard-link directory SRCDIR's file SRCNAME to directory DSTDIR's file DSTNAME, using linkat-style FLAGS to control the linking. If FORCE and DSTNAME already exists, replace it atomically. If LINKAT_ERRNO is 0, the hard link is already done; if positive, the hard link was tried and failed with errno == LINKAT_ERRNO. Return -1 if successful and DSTNAME already existed, 0 if success

Source from the content-addressed store, hash-verified

92 0 if successful and DSTNAME did not already exist, and
93 a positive errno value on failure. */
94extern int
95force_linkat (int srcdir, char const *srcname,
96 int dstdir, char const *dstname, int flags, bool force,
97 int linkat_errno)
98{
99 if (linkat_errno < 0)
100 linkat_errno = (linkat (srcdir, srcname, dstdir, dstname, flags) == 0
101 ? 0 : errno);
102 if (!force || linkat_errno != EEXIST)
103 return linkat_errno;
104
105 char buf[smallsize];
106 char *dsttmp = samedir_template (dstname, buf);
107 if (! dsttmp)
108 return errno;
109 struct link_arg arg = { srcdir, srcname, dstdir, flags };
110 int err;
111
112 if (try_tempname_len (dsttmp, 0, &arg, try_link, x_suffix_len) != 0)
113 err = errno;
114 else
115 {
116 err = renameat (dstdir, dsttmp, dstdir, dstname) == 0 ? -1 : errno;
117 /* Unlink DSTTMP even if renameat succeeded, in case DSTTMP
118 and DSTNAME were already the same hard link and renameat
119 was a no-op. */
120 unlinkat (dstdir, dsttmp, 0);
121 }
122
123 if (dsttmp != buf)
124 free (dsttmp);
125 return err;
126}
127
128
129/* Auxiliaries for force_symlinkat. */

Callers 2

create_hard_linkFunction · 0.85
do_linkFunction · 0.85

Calls 1

samedir_templateFunction · 0.85

Tested by

no test coverage detected