-
Notifications
You must be signed in to change notification settings - Fork 0
/
file.scm
77 lines (70 loc) · 2.41 KB
/
file.scm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
(use srfi-1)
(use file.util)
(use util.match)
(use gauche.parameter)
(define current-link (make-parameter "current"))
(define data-dir (make-parameter "data"))
(define (max-file-size) (config-get 'max-file-size))
(define (log-files)
(if (file-is-directory? (data-dir))
(let ((lst (directory-list (data-dir) :add-path? #t)))
(filter #/.log$/ lst)
)
()))
(define (create-new-file)
(if (file-exists? (data-dir))
(if (file-is-directory? (data-dir))
(let1 path (build-path (data-dir)
(string-append (current-link) "."
(x->string (sys-time)) "."
(x->string (sys-getpid)) ".log"))
(touch-file path)
path)
(error #`",(data-dir) is not a direcotry."))
(begin (make-directory* (data-dir))
(create-new-file))))
(define (get-or-prepare-log-file)
(if (file-exists? (current-link))
(if (file-is-symlink? (current-link))
(sys-readlink (current-link))
(error #`",(current-link) is not a symlink."))
(let1 file (create-new-file)
(sys-symlink file (current-link))
file)))
(define (read-from-log-aux port file pos end)
(let loop ((pos pos)
(part ()))
(if (> end pos)
(begin
(port-seek port pos)
(let ((exp (read port)))
(let ((exp2 (match exp
(`(chat-entry . ,content)
`(chat-entry
(link (file ,file) (pos ,pos))
. ,content))
(else exp))))
(loop (port-tell port) (cons exp2 part))))
)
(values (reverse part) file pos))))
(define (read-from-log file pos)
(let ((pos (or pos 0))
(file (or file (get-or-prepare-log-file))))
(let ((port (open-input-file file)))
(let wait-loop ((count 0))
(let ((end (port-seek port 0 SEEK_END)))
(if (> end pos)
(read-from-log-aux port file pos end)
(if (> count 30)
(values () file pos)
(begin
(sys-sleep 1)
(wait-loop (+ count 1))))))))))
(define (read-from-log-no-wait file pos)
(let ((pos (or pos 0))
(file (or file (get-or-prepare-log-file))))
(let ((port (open-input-file file)))
(let ((end (port-seek port 0 SEEK_END)))
(if (> end pos)
(read-from-log-aux port file pos end)
(values () file pos))))))