11cb0ef41Sopenharmony_ci// Copyright Joyent, Inc. and other Node contributors.
21cb0ef41Sopenharmony_ci//
31cb0ef41Sopenharmony_ci// Permission is hereby granted, free of charge, to any person obtaining a
41cb0ef41Sopenharmony_ci// copy of this software and associated documentation files (the
51cb0ef41Sopenharmony_ci// "Software"), to deal in the Software without restriction, including
61cb0ef41Sopenharmony_ci// without limitation the rights to use, copy, modify, merge, publish,
71cb0ef41Sopenharmony_ci// distribute, sublicense, and/or sell copies of the Software, and to permit
81cb0ef41Sopenharmony_ci// persons to whom the Software is furnished to do so, subject to the
91cb0ef41Sopenharmony_ci// following conditions:
101cb0ef41Sopenharmony_ci//
111cb0ef41Sopenharmony_ci// The above copyright notice and this permission notice shall be included
121cb0ef41Sopenharmony_ci// in all copies or substantial portions of the Software.
131cb0ef41Sopenharmony_ci//
141cb0ef41Sopenharmony_ci// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
151cb0ef41Sopenharmony_ci// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
161cb0ef41Sopenharmony_ci// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
171cb0ef41Sopenharmony_ci// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
181cb0ef41Sopenharmony_ci// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
191cb0ef41Sopenharmony_ci// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
201cb0ef41Sopenharmony_ci// USE OR OTHER DEALINGS IN THE SOFTWARE.
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci'use strict';
231cb0ef41Sopenharmony_ciconst common = require('../common');
241cb0ef41Sopenharmony_ciconst assert = require('assert');
251cb0ef41Sopenharmony_ciconst path = require('path');
261cb0ef41Sopenharmony_ciconst fs = require('fs');
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_cilet mode_async;
291cb0ef41Sopenharmony_cilet mode_sync;
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ci// Need to hijack fs.open/close to make sure that things
321cb0ef41Sopenharmony_ci// get closed once they're opened.
331cb0ef41Sopenharmony_cifs._open = fs.open;
341cb0ef41Sopenharmony_cifs._openSync = fs.openSync;
351cb0ef41Sopenharmony_cifs.open = open;
361cb0ef41Sopenharmony_cifs.openSync = openSync;
371cb0ef41Sopenharmony_cifs._close = fs.close;
381cb0ef41Sopenharmony_cifs._closeSync = fs.closeSync;
391cb0ef41Sopenharmony_cifs.close = close;
401cb0ef41Sopenharmony_cifs.closeSync = closeSync;
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_cilet openCount = 0;
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_cifunction open() {
451cb0ef41Sopenharmony_ci  openCount++;
461cb0ef41Sopenharmony_ci  return fs._open.apply(fs, arguments);
471cb0ef41Sopenharmony_ci}
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_cifunction openSync() {
501cb0ef41Sopenharmony_ci  openCount++;
511cb0ef41Sopenharmony_ci  return fs._openSync.apply(fs, arguments);
521cb0ef41Sopenharmony_ci}
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_cifunction close() {
551cb0ef41Sopenharmony_ci  openCount--;
561cb0ef41Sopenharmony_ci  return fs._close.apply(fs, arguments);
571cb0ef41Sopenharmony_ci}
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_cifunction closeSync() {
601cb0ef41Sopenharmony_ci  openCount--;
611cb0ef41Sopenharmony_ci  return fs._closeSync.apply(fs, arguments);
621cb0ef41Sopenharmony_ci}
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ci// On Windows chmod is only able to manipulate write permission
661cb0ef41Sopenharmony_ciif (common.isWindows) {
671cb0ef41Sopenharmony_ci  mode_async = 0o400;   // read-only
681cb0ef41Sopenharmony_ci  mode_sync = 0o600;    // read-write
691cb0ef41Sopenharmony_ci} else {
701cb0ef41Sopenharmony_ci  mode_async = 0o777;
711cb0ef41Sopenharmony_ci  mode_sync = 0o644;
721cb0ef41Sopenharmony_ci}
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ciconst tmpdir = require('../common/tmpdir');
751cb0ef41Sopenharmony_citmpdir.refresh();
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ciconst file1 = path.join(tmpdir.path, 'a.js');
781cb0ef41Sopenharmony_ciconst file2 = path.join(tmpdir.path, 'a1.js');
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ci// Create file1.
811cb0ef41Sopenharmony_cifs.closeSync(fs.openSync(file1, 'w'));
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_cifs.chmod(file1, mode_async.toString(8), common.mustSucceed(() => {
841cb0ef41Sopenharmony_ci  if (common.isWindows) {
851cb0ef41Sopenharmony_ci    assert.ok((fs.statSync(file1).mode & 0o777) & mode_async);
861cb0ef41Sopenharmony_ci  } else {
871cb0ef41Sopenharmony_ci    assert.strictEqual(fs.statSync(file1).mode & 0o777, mode_async);
881cb0ef41Sopenharmony_ci  }
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_ci  fs.chmodSync(file1, mode_sync);
911cb0ef41Sopenharmony_ci  if (common.isWindows) {
921cb0ef41Sopenharmony_ci    assert.ok((fs.statSync(file1).mode & 0o777) & mode_sync);
931cb0ef41Sopenharmony_ci  } else {
941cb0ef41Sopenharmony_ci    assert.strictEqual(fs.statSync(file1).mode & 0o777, mode_sync);
951cb0ef41Sopenharmony_ci  }
961cb0ef41Sopenharmony_ci}));
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_cifs.open(file2, 'w', common.mustSucceed((fd) => {
991cb0ef41Sopenharmony_ci  fs.fchmod(fd, mode_async.toString(8), common.mustSucceed(() => {
1001cb0ef41Sopenharmony_ci    if (common.isWindows) {
1011cb0ef41Sopenharmony_ci      assert.ok((fs.fstatSync(fd).mode & 0o777) & mode_async);
1021cb0ef41Sopenharmony_ci    } else {
1031cb0ef41Sopenharmony_ci      assert.strictEqual(fs.fstatSync(fd).mode & 0o777, mode_async);
1041cb0ef41Sopenharmony_ci    }
1051cb0ef41Sopenharmony_ci
1061cb0ef41Sopenharmony_ci    assert.throws(
1071cb0ef41Sopenharmony_ci      () => fs.fchmod(fd, {}),
1081cb0ef41Sopenharmony_ci      {
1091cb0ef41Sopenharmony_ci        code: 'ERR_INVALID_ARG_TYPE',
1101cb0ef41Sopenharmony_ci      }
1111cb0ef41Sopenharmony_ci    );
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ci    fs.fchmodSync(fd, mode_sync);
1141cb0ef41Sopenharmony_ci    if (common.isWindows) {
1151cb0ef41Sopenharmony_ci      assert.ok((fs.fstatSync(fd).mode & 0o777) & mode_sync);
1161cb0ef41Sopenharmony_ci    } else {
1171cb0ef41Sopenharmony_ci      assert.strictEqual(fs.fstatSync(fd).mode & 0o777, mode_sync);
1181cb0ef41Sopenharmony_ci    }
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ci    fs.close(fd, assert.ifError);
1211cb0ef41Sopenharmony_ci  }));
1221cb0ef41Sopenharmony_ci}));
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ci// lchmod
1251cb0ef41Sopenharmony_ciif (fs.lchmod) {
1261cb0ef41Sopenharmony_ci  const link = path.join(tmpdir.path, 'symbolic-link');
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ci  fs.symlinkSync(file2, link);
1291cb0ef41Sopenharmony_ci
1301cb0ef41Sopenharmony_ci  fs.lchmod(link, mode_async, common.mustSucceed(() => {
1311cb0ef41Sopenharmony_ci    assert.strictEqual(fs.lstatSync(link).mode & 0o777, mode_async);
1321cb0ef41Sopenharmony_ci
1331cb0ef41Sopenharmony_ci    fs.lchmodSync(link, mode_sync);
1341cb0ef41Sopenharmony_ci    assert.strictEqual(fs.lstatSync(link).mode & 0o777, mode_sync);
1351cb0ef41Sopenharmony_ci
1361cb0ef41Sopenharmony_ci  }));
1371cb0ef41Sopenharmony_ci}
1381cb0ef41Sopenharmony_ci
1391cb0ef41Sopenharmony_ci[false, 1, {}, [], null, undefined].forEach((input) => {
1401cb0ef41Sopenharmony_ci  const errObj = {
1411cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_ARG_TYPE',
1421cb0ef41Sopenharmony_ci    name: 'TypeError',
1431cb0ef41Sopenharmony_ci    message: 'The "path" argument must be of type string or an instance ' +
1441cb0ef41Sopenharmony_ci             'of Buffer or URL.' +
1451cb0ef41Sopenharmony_ci             common.invalidArgTypeHelper(input)
1461cb0ef41Sopenharmony_ci  };
1471cb0ef41Sopenharmony_ci  assert.throws(() => fs.chmod(input, 1, common.mustNotCall()), errObj);
1481cb0ef41Sopenharmony_ci  assert.throws(() => fs.chmodSync(input, 1), errObj);
1491cb0ef41Sopenharmony_ci});
1501cb0ef41Sopenharmony_ci
1511cb0ef41Sopenharmony_ciprocess.on('exit', function() {
1521cb0ef41Sopenharmony_ci  assert.strictEqual(openCount, 0);
1531cb0ef41Sopenharmony_ci});
154