(existingPath, newPath)
| 821 | } |
| 822 | |
| 823 | linkSync(existingPath, newPath) { |
| 824 | if (this.readonly) { |
| 825 | throw createEROFS('link', newPath); |
| 826 | } |
| 827 | |
| 828 | const normalizedExisting = this.#normalizePath(existingPath); |
| 829 | const normalizedNew = this.#normalizePath(newPath); |
| 830 | |
| 831 | const entry = this.#getEntry(normalizedExisting, 'link', true); |
| 832 | if (!entry.isFile()) { |
| 833 | // Hard links to directories are not supported |
| 834 | throw createEINVAL('link', existingPath); |
| 835 | } |
| 836 | |
| 837 | // Check if new path already exists |
| 838 | const existing = this.#lookupEntry(normalizedNew, false); |
| 839 | if (existing.entry) { |
| 840 | throw createEEXIST('link', newPath); |
| 841 | } |
| 842 | |
| 843 | const parent = this.#ensureParent(normalizedNew, false, 'link'); |
| 844 | const name = pathPosix.basename(normalizedNew); |
| 845 | // Hard link: same entry object referenced by both names |
| 846 | parent.children.set(name, entry); |
| 847 | entry.nlink++; |
| 848 | const now = DateNow(); |
| 849 | parent.mtime = now; |
| 850 | parent.ctime = now; |
| 851 | } |
| 852 | |
| 853 | async link(existingPath, newPath) { |
| 854 | this.linkSync(existingPath, newPath); |
no test coverage detected