121 });
122}
123
124export namespace win32 {125126 /**127 * Check if the passed files are open by any other process.128 *129 * @param absPaths Absolute paths of files to check.130 * @param relPaths Relative paths of files to check.131 * @throws Throws an AggregateError with a description of the effected files.132 */133 export function checkWriteAccess(ioContextClass: typeof IoContext, absPaths: string[]): Promise<void> {134 const winAccess = ioContextClass.calculateAndGetWinAccessPath();135136 return new Promise<void>((resolve, reject) => {137 let std = '';138139 let paths = '';140 for (const absPath of absPaths) {141 // the stdin of win-access.exe accepts utf-16 little endian142 paths += `${absPath}\n`;143 }144145 const pathsArray = strEncodeUTF16(paths);146 const p0 = spawn(winAccess);147148 p0.stdin.write(pathsArray);149 p0.stdin.end();150 p0.stdout.on('data', (data) => {151 std += data.toString();152 });153154 p0.on('exit', (code) => {155 if (code === 0) {156 resolve();157 } else {158 try {159 // eslint-disable-next-line no-unreachable-loop160 for (const d of JSON.parse(std)) {161 let msg = `Your files are accessed by ${d.strAppName}.`;162 if (d.strAppName !== 'Windows Explorer') {163 msg += ' Please close the application and retry.';164 }165 return reject(new Error(msg));166 }167 } catch (error) {168 // throw an error if something happened during JSON.parse169 reject(new Error(error));170 }171 }172 });173 });174 }175}176
177export namespace unix {
178
174 }
175}
176
177export namespace unix {178179/**180 * Possible file lock types on a given file. This are the extracted181 * information from a `man lsof` converted into an enum.182 */183export enum LOCKTYPE {184 NFS_LOCK = 'N', // for a Solaris NFS lock of unknown type185 READ_LOCK_FILE_PART = 'r', // for read lock on part of the file186 READ_LOCK_FILE = 'R', // for a read lock on the entire file187 WRITE_LOCK_FILE_PART = 'w', // for a write lock on part of the file188 WRITE_LOCK_FILE = 'W', // for a write lock on the entire file189 READ_WRITE_LOCK_FILE = 'u', // for a read and write lock of any length190 UNKNOWN = 'X' // An unknown lock type (U, x or X)191}192193export class FileHandle {194 /** PID of process which acquired the file handle */195 pid: string;196197 processname: string;198199 /** File access information with file lock info */200 lockType: LOCKTYPE;201202 /** Documents filepath */203 filepath: string;204}205206export function whichFilesInDirAreOpen(dirpath: string): Promise<Map<string, FileHandle[]>> {207 try {208 return new Promise<Map<string, FileHandle[]>>((resolve, reject) => {209 const p0 = cp.spawn('lsof', ['-X', '-F', 'pcan', '+D', dirpath]);210 const p = new Map<string, FileHandle[]>();211212 let stdout = '';213 p0.stdout.on('data', (data) => {214 stdout += data.toString();215 });216217 function parseStdout(stdout: string) {218 let lsofEntry: FileHandle = new FileHandle();219 for (const pline of stdout.split(/\n/)) {220 if (pline.startsWith('p')) { // PID of process which acquired the file handle221 // first item, therefore it creates the file handle222 lsofEntry = new FileHandle();223 lsofEntry.pid = pline.substr(1, pline.length - 1);224 } else if (pline.startsWith('c')) { // Name of process which acquired the file handle225 lsofEntry.processname = pline.substr(1, pline.length - 1);226 } else if (pline.startsWith('a')) { // File access information with file lock info227 // See `LOCKTYPE` for more information228 if (pline.includes('N')) {229 lsofEntry.lockType = LOCKTYPE.NFS_LOCK;230 } else if (pline.includes('r')) {231 lsofEntry.lockType = LOCKTYPE.READ_LOCK_FILE_PART;232 } else if (pline.includes('R')) {233 lsofEntry.lockType = LOCKTYPE.READ_LOCK_FILE;234 } else if (pline.includes('w')) {235 lsofEntry.lockType = LOCKTYPE.WRITE_LOCK_FILE_PART;236 } else if (pline.includes('W')) {237 lsofEntry.lockType = LOCKTYPE.WRITE_LOCK_FILE;238 } else if (pline.includes('u')) {239 lsofEntry.lockType = LOCKTYPE.READ_WRITE_LOCK_FILE;240 } else {241 lsofEntry.lockType = LOCKTYPE.UNKNOWN;242 }243 } else if (pline.startsWith('n')) { // Documents filepath244 const absPath = pline.substr(1, pline.length - 1);245 if (absPath.startsWith(dirpath)) {246 const relPath = relative(dirpath, pline.substr(1, pline.length - 1));247 const q = p.get(relPath);248 if (q) {249 // if there was an entry before, add the new entry to the array in the map250 q.push(lsofEntry);251 } else {252 // ..otherwise add a new list with the lsofEntry as the first element253 p.set(relPath, [lsofEntry]);254 }255 lsofEntry = new FileHandle();256 } else {257 console.log(`lsof reported unknown path: ${absPath}`);258 }259 }260 }261 }262263 p0.on('exit', (code) => {264 if (code === 1) { // lsof returns 1265 parseStdout(stdout);266 resolve(p);267 } else {268 reject(code);269 }270 });271 });272 } catch (error) {273 console.log(error);274 return Promise.resolve(new Map());275 }276}277278}279
280function getFilesystem(drive: any, mountpoint: string): Promise<FILESYSTEM> {
281 try {
Custom TypeScript modules (module foo {}
) and namespaces (namespace foo {}
) are considered outdated ways to organize TypeScript code. ES2015 module syntax is now preferred (import/export
).
This rule still allows the use of TypeScript module declarations to describe external APIs (declare module 'foo' {}
).
module foo {}
namespace foo {}
declare module foo {}
declare namespace foo {}
declare module 'foo' {}