Clean /tmp on boot.

This commit is contained in:
Nicholas De Nova 2017-04-19 08:56:53 -05:00
parent 326e43f3e9
commit 8b64b4bbbe
2 changed files with 131 additions and 0 deletions

View File

@ -84,6 +84,11 @@ command line if it hasn't been password protected.
Likewise unprivileged users can use their own replacement bootloader by booting Likewise unprivileged users can use their own replacement bootloader by booting
a portable device under their control if the firmware configuration has not been a portable device under their control if the firmware configuration has not been
password protected. password protected.
.Ss Cleanup of /tmp
.Nm
deletes everything inside of
.Pa /tmp
if it exists, otherwise it is created with mode 1777.
.Ss Partition Creation .Ss Partition Creation
.Nm .Nm
will scan every block device for valid partition tables and create the will scan every block device for valid partition tables and create the

View File

@ -538,6 +538,131 @@ static void set_videomode(void)
xres, yres, bpp); xres, yres, bpp);
} }
static int no_dot_nor_dot_dot(const struct dirent* entry, void* ctx)
{
(void) ctx;
return !strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..") ? 0 : 1;
}
struct clean_tmp
{
struct clean_tmp* parent;
DIR* dir;
char* path;
struct dirent** entries;
int num_entries;
int current_entry;
};
static void clean_tmp(void)
{
const char* tmp_path = "/tmp";
struct clean_tmp* state = calloc(1, sizeof(struct clean_tmp));
if ( !state )
{
warning("malloc: %m");
return;
}
state->path = strdup(tmp_path);
if ( !state->path )
{
warning("malloc: %m");
free(state);
return;
}
state->dir = opendir(state->path);
if ( !state->dir )
{
warning("%s: %m", state->path);
free(state->path);
free(state);
return;
}
while ( state )
{
if ( !state->entries )
{
state->num_entries = dscandir_r(state->dir, &state->entries,
no_dot_nor_dot_dot, NULL,
alphasort_r, NULL);
if ( state->num_entries < 0 )
warning("%s: %m", state->path);
}
if ( state->num_entries <= state->current_entry )
{
closedir(state->dir);
for ( int i = 0; i < state->num_entries; i++ )
free(state->entries[i]);
free(state->entries);
free(state->path);
struct clean_tmp* new_state = state->parent;
free(state);
state = new_state;
if ( state )
{
struct dirent* entry = state->entries[state->current_entry];
const char* name = entry->d_name;
int fd = dirfd(state->dir);
if ( unlinkat(fd, name, AT_REMOVEDIR) < 0 )
warning("%s/%s: %m", state->path, name);
state->current_entry++;
}
continue;
}
struct dirent* entry = state->entries[state->current_entry];
const char* name = entry->d_name;
int fd = dirfd(state->dir);
if ( unlinkat(fd, name, AT_REMOVEFILE | AT_REMOVEDIR) < 0 )
{
if ( errno == ENOTEMPTY )
{
struct clean_tmp* new_state =
calloc(1, sizeof(struct clean_tmp));
if ( !new_state )
{
warning("%s/%s: malloc: %m", state->path, name);
state->current_entry++;
continue;
}
new_state->path = join_paths(state->path, name);
if ( !new_state->path )
{
warning("%s/%s: malloc: %m", state->path, name);
free(new_state);
state->current_entry++;
continue;
}
int flags = O_DIRECTORY | O_RDONLY | O_NOFOLLOW;
int newfd = openat(fd, new_state->path, flags);
if ( newfd < 0 )
{
warning("%s: %m", new_state->path);
free(new_state->path);
free(new_state);
state->current_entry++;
continue;
}
new_state->dir = fdopendir(newfd);
if ( !new_state->dir )
{
warning("%s: %m", new_state->path);
close(newfd);
free(new_state->path);
free(new_state);
state->current_entry++;
continue;
}
new_state->parent = state;
state = new_state;
continue;
}
else
warning("%s/%s: %m", state->path, name);
}
state->current_entry++;
}
}
static void init_early(void) static void init_early(void)
{ {
static bool done = false; static bool done = false;
@ -548,6 +673,7 @@ static void init_early(void)
// Make sure that we have a /tmp directory. // Make sure that we have a /tmp directory.
umask(0000); umask(0000);
mkdir("/tmp", 01777); mkdir("/tmp", 01777);
clean_tmp();
// Set the default file creation mask. // Set the default file creation mask.
umask(0022); umask(0022);