Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chmodSync is not recursive #8653

Closed
kkorada opened this issue Sep 19, 2016 · 5 comments
Closed

chmodSync is not recursive #8653

kkorada opened this issue Sep 19, 2016 · 5 comments
Labels
feature request Issues that request new features to be added to Node.js. fs Issues and PRs related to the fs subsystem / file system.

Comments

@kkorada
Copy link

kkorada commented Sep 19, 2016

fs.chmodSync() is not recursive please add recursive feature to it.

There should be some flag option available to make it recursive.

with fs.chmodSync() "chmod 777 -R some-folder/" cannot be achieved

  • Version: v4.5.0
  • Platform: linux/windows
  • Subsystem: NA
@bnoordhuis bnoordhuis added fs Issues and PRs related to the fs subsystem / file system. feature request Issues that request new features to be added to Node.js. labels Sep 19, 2016
@bnoordhuis
Copy link
Member

fs.chmod() is a wrapper around the system call of the same name, not the command line tool. The system call does not support recursion.

@addaleax
Copy link
Member

@kkorada
Copy link
Author

kkorada commented Sep 20, 2016

thank you

@angstyloop
Copy link

angstyloop commented Oct 2, 2022

@kkorada @bnoordhuis @addaleax Here is a Node.js script that uses the built-in module fs to chmod -R <PERMISSIONS> <DIRECTORY>.

Source code is here too.

But please note these concerns about the vulnerability to TOCTOU attacks.

USAGE: ./chmodRecursive <DIRECTORY> <PERMISSIONS>

PERMISSIONS is a three character string, like 777.

#! /usr/bin/env node

const { readdirSync, lstatSync, isDirectory, chmodSync } = require('fs');
const { join, posix: { basename } } = require('path');

/** List subdirectories of target directory @d. NOT recursive.
 * @param dir - (string) Target directory.
 * @return (string[]) Subdirectories of @d.
 */
function listDirs(dir) {
    return readdirSync(dir)
            .map(it => join(dir, it))
            .filter(it => lstatSync(it).isDirectory());
}

/** List files (and subdirectories) in target directory @dir. NOT recursive.
 * @param dir - (string) Full or relative path of target directory.
 * @return (string[]) Files of @dir.
 */
function listChildren(dir) {
    return readdirSync(dir).map(it => join(dir, it));
}

/** chmod all files (and subdirectories) in a directory @dir, giving them new
 * permissions @perms. NOT recursive.
 *
 * @param dir - (string) Full or relative path of target directory.
 * @perms - (string) Permissions for chmod, as a string (e.g., '644')
 */
function chmodChildren(dir, perms) {
    listChildren(dir).map(it => chmodSync(it, perms));
}

/* Starting in the directory named @root, recursively find and chmod all
 * all files and subdirectories. The directory @root is also chmod'd.
 * Implements BFS with a FIFO queue.
 *
 * @root - Full or relative path of directory to start in.
 * @perms - (string) Permissions for chmod, as a string (e.g., '644')
 *
 */
/*module.exports = */function chmodRecursive(root, perms) {
    let dir = root;
    chmodSync(root, perms);
    chmodChildren(root, perms);
    const dirs = listDirs(dir);
    while (dirs.length) {
        dir = dirs.shift();
        chmodChildren(dir, perms);
        dirs.push(...listDirs(dir));
    }
}

const EXIT_SUCCESS = 0;
const EXIT_FAILURE = 1;

/** Driver code.
 */
function main() {
    // "node" and the name of the script are always the first two arguments.
    // Your command line arguments start at index=2 (the third argument -
    // totally not confusing, right?)
    if (process.argv.length !== 4) {
        console.log('USAGE: ./chmodRecursive <DIRECTORY> <PERMISSIONS>');
        console.log('PERMISSIONS is a three character string, like 777.');
        process.exit(EXIT_FAILURE);
    }
    chmodRecursive(...process.argv.slice(2));
    process.exit(EXIT_SUCCESS);
}

main();

@bnoordhuis
Copy link
Member

bnoordhuis commented Oct 2, 2022

@angstyloop Please open a pull request if you want. The recursive Rubicon has been crossed for fs.mkdir() so I suppose there is no reason to not support it in fs.chmod().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request Issues that request new features to be added to Node.js. fs Issues and PRs related to the fs subsystem / file system.
Projects
None yet
Development

No branches or pull requests

4 participants