| 157 | // checks the src and dest inodes. It starts from the deepest |
| 158 | // parent and stops once it reaches the src parent or the root path. |
| 159 | async function checkParentPaths(src, srcStat, dest) { |
| 160 | const srcParent = resolve(dirname(src)); |
| 161 | const destParent = resolve(dirname(dest)); |
| 162 | if (destParent === srcParent || destParent === parse(destParent).root) { |
| 163 | return; |
| 164 | } |
| 165 | let destStat; |
| 166 | try { |
| 167 | destStat = await stat(destParent, { bigint: true }); |
| 168 | } catch (err) { |
| 169 | if (err.code === 'ENOENT') return; |
| 170 | throw err; |
| 171 | } |
| 172 | if (areIdentical(srcStat, destStat)) { |
| 173 | throw new ERR_FS_CP_EINVAL({ |
| 174 | message: `cannot copy ${src} to a subdirectory of self ${dest}`, |
| 175 | path: dest, |
| 176 | syscall: 'cp', |
| 177 | errno: EINVAL, |
| 178 | code: 'EINVAL', |
| 179 | }); |
| 180 | } |
| 181 | return checkParentPaths(src, srcStat, destParent); |
| 182 | } |
| 183 | |
| 184 | const normalizePathToArray = (path) => |
| 185 | ArrayPrototypeFilter(StringPrototypeSplit(resolve(path), sep), Boolean); |