11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ci// This file is a modified version of the fs-extra's copySync method.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ciconst { areIdentical, isSrcSubdir } = require('internal/fs/cp/cp');
61cb0ef41Sopenharmony_ciconst { codes } = require('internal/errors');
71cb0ef41Sopenharmony_ciconst {
81cb0ef41Sopenharmony_ci  os: {
91cb0ef41Sopenharmony_ci    errno: {
101cb0ef41Sopenharmony_ci      EEXIST,
111cb0ef41Sopenharmony_ci      EISDIR,
121cb0ef41Sopenharmony_ci      EINVAL,
131cb0ef41Sopenharmony_ci      ENOTDIR,
141cb0ef41Sopenharmony_ci    },
151cb0ef41Sopenharmony_ci  },
161cb0ef41Sopenharmony_ci} = internalBinding('constants');
171cb0ef41Sopenharmony_ciconst {
181cb0ef41Sopenharmony_ci  ERR_FS_CP_DIR_TO_NON_DIR,
191cb0ef41Sopenharmony_ci  ERR_FS_CP_EEXIST,
201cb0ef41Sopenharmony_ci  ERR_FS_CP_EINVAL,
211cb0ef41Sopenharmony_ci  ERR_FS_CP_FIFO_PIPE,
221cb0ef41Sopenharmony_ci  ERR_FS_CP_NON_DIR_TO_DIR,
231cb0ef41Sopenharmony_ci  ERR_FS_CP_SOCKET,
241cb0ef41Sopenharmony_ci  ERR_FS_CP_SYMLINK_TO_SUBDIRECTORY,
251cb0ef41Sopenharmony_ci  ERR_FS_CP_UNKNOWN,
261cb0ef41Sopenharmony_ci  ERR_FS_EISDIR,
271cb0ef41Sopenharmony_ci  ERR_INVALID_RETURN_VALUE,
281cb0ef41Sopenharmony_ci} = codes;
291cb0ef41Sopenharmony_ciconst {
301cb0ef41Sopenharmony_ci  chmodSync,
311cb0ef41Sopenharmony_ci  copyFileSync,
321cb0ef41Sopenharmony_ci  existsSync,
331cb0ef41Sopenharmony_ci  lstatSync,
341cb0ef41Sopenharmony_ci  mkdirSync,
351cb0ef41Sopenharmony_ci  opendirSync,
361cb0ef41Sopenharmony_ci  readlinkSync,
371cb0ef41Sopenharmony_ci  statSync,
381cb0ef41Sopenharmony_ci  symlinkSync,
391cb0ef41Sopenharmony_ci  unlinkSync,
401cb0ef41Sopenharmony_ci  utimesSync,
411cb0ef41Sopenharmony_ci} = require('fs');
421cb0ef41Sopenharmony_ciconst {
431cb0ef41Sopenharmony_ci  dirname,
441cb0ef41Sopenharmony_ci  isAbsolute,
451cb0ef41Sopenharmony_ci  join,
461cb0ef41Sopenharmony_ci  parse,
471cb0ef41Sopenharmony_ci  resolve,
481cb0ef41Sopenharmony_ci} = require('path');
491cb0ef41Sopenharmony_ciconst { isPromise } = require('util/types');
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_cifunction cpSyncFn(src, dest, opts) {
521cb0ef41Sopenharmony_ci  // Warn about using preserveTimestamps on 32-bit node
531cb0ef41Sopenharmony_ci  if (opts.preserveTimestamps && process.arch === 'ia32') {
541cb0ef41Sopenharmony_ci    const warning = 'Using the preserveTimestamps option in 32-bit ' +
551cb0ef41Sopenharmony_ci      'node is not recommended';
561cb0ef41Sopenharmony_ci    process.emitWarning(warning, 'TimestampPrecisionWarning');
571cb0ef41Sopenharmony_ci  }
581cb0ef41Sopenharmony_ci  const { srcStat, destStat, skipped } = checkPathsSync(src, dest, opts);
591cb0ef41Sopenharmony_ci  if (skipped) return;
601cb0ef41Sopenharmony_ci  checkParentPathsSync(src, srcStat, dest);
611cb0ef41Sopenharmony_ci  return checkParentDir(destStat, src, dest, opts);
621cb0ef41Sopenharmony_ci}
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_cifunction checkPathsSync(src, dest, opts) {
651cb0ef41Sopenharmony_ci  if (opts.filter) {
661cb0ef41Sopenharmony_ci    const shouldCopy = opts.filter(src, dest);
671cb0ef41Sopenharmony_ci    if (isPromise(shouldCopy)) {
681cb0ef41Sopenharmony_ci      throw new ERR_INVALID_RETURN_VALUE('boolean', 'filter', shouldCopy);
691cb0ef41Sopenharmony_ci    }
701cb0ef41Sopenharmony_ci    if (!shouldCopy) return { __proto__: null, skipped: true };
711cb0ef41Sopenharmony_ci  }
721cb0ef41Sopenharmony_ci  const { srcStat, destStat } = getStatsSync(src, dest, opts);
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci  if (destStat) {
751cb0ef41Sopenharmony_ci    if (areIdentical(srcStat, destStat)) {
761cb0ef41Sopenharmony_ci      throw new ERR_FS_CP_EINVAL({
771cb0ef41Sopenharmony_ci        message: 'src and dest cannot be the same',
781cb0ef41Sopenharmony_ci        path: dest,
791cb0ef41Sopenharmony_ci        syscall: 'cp',
801cb0ef41Sopenharmony_ci        errno: EINVAL,
811cb0ef41Sopenharmony_ci        code: 'EINVAL',
821cb0ef41Sopenharmony_ci      });
831cb0ef41Sopenharmony_ci    }
841cb0ef41Sopenharmony_ci    if (srcStat.isDirectory() && !destStat.isDirectory()) {
851cb0ef41Sopenharmony_ci      throw new ERR_FS_CP_DIR_TO_NON_DIR({
861cb0ef41Sopenharmony_ci        message: `cannot overwrite directory ${src} ` +
871cb0ef41Sopenharmony_ci          `with non-directory ${dest}`,
881cb0ef41Sopenharmony_ci        path: dest,
891cb0ef41Sopenharmony_ci        syscall: 'cp',
901cb0ef41Sopenharmony_ci        errno: EISDIR,
911cb0ef41Sopenharmony_ci        code: 'EISDIR',
921cb0ef41Sopenharmony_ci      });
931cb0ef41Sopenharmony_ci    }
941cb0ef41Sopenharmony_ci    if (!srcStat.isDirectory() && destStat.isDirectory()) {
951cb0ef41Sopenharmony_ci      throw new ERR_FS_CP_NON_DIR_TO_DIR({
961cb0ef41Sopenharmony_ci        message: `cannot overwrite non-directory ${src} ` +
971cb0ef41Sopenharmony_ci          `with directory ${dest}`,
981cb0ef41Sopenharmony_ci        path: dest,
991cb0ef41Sopenharmony_ci        syscall: 'cp',
1001cb0ef41Sopenharmony_ci        errno: ENOTDIR,
1011cb0ef41Sopenharmony_ci        code: 'ENOTDIR',
1021cb0ef41Sopenharmony_ci      });
1031cb0ef41Sopenharmony_ci    }
1041cb0ef41Sopenharmony_ci  }
1051cb0ef41Sopenharmony_ci
1061cb0ef41Sopenharmony_ci  if (srcStat.isDirectory() && isSrcSubdir(src, dest)) {
1071cb0ef41Sopenharmony_ci    throw new ERR_FS_CP_EINVAL({
1081cb0ef41Sopenharmony_ci      message: `cannot copy ${src} to a subdirectory of self ${dest}`,
1091cb0ef41Sopenharmony_ci      path: dest,
1101cb0ef41Sopenharmony_ci      syscall: 'cp',
1111cb0ef41Sopenharmony_ci      errno: EINVAL,
1121cb0ef41Sopenharmony_ci      code: 'EINVAL',
1131cb0ef41Sopenharmony_ci    });
1141cb0ef41Sopenharmony_ci  }
1151cb0ef41Sopenharmony_ci  return { __proto__: null, srcStat, destStat, skipped: false };
1161cb0ef41Sopenharmony_ci}
1171cb0ef41Sopenharmony_ci
1181cb0ef41Sopenharmony_cifunction getStatsSync(src, dest, opts) {
1191cb0ef41Sopenharmony_ci  let destStat;
1201cb0ef41Sopenharmony_ci  const statFunc = opts.dereference ?
1211cb0ef41Sopenharmony_ci    (file) => statSync(file, { bigint: true }) :
1221cb0ef41Sopenharmony_ci    (file) => lstatSync(file, { bigint: true });
1231cb0ef41Sopenharmony_ci  const srcStat = statFunc(src);
1241cb0ef41Sopenharmony_ci  try {
1251cb0ef41Sopenharmony_ci    destStat = statFunc(dest);
1261cb0ef41Sopenharmony_ci  } catch (err) {
1271cb0ef41Sopenharmony_ci    if (err.code === 'ENOENT') return { srcStat, destStat: null };
1281cb0ef41Sopenharmony_ci    throw err;
1291cb0ef41Sopenharmony_ci  }
1301cb0ef41Sopenharmony_ci  return { srcStat, destStat };
1311cb0ef41Sopenharmony_ci}
1321cb0ef41Sopenharmony_ci
1331cb0ef41Sopenharmony_cifunction checkParentPathsSync(src, srcStat, dest) {
1341cb0ef41Sopenharmony_ci  const srcParent = resolve(dirname(src));
1351cb0ef41Sopenharmony_ci  const destParent = resolve(dirname(dest));
1361cb0ef41Sopenharmony_ci  if (destParent === srcParent || destParent === parse(destParent).root) return;
1371cb0ef41Sopenharmony_ci  let destStat;
1381cb0ef41Sopenharmony_ci  try {
1391cb0ef41Sopenharmony_ci    destStat = statSync(destParent, { bigint: true });
1401cb0ef41Sopenharmony_ci  } catch (err) {
1411cb0ef41Sopenharmony_ci    if (err.code === 'ENOENT') return;
1421cb0ef41Sopenharmony_ci    throw err;
1431cb0ef41Sopenharmony_ci  }
1441cb0ef41Sopenharmony_ci  if (areIdentical(srcStat, destStat)) {
1451cb0ef41Sopenharmony_ci    throw new ERR_FS_CP_EINVAL({
1461cb0ef41Sopenharmony_ci      message: `cannot copy ${src} to a subdirectory of self ${dest}`,
1471cb0ef41Sopenharmony_ci      path: dest,
1481cb0ef41Sopenharmony_ci      syscall: 'cp',
1491cb0ef41Sopenharmony_ci      errno: EINVAL,
1501cb0ef41Sopenharmony_ci      code: 'EINVAL',
1511cb0ef41Sopenharmony_ci    });
1521cb0ef41Sopenharmony_ci  }
1531cb0ef41Sopenharmony_ci  return checkParentPathsSync(src, srcStat, destParent);
1541cb0ef41Sopenharmony_ci}
1551cb0ef41Sopenharmony_ci
1561cb0ef41Sopenharmony_cifunction checkParentDir(destStat, src, dest, opts) {
1571cb0ef41Sopenharmony_ci  const destParent = dirname(dest);
1581cb0ef41Sopenharmony_ci  if (!existsSync(destParent)) mkdirSync(destParent, { recursive: true });
1591cb0ef41Sopenharmony_ci  return getStats(destStat, src, dest, opts);
1601cb0ef41Sopenharmony_ci}
1611cb0ef41Sopenharmony_ci
1621cb0ef41Sopenharmony_cifunction getStats(destStat, src, dest, opts) {
1631cb0ef41Sopenharmony_ci  const statSyncFn = opts.dereference ? statSync : lstatSync;
1641cb0ef41Sopenharmony_ci  const srcStat = statSyncFn(src);
1651cb0ef41Sopenharmony_ci
1661cb0ef41Sopenharmony_ci  if (srcStat.isDirectory() && opts.recursive) {
1671cb0ef41Sopenharmony_ci    return onDir(srcStat, destStat, src, dest, opts);
1681cb0ef41Sopenharmony_ci  } else if (srcStat.isDirectory()) {
1691cb0ef41Sopenharmony_ci    throw new ERR_FS_EISDIR({
1701cb0ef41Sopenharmony_ci      message: `${src} is a directory (not copied)`,
1711cb0ef41Sopenharmony_ci      path: src,
1721cb0ef41Sopenharmony_ci      syscall: 'cp',
1731cb0ef41Sopenharmony_ci      errno: EINVAL,
1741cb0ef41Sopenharmony_ci      code: 'EISDIR',
1751cb0ef41Sopenharmony_ci    });
1761cb0ef41Sopenharmony_ci  } else if (srcStat.isFile() ||
1771cb0ef41Sopenharmony_ci           srcStat.isCharacterDevice() ||
1781cb0ef41Sopenharmony_ci           srcStat.isBlockDevice()) {
1791cb0ef41Sopenharmony_ci    return onFile(srcStat, destStat, src, dest, opts);
1801cb0ef41Sopenharmony_ci  } else if (srcStat.isSymbolicLink()) {
1811cb0ef41Sopenharmony_ci    return onLink(destStat, src, dest, opts);
1821cb0ef41Sopenharmony_ci  } else if (srcStat.isSocket()) {
1831cb0ef41Sopenharmony_ci    throw new ERR_FS_CP_SOCKET({
1841cb0ef41Sopenharmony_ci      message: `cannot copy a socket file: ${dest}`,
1851cb0ef41Sopenharmony_ci      path: dest,
1861cb0ef41Sopenharmony_ci      syscall: 'cp',
1871cb0ef41Sopenharmony_ci      errno: EINVAL,
1881cb0ef41Sopenharmony_ci      code: 'EINVAL',
1891cb0ef41Sopenharmony_ci    });
1901cb0ef41Sopenharmony_ci  } else if (srcStat.isFIFO()) {
1911cb0ef41Sopenharmony_ci    throw new ERR_FS_CP_FIFO_PIPE({
1921cb0ef41Sopenharmony_ci      message: `cannot copy a FIFO pipe: ${dest}`,
1931cb0ef41Sopenharmony_ci      path: dest,
1941cb0ef41Sopenharmony_ci      syscall: 'cp',
1951cb0ef41Sopenharmony_ci      errno: EINVAL,
1961cb0ef41Sopenharmony_ci      code: 'EINVAL',
1971cb0ef41Sopenharmony_ci    });
1981cb0ef41Sopenharmony_ci  }
1991cb0ef41Sopenharmony_ci  throw new ERR_FS_CP_UNKNOWN({
2001cb0ef41Sopenharmony_ci    message: `cannot copy an unknown file type: ${dest}`,
2011cb0ef41Sopenharmony_ci    path: dest,
2021cb0ef41Sopenharmony_ci    syscall: 'cp',
2031cb0ef41Sopenharmony_ci    errno: EINVAL,
2041cb0ef41Sopenharmony_ci    code: 'EINVAL',
2051cb0ef41Sopenharmony_ci  });
2061cb0ef41Sopenharmony_ci}
2071cb0ef41Sopenharmony_ci
2081cb0ef41Sopenharmony_cifunction onFile(srcStat, destStat, src, dest, opts) {
2091cb0ef41Sopenharmony_ci  if (!destStat) return copyFile(srcStat, src, dest, opts);
2101cb0ef41Sopenharmony_ci  return mayCopyFile(srcStat, src, dest, opts);
2111cb0ef41Sopenharmony_ci}
2121cb0ef41Sopenharmony_ci
2131cb0ef41Sopenharmony_cifunction mayCopyFile(srcStat, src, dest, opts) {
2141cb0ef41Sopenharmony_ci  if (opts.force) {
2151cb0ef41Sopenharmony_ci    unlinkSync(dest);
2161cb0ef41Sopenharmony_ci    return copyFile(srcStat, src, dest, opts);
2171cb0ef41Sopenharmony_ci  } else if (opts.errorOnExist) {
2181cb0ef41Sopenharmony_ci    throw new ERR_FS_CP_EEXIST({
2191cb0ef41Sopenharmony_ci      message: `${dest} already exists`,
2201cb0ef41Sopenharmony_ci      path: dest,
2211cb0ef41Sopenharmony_ci      syscall: 'cp',
2221cb0ef41Sopenharmony_ci      errno: EEXIST,
2231cb0ef41Sopenharmony_ci      code: 'EEXIST',
2241cb0ef41Sopenharmony_ci    });
2251cb0ef41Sopenharmony_ci  }
2261cb0ef41Sopenharmony_ci}
2271cb0ef41Sopenharmony_ci
2281cb0ef41Sopenharmony_cifunction copyFile(srcStat, src, dest, opts) {
2291cb0ef41Sopenharmony_ci  copyFileSync(src, dest, opts.mode);
2301cb0ef41Sopenharmony_ci  if (opts.preserveTimestamps) handleTimestamps(srcStat.mode, src, dest);
2311cb0ef41Sopenharmony_ci  return setDestMode(dest, srcStat.mode);
2321cb0ef41Sopenharmony_ci}
2331cb0ef41Sopenharmony_ci
2341cb0ef41Sopenharmony_cifunction handleTimestamps(srcMode, src, dest) {
2351cb0ef41Sopenharmony_ci  // Make sure the file is writable before setting the timestamp
2361cb0ef41Sopenharmony_ci  // otherwise open fails with EPERM when invoked with 'r+'
2371cb0ef41Sopenharmony_ci  // (through utimes call)
2381cb0ef41Sopenharmony_ci  if (fileIsNotWritable(srcMode)) makeFileWritable(dest, srcMode);
2391cb0ef41Sopenharmony_ci  return setDestTimestamps(src, dest);
2401cb0ef41Sopenharmony_ci}
2411cb0ef41Sopenharmony_ci
2421cb0ef41Sopenharmony_cifunction fileIsNotWritable(srcMode) {
2431cb0ef41Sopenharmony_ci  return (srcMode & 0o200) === 0;
2441cb0ef41Sopenharmony_ci}
2451cb0ef41Sopenharmony_ci
2461cb0ef41Sopenharmony_cifunction makeFileWritable(dest, srcMode) {
2471cb0ef41Sopenharmony_ci  return setDestMode(dest, srcMode | 0o200);
2481cb0ef41Sopenharmony_ci}
2491cb0ef41Sopenharmony_ci
2501cb0ef41Sopenharmony_cifunction setDestMode(dest, srcMode) {
2511cb0ef41Sopenharmony_ci  return chmodSync(dest, srcMode);
2521cb0ef41Sopenharmony_ci}
2531cb0ef41Sopenharmony_ci
2541cb0ef41Sopenharmony_cifunction setDestTimestamps(src, dest) {
2551cb0ef41Sopenharmony_ci  // The initial srcStat.atime cannot be trusted
2561cb0ef41Sopenharmony_ci  // because it is modified by the read(2) system call
2571cb0ef41Sopenharmony_ci  // (See https://nodejs.org/api/fs.html#fs_stat_time_values)
2581cb0ef41Sopenharmony_ci  const updatedSrcStat = statSync(src);
2591cb0ef41Sopenharmony_ci  return utimesSync(dest, updatedSrcStat.atime, updatedSrcStat.mtime);
2601cb0ef41Sopenharmony_ci}
2611cb0ef41Sopenharmony_ci
2621cb0ef41Sopenharmony_cifunction onDir(srcStat, destStat, src, dest, opts) {
2631cb0ef41Sopenharmony_ci  if (!destStat) return mkDirAndCopy(srcStat.mode, src, dest, opts);
2641cb0ef41Sopenharmony_ci  return copyDir(src, dest, opts);
2651cb0ef41Sopenharmony_ci}
2661cb0ef41Sopenharmony_ci
2671cb0ef41Sopenharmony_cifunction mkDirAndCopy(srcMode, src, dest, opts) {
2681cb0ef41Sopenharmony_ci  mkdirSync(dest);
2691cb0ef41Sopenharmony_ci  copyDir(src, dest, opts);
2701cb0ef41Sopenharmony_ci  return setDestMode(dest, srcMode);
2711cb0ef41Sopenharmony_ci}
2721cb0ef41Sopenharmony_ci
2731cb0ef41Sopenharmony_cifunction copyDir(src, dest, opts) {
2741cb0ef41Sopenharmony_ci  const dir = opendirSync(src);
2751cb0ef41Sopenharmony_ci
2761cb0ef41Sopenharmony_ci  try {
2771cb0ef41Sopenharmony_ci    let dirent;
2781cb0ef41Sopenharmony_ci
2791cb0ef41Sopenharmony_ci    while ((dirent = dir.readSync()) !== null) {
2801cb0ef41Sopenharmony_ci      const { name } = dirent;
2811cb0ef41Sopenharmony_ci      const srcItem = join(src, name);
2821cb0ef41Sopenharmony_ci      const destItem = join(dest, name);
2831cb0ef41Sopenharmony_ci      const { destStat, skipped } = checkPathsSync(srcItem, destItem, opts);
2841cb0ef41Sopenharmony_ci      if (!skipped) getStats(destStat, srcItem, destItem, opts);
2851cb0ef41Sopenharmony_ci    }
2861cb0ef41Sopenharmony_ci  } finally {
2871cb0ef41Sopenharmony_ci    dir.closeSync();
2881cb0ef41Sopenharmony_ci  }
2891cb0ef41Sopenharmony_ci}
2901cb0ef41Sopenharmony_ci
2911cb0ef41Sopenharmony_cifunction onLink(destStat, src, dest, opts) {
2921cb0ef41Sopenharmony_ci  let resolvedSrc = readlinkSync(src);
2931cb0ef41Sopenharmony_ci  if (!opts.verbatimSymlinks && !isAbsolute(resolvedSrc)) {
2941cb0ef41Sopenharmony_ci    resolvedSrc = resolve(dirname(src), resolvedSrc);
2951cb0ef41Sopenharmony_ci  }
2961cb0ef41Sopenharmony_ci  if (!destStat) {
2971cb0ef41Sopenharmony_ci    return symlinkSync(resolvedSrc, dest);
2981cb0ef41Sopenharmony_ci  }
2991cb0ef41Sopenharmony_ci  let resolvedDest;
3001cb0ef41Sopenharmony_ci  try {
3011cb0ef41Sopenharmony_ci    resolvedDest = readlinkSync(dest);
3021cb0ef41Sopenharmony_ci  } catch (err) {
3031cb0ef41Sopenharmony_ci    // Dest exists and is a regular file or directory,
3041cb0ef41Sopenharmony_ci    // Windows may throw UNKNOWN error. If dest already exists,
3051cb0ef41Sopenharmony_ci    // fs throws error anyway, so no need to guard against it here.
3061cb0ef41Sopenharmony_ci    if (err.code === 'EINVAL' || err.code === 'UNKNOWN') {
3071cb0ef41Sopenharmony_ci      return symlinkSync(resolvedSrc, dest);
3081cb0ef41Sopenharmony_ci    }
3091cb0ef41Sopenharmony_ci    throw err;
3101cb0ef41Sopenharmony_ci  }
3111cb0ef41Sopenharmony_ci  if (!isAbsolute(resolvedDest)) {
3121cb0ef41Sopenharmony_ci    resolvedDest = resolve(dirname(dest), resolvedDest);
3131cb0ef41Sopenharmony_ci  }
3141cb0ef41Sopenharmony_ci  if (isSrcSubdir(resolvedSrc, resolvedDest)) {
3151cb0ef41Sopenharmony_ci    throw new ERR_FS_CP_EINVAL({
3161cb0ef41Sopenharmony_ci      message: `cannot copy ${resolvedSrc} to a subdirectory of self ` +
3171cb0ef41Sopenharmony_ci          `${resolvedDest}`,
3181cb0ef41Sopenharmony_ci      path: dest,
3191cb0ef41Sopenharmony_ci      syscall: 'cp',
3201cb0ef41Sopenharmony_ci      errno: EINVAL,
3211cb0ef41Sopenharmony_ci      code: 'EINVAL',
3221cb0ef41Sopenharmony_ci    });
3231cb0ef41Sopenharmony_ci  }
3241cb0ef41Sopenharmony_ci  // Prevent copy if src is a subdir of dest since unlinking
3251cb0ef41Sopenharmony_ci  // dest in this case would result in removing src contents
3261cb0ef41Sopenharmony_ci  // and therefore a broken symlink would be created.
3271cb0ef41Sopenharmony_ci  if (statSync(dest).isDirectory() && isSrcSubdir(resolvedDest, resolvedSrc)) {
3281cb0ef41Sopenharmony_ci    throw new ERR_FS_CP_SYMLINK_TO_SUBDIRECTORY({
3291cb0ef41Sopenharmony_ci      message: `cannot overwrite ${resolvedDest} with ${resolvedSrc}`,
3301cb0ef41Sopenharmony_ci      path: dest,
3311cb0ef41Sopenharmony_ci      syscall: 'cp',
3321cb0ef41Sopenharmony_ci      errno: EINVAL,
3331cb0ef41Sopenharmony_ci      code: 'EINVAL',
3341cb0ef41Sopenharmony_ci    });
3351cb0ef41Sopenharmony_ci  }
3361cb0ef41Sopenharmony_ci  return copyLink(resolvedSrc, dest);
3371cb0ef41Sopenharmony_ci}
3381cb0ef41Sopenharmony_ci
3391cb0ef41Sopenharmony_cifunction copyLink(resolvedSrc, dest) {
3401cb0ef41Sopenharmony_ci  unlinkSync(dest);
3411cb0ef41Sopenharmony_ci  return symlinkSync(resolvedSrc, dest);
3421cb0ef41Sopenharmony_ci}
3431cb0ef41Sopenharmony_ci
3441cb0ef41Sopenharmony_cimodule.exports = { cpSyncFn };
345