_xstat(cmd, aPath, addListeners = true) {
    let listeners;
    return new Promise((resolve, reject) => {
      const cb = (err, stats) => {
        if (err) {
          if (err.code === 2 || err.code === 4) {
            reject(this.fmtError(`No such file: ${aPath}`, '_xstat', errorCode.notexist));
          } else {
            reject(this.fmtError(`${err.message} ${aPath}`, '_xstat', err.code));
          }
        } else {
          const result = {
            mode: stats.mode,
            uid: stats.uid,
            gid: stats.gid,
            size: stats.size,
            accessTime: stats.atime * 1000,
            modifyTime: stats.mtime * 1000,
            isDirectory: stats.isDirectory(),
            isFile: stats.isFile(),
            isBlockDevice: stats.isBlockDevice(),
            isCharacterDevice: stats.isCharacterDevice(),
            isSymbolicLink: stats.isSymbolicLink(),
            isFIFO: stats.isFIFO(),
            isSocket: stats.isSocket(),
          };
          resolve(result);
        }
      };
      if (addListeners) {
        listeners = addTempListeners(this, '_xstat', reject);
      }
      if (cmd === 'stat') {
        this.sftp.stat(aPath, cb);
      } else {
        this.sftp.lstat(aPath, cb);
      }
    }).finally(() => {
      if (addListeners) {
        removeTempListeners(this, listeners, '_xstat');
      }
    });
  }
Retrieves attributes for path using cmd, which is either
this.sftp.stat or this.sftp.lstat

@param {Function} cmd - either this.sftp.stat or this.sftp.lstat
@param {String} remotePath - a string containing the path to a file
@param {Boolean} addListeners - (Optional) if true add event listeners. Default true.
@return {Promise<Object>} stats - attributes info