(destStat, src, dest, verbatimSymlinks)
| 187 | |
| 188 | // TODO(@anonrig): Move this function to C++. |
| 189 | function onLink(destStat, src, dest, verbatimSymlinks) { |
| 190 | let resolvedSrc = readlinkSync(src); |
| 191 | if (!verbatimSymlinks && !isAbsolute(resolvedSrc)) { |
| 192 | resolvedSrc = resolve(dirname(src), resolvedSrc); |
| 193 | } |
| 194 | if (!destStat) { |
| 195 | return symlinkSync(resolvedSrc, dest); |
| 196 | } |
| 197 | let resolvedDest; |
| 198 | try { |
| 199 | resolvedDest = readlinkSync(dest); |
| 200 | } catch (err) { |
| 201 | // Dest exists and is a regular file or directory, |
| 202 | // Windows may throw UNKNOWN error. If dest already exists, |
| 203 | // fs throws error anyway, so no need to guard against it here. |
| 204 | if (err.code === 'EINVAL' || err.code === 'UNKNOWN') { |
| 205 | return symlinkSync(resolvedSrc, dest); |
| 206 | } |
| 207 | throw err; |
| 208 | } |
| 209 | if (!isAbsolute(resolvedDest)) { |
| 210 | resolvedDest = resolve(dirname(dest), resolvedDest); |
| 211 | } |
| 212 | const srcIsDir = fsBinding.internalModuleStat(src) === 1; |
| 213 | |
| 214 | if (srcIsDir && isSrcSubdir(resolvedSrc, resolvedDest)) { |
| 215 | throw new ERR_FS_CP_EINVAL({ |
| 216 | message: `cannot copy ${resolvedSrc} to a subdirectory of self ` + |
| 217 | `${resolvedDest}`, |
| 218 | path: dest, |
| 219 | syscall: 'cp', |
| 220 | errno: EINVAL, |
| 221 | code: 'EINVAL', |
| 222 | }); |
| 223 | } |
| 224 | // Prevent copy if src is a subdir of dest since unlinking |
| 225 | // dest in this case would result in removing src contents |
| 226 | // and therefore a broken symlink would be created. |
| 227 | if (statSync(dest).isDirectory() && isSrcSubdir(resolvedDest, resolvedSrc)) { |
| 228 | throw new ERR_FS_CP_SYMLINK_TO_SUBDIRECTORY({ |
| 229 | message: `cannot overwrite ${resolvedDest} with ${resolvedSrc}`, |
| 230 | path: dest, |
| 231 | syscall: 'cp', |
| 232 | errno: EINVAL, |
| 233 | code: 'EINVAL', |
| 234 | }); |
| 235 | } |
| 236 | return copyLink(resolvedSrc, dest); |
| 237 | } |
| 238 | |
| 239 | function copyLink(resolvedSrc, dest) { |
| 240 | unlinkSync(dest); |
no test coverage detected