1 /* Virtual File System garbage collection code
2 Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
4 Written by: 1995 Miguel de Icaza
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public License
11 as published by the Free Software Foundation; either version 2 of
12 the License, or (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU Library General Public License for more details.
19 You should have received a copy of the GNU Library General Public
20 License along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
26 #include <stdlib.h> /* For atol() */
30 #include <sys/types.h>
32 #include <ctype.h> /* is_digit() */
34 #include "../src/global.h"
35 #include "../src/tty.h" /* enable/disable interrupt key */
36 #include "../src/wtools.h" /* message() */
37 #include "../src/main.h" /* print_vfs_message */
43 #include "../src/panel.h" /* get_current_panel() */
44 #include "../src/layout.h" /* get_current_type() */
47 int vfs_timeout
= 60; /* VFS timeout in seconds */
49 static struct vfs_stamping
*stamps
;
53 vfs_addstamp (struct vfs_class
*v
, vfsid id
)
55 if (!(v
->flags
& VFSF_LOCAL
) && id
!= NULL
) {
56 struct vfs_stamping
*stamp
;
57 struct vfs_stamping
*last_stamp
= NULL
;
59 for (stamp
= stamps
; stamp
!= NULL
; stamp
= stamp
->next
) {
60 if (stamp
->v
== v
&& stamp
->id
== id
) {
61 gettimeofday (&(stamp
->time
), NULL
);
66 stamp
= g_new (struct vfs_stamping
, 1);
70 gettimeofday (&(stamp
->time
), NULL
);
75 last_stamp
->next
= stamp
;
77 /* Add first element */
85 vfs_stamp (struct vfs_class
*v
, vfsid id
)
87 struct vfs_stamping
*stamp
;
89 for (stamp
= stamps
; stamp
!= NULL
; stamp
= stamp
->next
)
90 if (stamp
->v
== v
&& stamp
->id
== id
) {
91 gettimeofday (&(stamp
->time
), NULL
);
98 vfs_rmstamp (struct vfs_class
*v
, vfsid id
)
100 struct vfs_stamping
*stamp
, *st1
;
102 for (stamp
= stamps
, st1
= NULL
; stamp
!= NULL
;
103 st1
= stamp
, stamp
= stamp
->next
)
104 if (stamp
->v
== v
&& stamp
->id
== id
) {
106 stamps
= stamp
->next
;
108 st1
->next
= stamp
->next
;
117 /* Find VFS id for given directory name */
119 vfs_getid (struct vfs_class
*vclass
, const char *dir
)
124 /* append slash if needed */
125 dir1
= concat_dir_and_file (dir
, "");
127 id
= (*vclass
->getid
) (vclass
, dir1
);
135 vfs_stamp_path (char *path
)
137 struct vfs_class
*vfs
;
140 vfs
= vfs_get_class (path
);
141 id
= vfs_getid (vfs
, path
);
142 vfs_addstamp (vfs
, id
);
147 * Create a new timestamp item by VFS class and VFS id.
150 vfs_stamp_create (struct vfs_class
*oldvfs
, vfsid oldvfsid
)
152 struct vfs_class
*nvfs
, *n2vfs
, *n3vfs
;
153 vfsid nvfsid
, n2vfsid
, n3vfsid
;
155 /* There are three directories we have to take care of: current_dir,
156 current_panel->cwd and other_panel->cwd. Athough most of the time either
157 current_dir and current_panel->cwd or current_dir and other_panel->cwd are the
158 same, it's possible that all three are different -- Norbert */
163 nvfs
= vfs_get_class (vfs_get_current_dir ());
164 nvfsid
= vfs_getid (nvfs
, vfs_get_current_dir ());
165 vfs_rmstamp (nvfs
, nvfsid
);
167 if ((nvfs
== oldvfs
&& nvfsid
== oldvfsid
) || oldvfsid
== NULL
) {
171 if (get_current_type () == view_listing
) {
172 n2vfs
= vfs_get_class (current_panel
->cwd
);
173 n2vfsid
= vfs_getid (n2vfs
, current_panel
->cwd
);
174 if (n2vfs
== oldvfs
&& n2vfsid
== oldvfsid
)
181 if (get_other_type () == view_listing
) {
182 n3vfs
= vfs_get_class (other_panel
->cwd
);
183 n3vfsid
= vfs_getid (n3vfs
, other_panel
->cwd
);
184 if (n3vfs
== oldvfs
&& n3vfsid
== oldvfsid
)
191 if (!oldvfs
->nothingisopen
|| !(*oldvfs
->nothingisopen
) (oldvfsid
))
194 vfs_addstamp (oldvfs
, oldvfsid
);
199 vfs_add_current_stamps (void)
201 vfs_stamp_path (vfs_get_current_dir ());
204 if (get_current_type () == view_listing
)
205 vfs_stamp_path (current_panel
->cwd
);
209 if (get_other_type () == view_listing
)
210 vfs_stamp_path (other_panel
->cwd
);
215 /* Compare two timeval structures. Return 0 is t1 is less than t2. */
217 timeoutcmp (struct timeval
*t1
, struct timeval
*t2
)
219 return ((t1
->tv_sec
< t2
->tv_sec
)
220 || ((t1
->tv_sec
== t2
->tv_sec
)
221 && (t1
->tv_usec
<= t2
->tv_usec
)));
225 /* This is called from timeout handler with now = 0, or can be called
226 with now = 1 to force freeing all filesystems that are not in use */
230 static int locked
= 0;
232 struct vfs_stamping
*stamp
, *st
;
234 /* Avoid recursive invocation, e.g. when one of the free functions
240 gettimeofday (&time
, NULL
);
241 time
.tv_sec
-= vfs_timeout
;
243 for (stamp
= stamps
; stamp
!= NULL
;) {
244 if (now
|| (timeoutcmp (&stamp
->time
, &time
))) {
247 (*stamp
->v
->free
) (stamp
->id
);
248 vfs_rmstamp (stamp
->v
, stamp
->id
);
258 * Return the number of seconds remaining to the vfs timeout.
259 * FIXME: The code should be improved to actually return the number of
260 * seconds until the next item times out.
265 return stamps
? 10 : 0;
270 vfs_timeout_handler (void)
277 vfs_release_path (const char *dir
)
279 struct vfs_class
*oldvfs
;
282 oldvfs
= vfs_get_class (dir
);
283 oldvfsid
= vfs_getid (oldvfs
, dir
);
284 vfs_stamp_create (oldvfs
, oldvfsid
);
292 struct vfs_stamping
*stamp
, *st
;
294 for (stamp
= stamps
, stamps
= 0; stamp
!= NULL
;) {
296 (*stamp
->v
->free
) (stamp
->id
);
303 vfs_rmstamp (stamps
->v
, stamps
->id
);