Loading...
Searching...
No Matches
clean_temp.c
Go to the documentation of this file.
#include <grass/config.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <grass/gis.h>
#include "local_proto.h"
/**************************************************************
* clean_temp
*
* looks for all files in mapset temp directory
* of the form pid.n and removes those which have
* been abandoned their processes (pid).
*
* also removes any other file found which is "old"
* with an modification time greater then 4 days
*
* 2006: Rewritten for GRASS 6 by Roberto Flor, ITC-irst
*
**************************************************************/
#include <limits.h>
#include <string.h>
#include <errno.h>
#ifdef PATH_MAX
#define BUF_MAX PATH_MAX
#else
#define BUF_MAX 4096
#endif
#define SLEEP 30 /* 30 seconds */
/* Recursively scan the directory pathname, removing directory and files */
void clean_dir(const char *pathname, uid_t uid, pid_t pid, time_t now,
int max_age)
{
char buf[BUF_MAX];
DIR *curdir;
struct dirent *cur_entry;
struct stat info;
int n, pathlen;
curdir = opendir(pathname);
if (curdir == NULL) {
G_warning("Can't open directory %s: %s,skipping\n", pathname,
strerror(errno));
return;
}
/* loop over current dir */
while ((cur_entry = readdir(curdir))) {
if ((G_strcasecmp(cur_entry->d_name, ".") == 0) ||
(G_strcasecmp(cur_entry->d_name, "..") == 0))
continue; /* Skip dir and parent dir entries */
if ((pathlen = snprintf(buf, BUF_MAX, "%s/%s", pathname,
cur_entry->d_name)) >= BUF_MAX)
G_fatal_error("clean_temp: exceeded maximum pathname length %d, "
"got %d, shouldn't happen",
BUF_MAX, pathlen);
if (stat(buf, &info) != 0) {
G_warning("Can't stat file %s: %s,skipping\n", buf,
strerror(errno));
continue;
}
if (S_ISDIR(info.st_mode)) { /* It's a dir, recurring */
clean_dir(buf, uid, pid, now, max_age);
/* Return here means we have completed the subdir recursion */
/* Trying to remove the now empty dir */
if (info.st_uid != uid) /* Not owners of dir */
continue;
#ifndef DEBUG_CLEAN
if (rmdir(buf) != 0) {
if (errno != ENOTEMPTY) {
G_warning("Can't remove empty directory %s: %s,skipping\n",
buf, strerror(errno));
}
}
#else
G_warning("Removing directory %s\n", buf);
#endif
}
else { /* It's a file check it */
if (info.st_uid ==
uid) { /* Remove only files owned by current user */
if (sscanf(cur_entry->d_name, "%d.%d", &pid, &n) == 2) {
if (!find_process(pid))
#ifndef DEBUG_CLEAN
if (unlink(buf) != 0)
G_warning("Can't remove file %s: %s,skipping\n",
buf, strerror(errno));
#else
G_warning("Removing file %s\n", buf);
#endif
}
else {
if ((now - info.st_mtime) >
max_age) /* Not modified in 4 days: TODO configurable
param */
#ifndef DEBUG_CLEAN
if (unlink(buf) != 0)
G_warning("Can't remove file %s: %s,skipping\n",
buf, strerror(errno));
#else
G_warning("Removing file %s\n", buf);
#endif
}
}
}
}
closedir(curdir);
return;
}
int main(int argc, char *argv[])
{
const char *mapset;
char element[GNAME_MAX];
char tmppath[BUF_MAX];
pid_t ppid;
pid_t pid;
uid_t uid;
time_t now;
long max_age;
G_gisinit(argv[0]);
pid = 0;
ppid = 0;
if (argc > 1)
sscanf(argv[1], "%d", &ppid);
/* Get the mapset temp directory */
G_temp_element(element);
G_file_name(tmppath, element, "", mapset = G_mapset());
/* get user id and current time in seconds */
#ifdef _WIN32
/* TODO */
uid = -1;
#else
uid = getuid();
#endif
now = time(NULL);
/* set maximum age in seconds (4 days) */
max_age = 4 * 24 * 60 * 60;
/*
* Scan the temp directory and subdirectory for
* files owned by the user and of the form pid.n
* to be removed if the process is not running
* all "old" files are removed as well
*/
while (1) {
if (ppid > 0 && !find_process(ppid))
break;
clean_dir(tmppath, uid, pid, now, max_age);
if (ppid <= 0)
break;
G_sleep(SLEEP);
}
exit(0);
}
int find_process(int pid)
{
#ifdef _WIN32
/* TODO */
return -1;
#else
return (kill(pid, 0) == 0 || errno != ESRCH);
#endif
}
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