GRASS 8 Programmer's Manual
8.5.0(2026)-8d6ceba290
Toggle main menu visibility
Loading...
Searching...
No Matches
clean_temp.c
Go to the documentation of this file.
1
#include <grass/config.h>
2
#include <stdlib.h>
3
#include <stdio.h>
4
#include <signal.h>
5
#include <unistd.h>
6
#include <time.h>
7
#include <sys/types.h>
8
#include <dirent.h>
9
#include <sys/stat.h>
10
#include <grass/gis.h>
11
#include "local_proto.h"
12
13
/**************************************************************
14
* clean_temp
15
*
16
* looks for all files in mapset temp directory
17
* of the form pid.n and removes those which have
18
* been abandoned their processes (pid).
19
*
20
* also removes any other file found which is "old"
21
* with an modification time greater then 4 days
22
*
23
* 2006: Rewritten for GRASS 6 by Roberto Flor, ITC-irst
24
*
25
**************************************************************/
26
27
#include <limits.h>
28
#include <string.h>
29
#include <errno.h>
30
#ifdef PATH_MAX
31
#define BUF_MAX PATH_MAX
32
#else
33
#define BUF_MAX 4096
34
#endif
35
36
#define SLEEP 30
/* 30 seconds */
37
38
/* Recursively scan the directory pathname, removing directory and files */
39
void
clean_dir
(
const
char
*pathname, uid_t uid, pid_t pid, time_t now,
40
int
max_age)
41
{
42
char
buf[
BUF_MAX
];
43
DIR *curdir;
44
struct
dirent *cur_entry;
45
struct
stat info;
46
int
n, pathlen;
47
48
curdir = opendir(pathname);
49
if
(curdir ==
NULL
) {
50
G_warning
(
"Can't open directory %s: %s,skipping\n"
, pathname,
51
strerror(errno));
52
return
;
53
}
54
/* loop over current dir */
55
while
((cur_entry = readdir(curdir))) {
56
if
((
G_strcasecmp
(cur_entry->d_name,
"."
) == 0) ||
57
(
G_strcasecmp
(cur_entry->d_name,
".."
) == 0))
58
continue
;
/* Skip dir and parent dir entries */
59
60
if
((pathlen = snprintf(buf,
BUF_MAX
,
"%s/%s"
, pathname,
61
cur_entry->d_name)) >=
BUF_MAX
)
62
G_fatal_error
(
"clean_temp: exceeded maximum pathname length %d, "
63
"got %d, shouldn't happen"
,
64
BUF_MAX
, pathlen);
65
66
if
(stat(buf, &info) != 0) {
67
G_warning
(
"Can't stat file %s: %s,skipping\n"
, buf,
68
strerror(errno));
69
continue
;
70
}
71
if
(S_ISDIR(info.st_mode)) {
/* It's a dir, recurring */
72
clean_dir
(buf, uid, pid, now, max_age);
73
/* Return here means we have completed the subdir recursion */
74
/* Trying to remove the now empty dir */
75
if
(info.st_uid != uid)
/* Not owners of dir */
76
continue
;
77
#ifndef DEBUG_CLEAN
78
if
(rmdir(buf) != 0) {
79
if
(errno != ENOTEMPTY) {
80
G_warning
(
"Can't remove empty directory %s: %s,skipping\n"
,
81
buf, strerror(errno));
82
}
83
}
84
#else
85
G_warning
(
"Removing directory %s\n"
, buf);
86
#endif
87
}
88
else
{
/* It's a file check it */
89
if
(info.st_uid ==
90
uid) {
/* Remove only files owned by current user */
91
if
(sscanf(cur_entry->d_name,
"%d.%d"
, &pid, &n) == 2) {
92
if
(!
find_process
(pid))
93
#ifndef DEBUG_CLEAN
94
if
(unlink(buf) != 0)
95
G_warning
(
"Can't remove file %s: %s,skipping\n"
,
96
buf, strerror(errno));
97
#else
98
G_warning
(
"Removing file %s\n"
, buf);
99
#endif
100
}
101
else
{
102
if
((now - info.st_mtime) >
103
max_age)
/* Not modified in 4 days: TODO configurable
104
param */
105
#ifndef DEBUG_CLEAN
106
if
(unlink(buf) != 0)
107
G_warning
(
"Can't remove file %s: %s,skipping\n"
,
108
buf, strerror(errno));
109
#else
110
G_warning
(
"Removing file %s\n"
, buf);
111
#endif
112
}
113
}
114
}
115
}
116
closedir(curdir);
117
return
;
118
}
119
120
int
main
(
int
argc,
char
*argv[])
121
{
122
const
char
*mapset;
123
char
element
[GNAME_MAX];
124
char
tmppath[
BUF_MAX
];
125
pid_t ppid;
126
pid_t pid;
127
uid_t uid;
128
time_t now;
129
long
max_age;
130
131
G_gisinit(argv[0]);
132
pid = 0;
133
ppid = 0;
134
if
(argc > 1)
135
sscanf(argv[1],
"%d"
, &ppid);
136
137
/* Get the mapset temp directory */
138
G_temp_element
(
element
);
139
G_file_name
(tmppath,
element
,
""
, mapset =
G_mapset
());
140
141
/* get user id and current time in seconds */
142
#ifdef _WIN32
143
/* TODO */
144
uid = -1;
145
#else
146
uid = getuid();
147
#endif
148
149
now = time(
NULL
);
150
151
/* set maximum age in seconds (4 days) */
152
max_age = 4 * 24 * 60 * 60;
153
154
/*
155
* Scan the temp directory and subdirectory for
156
* files owned by the user and of the form pid.n
157
* to be removed if the process is not running
158
* all "old" files are removed as well
159
*/
160
161
while
(1) {
162
if
(ppid > 0 && !
find_process
(ppid))
163
break
;
164
clean_dir
(tmppath, uid, pid, now, max_age);
165
if
(ppid <= 0)
166
break
;
167
G_sleep
(
SLEEP
);
168
}
169
exit(0);
170
}
171
172
int
find_process
(
int
pid)
173
{
174
#ifdef _WIN32
175
/* TODO */
176
return
-1;
177
#else
178
return
(kill(pid, 0) == 0 || errno != ESRCH);
179
#endif
180
}
NULL
#define NULL
Definition
ccmath.h:32
SLEEP
#define SLEEP
Definition
clean_temp.c:36
find_process
int find_process(int pid)
Definition
clean_temp.c:172
BUF_MAX
#define BUF_MAX
Definition
clean_temp.c:33
clean_dir
void clean_dir(const char *pathname, uid_t uid, pid_t pid, time_t now, int max_age)
Definition
clean_temp.c:39
G_file_name
char * G_file_name(char *path, const char *element, const char *name, const char *mapset)
Builds full path names to GIS data files.
Definition
file_name.c:61
G_fatal_error
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition
gis/error.c:159
G_warning
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition
gis/error.c:203
G_mapset
const char * G_mapset(void)
Get current mapset name.
Definition
mapset.c:33
G_sleep
void G_sleep(unsigned int seconds)
Definition
sleep.c:11
G_strcasecmp
int G_strcasecmp(const char *x, const char *y)
String compare ignoring case (upper or lower).
Definition
strings.c:47
element
Definition
lidar.h:85
G_temp_element
void G_temp_element(char *element)
Populates element with a path string.
Definition
tempfile.c:148
main
int main(void)
Definition
winlocale.c:201
init
clean_temp.c
Generated on
for GRASS 8 Programmer's Manual by
1.17.0