mirror of
https://github.com/winfsp/cgofuse.git
synced 2025-04-18 23:04:00 +03:00
135 lines
3.0 KiB
Go
135 lines
3.0 KiB
Go
//go:build windows
|
|
// +build windows
|
|
|
|
/*
|
|
* notifyfs.go
|
|
*
|
|
* Copyright 2017-2022 Bill Zissimopoulos
|
|
*/
|
|
/*
|
|
* This file is part of Cgofuse.
|
|
*
|
|
* It is licensed under the MIT license. The full license text can be found
|
|
* in the License.txt file at the root of this project.
|
|
*/
|
|
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
"sync/atomic"
|
|
"time"
|
|
|
|
"github.com/winfsp/cgofuse/fuse"
|
|
)
|
|
|
|
type Notifyfs struct {
|
|
fuse.FileSystemBase
|
|
ticks uint64
|
|
}
|
|
|
|
func countFromTicks(ticks uint64) uint64 {
|
|
/*
|
|
* The formula below produces the periodic sequence:
|
|
* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,
|
|
* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,
|
|
* ...
|
|
*/
|
|
div10 := (ticks % 20) / 10
|
|
mod10 := ticks % 10
|
|
mdv10 := 1 - div10
|
|
mmd10 := 10 - mod10
|
|
return mdv10*mod10 + div10*mmd10
|
|
}
|
|
|
|
func (self *Notifyfs) count() uint64 {
|
|
return countFromTicks(atomic.LoadUint64(&self.ticks))
|
|
}
|
|
|
|
func (self *Notifyfs) lookup(path string) uint64 {
|
|
count := self.count()
|
|
index, _ := strconv.ParseUint(path[1:], 10, 0)
|
|
if 0 < index && index <= count {
|
|
return index
|
|
}
|
|
return ^uint64(0)
|
|
}
|
|
|
|
func (self *Notifyfs) Open(path string, flags int) (errc int, fh uint64) {
|
|
index := self.lookup(path)
|
|
if ^uint64(0) == index {
|
|
return -fuse.ENOENT, ^uint64(0)
|
|
}
|
|
return 0, index
|
|
}
|
|
|
|
func (self *Notifyfs) Getattr(path string, stat *fuse.Stat_t, fh uint64) (errc int) {
|
|
if "/" == path {
|
|
stat.Mode = fuse.S_IFDIR | 0555
|
|
return 0
|
|
}
|
|
index := self.lookup(path)
|
|
if ^uint64(0) == index {
|
|
return -fuse.ENOENT
|
|
}
|
|
contents := strconv.FormatUint(index, 10) + "\n"
|
|
stat.Mode = fuse.S_IFREG | 0444
|
|
stat.Size = int64(len(contents))
|
|
return 0
|
|
}
|
|
|
|
func (self *Notifyfs) Read(path string, buff []byte, ofst int64, fh uint64) (n int) {
|
|
index := self.lookup(path)
|
|
if ^uint64(0) == index {
|
|
return -fuse.ENOENT
|
|
}
|
|
contents := strconv.FormatUint(index, 10) + "\n"
|
|
endofst := ofst + int64(len(buff))
|
|
if endofst > int64(len(contents)) {
|
|
endofst = int64(len(contents))
|
|
}
|
|
if endofst < ofst {
|
|
return 0
|
|
}
|
|
n = copy(buff, contents[ofst:endofst])
|
|
return
|
|
}
|
|
|
|
func (self *Notifyfs) Readdir(path string,
|
|
fill func(name string, stat *fuse.Stat_t, ofst int64) bool,
|
|
ofst int64,
|
|
fh uint64) (errc int) {
|
|
fill(".", nil, 0)
|
|
fill("..", nil, 0)
|
|
count := self.count()
|
|
for u := uint64(1); count >= u; u++ {
|
|
fill(strconv.FormatUint(u, 10), nil, 0)
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (self *Notifyfs) tick(host *fuse.FileSystemHost) {
|
|
ticker := time.NewTicker(1 * time.Second)
|
|
for range ticker.C {
|
|
ticks := atomic.AddUint64(&self.ticks, 1)
|
|
oldcount := countFromTicks(ticks - 1)
|
|
newcount := countFromTicks(ticks)
|
|
if oldcount < newcount {
|
|
fmt.Println("CREATE", "/"+strconv.FormatUint(newcount, 10))
|
|
host.Notify("/"+strconv.FormatUint(newcount, 10), fuse.NOTIFY_CREATE)
|
|
} else if oldcount > newcount {
|
|
fmt.Println("UNLINK", "/"+strconv.FormatUint(oldcount, 10))
|
|
host.Notify("/"+strconv.FormatUint(oldcount, 10), fuse.NOTIFY_UNLINK)
|
|
}
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
notifyfs := &Notifyfs{}
|
|
host := fuse.NewFileSystemHost(notifyfs)
|
|
go notifyfs.tick(host)
|
|
host.Mount("", os.Args[1:])
|
|
}
|