mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-27 23:08:31 +00:00
Make build hermetically sealed again
It turned out that Landlock Make hasn't been applying sandboxing for a while, due to a mistyped if statement for `$(USE_SYSTEM_TOOLCHAIN)` it should have had the opposite meaning. Regressions in the build configs have been fixed. The rmrf() function works better now. The rm.com tool works according to POSIX with the exception of supporting prompts.
This commit is contained in:
parent
0c43c98de1
commit
a75175fe94
14 changed files with 202 additions and 93 deletions
|
@ -17,13 +17,17 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/magnumstrs.internal.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/ok.h"
|
||||
#include "libc/sysv/consts/s.h"
|
||||
#include "third_party/getopt/getopt.internal.h"
|
||||
#include "third_party/musl/ftw.h"
|
||||
|
||||
#define USAGE \
|
||||
" FILE...\n\
|
||||
|
@ -34,11 +38,15 @@ SYNOPSIS\n\
|
|||
\n\
|
||||
FLAGS\n\
|
||||
\n\
|
||||
-h help\n\
|
||||
-f force\n\
|
||||
-h help\n\
|
||||
-f force\n\
|
||||
-f or -R recursive\n\
|
||||
-d remove empty dirs\n\
|
||||
\n"
|
||||
|
||||
static bool force;
|
||||
static bool recursive;
|
||||
static bool doemptydirs;
|
||||
static const char *prog;
|
||||
|
||||
static wontreturn void PrintUsage(int rc, int fd) {
|
||||
|
@ -48,11 +56,18 @@ static wontreturn void PrintUsage(int rc, int fd) {
|
|||
|
||||
static void GetOpts(int argc, char *argv[]) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "hf")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "rRdhf")) != -1) {
|
||||
switch (opt) {
|
||||
case 'f':
|
||||
force = true;
|
||||
break;
|
||||
case 'd':
|
||||
doemptydirs = true;
|
||||
break;
|
||||
case 'r':
|
||||
case 'R':
|
||||
recursive = true;
|
||||
break;
|
||||
case 'h':
|
||||
PrintUsage(0, 1);
|
||||
default:
|
||||
|
@ -61,12 +76,56 @@ static void GetOpts(int argc, char *argv[]) {
|
|||
}
|
||||
}
|
||||
|
||||
static void Remove(const char *path) {
|
||||
if (!force && access(path, W_OK) == -1) {
|
||||
perror(path);
|
||||
static int OnFile(const char *fpath, const struct stat *st, int typeflag,
|
||||
struct FTW *ftwbuf) {
|
||||
int rc;
|
||||
if (!force && typeflag == FTW_DNR) {
|
||||
rc = -1;
|
||||
} else if (!force && !S_ISLNK(st->st_mode) && access(fpath, W_OK)) {
|
||||
rc = -1;
|
||||
} else if (typeflag == FTW_DNR) {
|
||||
if (!(rc = chmod(fpath, 0700))) {
|
||||
rc = nftw(fpath, OnFile, 128 - ftwbuf->level, FTW_PHYS | FTW_DEPTH);
|
||||
}
|
||||
} else if (typeflag == FTW_DP) {
|
||||
rc = rmdir(fpath);
|
||||
} else {
|
||||
rc = unlink(fpath);
|
||||
}
|
||||
if (rc == -1) {
|
||||
if (force && errno == ENOENT) return 0;
|
||||
perror(fpath);
|
||||
exit(1);
|
||||
}
|
||||
if (unlink(path) == -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void Remove(const char *path) {
|
||||
int rc;
|
||||
struct stat st;
|
||||
if (path[0] == '/' && !path[1]) {
|
||||
tinyprint(2, prog, ": add a dot if you want\n", NULL);
|
||||
exit(1);
|
||||
}
|
||||
if (recursive) {
|
||||
rc = nftw(path, OnFile, 128, FTW_PHYS | FTW_DEPTH);
|
||||
} else {
|
||||
if (lstat(path, &st)) {
|
||||
if (force && errno == ENOENT) return;
|
||||
perror(path);
|
||||
exit(1);
|
||||
}
|
||||
if (!force && !S_ISLNK(st.st_mode) && access(path, W_OK)) {
|
||||
perror(path);
|
||||
exit(1);
|
||||
}
|
||||
if (S_ISDIR(st.st_mode) && doemptydirs) {
|
||||
rc = rmdir(path);
|
||||
} else {
|
||||
rc = unlink(path);
|
||||
}
|
||||
}
|
||||
if (rc == -1) {
|
||||
if (force && errno == ENOENT) return;
|
||||
perror(path);
|
||||
exit(1);
|
||||
|
@ -75,17 +134,13 @@ static void Remove(const char *path) {
|
|||
|
||||
int main(int argc, char *argv[]) {
|
||||
int i;
|
||||
|
||||
prog = argv[0];
|
||||
if (!prog) prog = "rm";
|
||||
|
||||
if (argc < 2) {
|
||||
GetOpts(argc, argv);
|
||||
if (optind == argc) {
|
||||
tinyprint(2, prog, ": missing operand\n", NULL);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
GetOpts(argc, argv);
|
||||
|
||||
for (i = optind; i < argc; ++i) {
|
||||
Remove(argv[i]);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue