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

utimens provide atime instead of mtime #3

Open
aa6 opened this issue May 23, 2024 · 0 comments
Open

utimens provide atime instead of mtime #3

aa6 opened this issue May 23, 2024 · 0 comments

Comments

@aa6
Copy link

aa6 commented May 23, 2024

Greetings everyone.

I have found out that utimens operation possibly contains a bug.

Consider the following code:

const fs = require('fs')
const os = require('os')
const nodepath = require('path')
const FuseNative = require('@cocalc/fuse-native')

async function testapp001()
{
    var mountpoint = fs.mkdtempSync(nodepath.join(os.tmpdir(), 'FuseNative-'))
    var fuse = new FuseNative(
        mountpoint, 
        {
            getattr: function(path, cb) 
            { 
                if (path == '/test.txt') 
                {
                    var stats = 
                    {
                        mtime: new Date(),
                        atime: new Date(),
                        ctime: new Date(),
                        size: 11,
                        mode: 33188,
                        uid: process.getuid(),
                        gid: process.getgid()
                    }
                    return process.nextTick(cb, null, stats)
                }
                else 
                { 
                    return process.nextTick(cb, FuseNative.ENOENT) 
                }
            },
            utimens: function(path, atime, mtime, cb)
            {
                console.log('utimens',{atime,mtime})
                return process.nextTick(cb, 0)
            },
        }, 
        {
            debug: false,
            force: true,
            mkdir: true,
        },
    )
    try
    {
        await new Promise((resolve, reject) => fuse.mount(err => err ? reject(err) : resolve()))
        await fs.promises.utimes(mountpoint + '/test.txt',0,9999)
        await fs.promises.utimes(mountpoint + '/test.txt',9999,0)
    }
    catch(err)
    {
        console.log({err})
    }
    finally
    {
        await new Promise((resolve, reject) => fuse.unmount(err => err ? reject(err) : resolve()))
    }
}

testapp001()

It outputs

utimens { atime: 0, mtime: 0 }
utimens { atime: 9999000, mtime: 9999000 }

although atime and mtime parameters on fs.promises.utimes() are different each call.

I apologize for not providing the pull request, because I'm not fully aware of how NAPI modules are compiled and written. But it seems that the problem lies in fuse-native.c definition:

fuse-native/fuse-native.c

Lines 345 to 346 in 828e14e

FUSE_UINT64_TO_INTS_ARGV(l->atime, 3)
FUSE_UINT64_TO_INTS_ARGV(l->atime, 5)

FUSE_METHOD_VOID(utimens, 5, 0, (const char *path, const struct timespec tv[2]), {
  l->path = path;
  l->atime = timespec_to_uint64(&tv[0]);
  l->mtime = timespec_to_uint64(&tv[1]);
}, {
  napi_create_string_utf8(env, l->path, NAPI_AUTO_LENGTH, &(argv[2]));
  FUSE_UINT64_TO_INTS_ARGV(l->atime, 3)
  FUSE_UINT64_TO_INTS_ARGV(l->atime, 5)
})

where the last lines instead of

  FUSE_UINT64_TO_INTS_ARGV(l->atime, 3)
  FUSE_UINT64_TO_INTS_ARGV(l->atime, 5)

should be the

  FUSE_UINT64_TO_INTS_ARGV(l->atime, 3)
  FUSE_UINT64_TO_INTS_ARGV(l->mtime, 5)

Thank you for supporting the module and have a nice day.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant