fs Fetch file contents
This commit is contained in:
@ -1,2 +1,3 @@
|
||||
mkalias pctl base:/bin/pctl
|
||||
mkalias tb base:/bin/tb
|
||||
mkalias fs base:/bin/fs
|
||||
|
@ -30,4 +30,6 @@ typedef struct IoctlStat {
|
||||
int32_t type;
|
||||
} IoctlStat;
|
||||
|
||||
typedef int32_t IOH;
|
||||
|
||||
#endif // SHARE_SYSDEFS_IOCTL_H_
|
||||
|
@ -157,3 +157,34 @@ long string_conv_strtol(const char *nptr, char **endptr, int base)
|
||||
*endptr = (char *) (any ? s - 1 : nptr);
|
||||
return (acc);
|
||||
}
|
||||
|
||||
const char *human_size(uint64_t bytes, char *buf, size_t bufsize) {
|
||||
static const char *units[] = { "B", "KiB", "MiB", "GiB", "TiB", "PiB" };
|
||||
int unit = 0;
|
||||
|
||||
// Scale down until value fits nicely
|
||||
uint64_t rem = 0;
|
||||
while (bytes >= 1024 && unit < (int)(sizeof(units)/sizeof(units[0])) - 1) {
|
||||
rem = bytes % 1024;
|
||||
bytes /= 1024;
|
||||
unit++;
|
||||
}
|
||||
|
||||
if (unit == 0) {
|
||||
// Just bytes
|
||||
usnprintf(buf, bufsize, "%llu %s", (unsigned long long)bytes, units[unit]);
|
||||
} else {
|
||||
// Show one decimal place without using floats
|
||||
// Multiply remainder by 10 to get first decimal digit
|
||||
uint64_t frac = (rem * 10 + 512) / 1024; // rounded
|
||||
if (frac == 10) { // handle carry, e.g. 1023.9 -> 1024.0
|
||||
bytes++;
|
||||
frac = 0;
|
||||
}
|
||||
|
||||
if (frac > 0) usnprintf(buf, bufsize, "%llu.%llu %s", (unsigned long long)bytes, (unsigned long long)frac, units[unit]);
|
||||
else usnprintf(buf, bufsize, "%llu %s", (unsigned long long)bytes, units[unit]);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
@ -3,5 +3,6 @@
|
||||
|
||||
unsigned long string_conv_strtoul(const char *nptr, char **endptr, int base);
|
||||
long string_conv_strtol(const char *nptr, char **endptr, int base);
|
||||
const char *human_size(uint64_t bytes, char *buf, size_t bufsize);
|
||||
|
||||
#endif // ULIB_STRING_CONV_H_
|
||||
|
2
user/fs/.gitignore
vendored
Normal file
2
user/fs/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*.o
|
||||
fs
|
24
user/fs/Makefile
Normal file
24
user/fs/Makefile
Normal file
@ -0,0 +1,24 @@
|
||||
include $(ROOT)/mk/grabsrc.mk
|
||||
include ../Makefile.inc
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
TARGET := fs
|
||||
|
||||
LDFLAGS += -L$(ROOT)/ulib -l:libulib.a
|
||||
|
||||
SRCFILES := $(call GRABSRC, .)
|
||||
CFILES := $(call GET_CFILES, $(SRCFILES))
|
||||
OBJ := $(call GET_OBJ, $(SRCFILES))
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJ)
|
||||
$(LD) $^ $(LDFLAGS) -o $@
|
||||
echo $$(realpath $(TARGET)) >> $(FILES)
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ) $(TARGET)
|
35
user/fs/fetch.c
Normal file
35
user/fs/fetch.c
Normal file
@ -0,0 +1,35 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <ulib.h>
|
||||
|
||||
void fs_fetch(void) {
|
||||
if (argslen() < 2) {
|
||||
uprintf("fs: Not enough arguments\n");
|
||||
return;
|
||||
}
|
||||
|
||||
char *path = *(args()+1);
|
||||
|
||||
IOH ioh = ioctl(IOCTL_NOHANDLE, IOCTL_OPENF, (uint64_t)path, IOCTL_F_READ, 0);
|
||||
if (ioh < 0) {
|
||||
uprintf("fs: could not open %s\n", path);
|
||||
return;
|
||||
}
|
||||
|
||||
IoctlStat statbuf; ZERO(&statbuf);
|
||||
|
||||
ioctl(ioh, IOCTL_STAT, (uint64_t)&statbuf, 0, 0);
|
||||
if (statbuf.type == IOCTLSTAT_FILE) {
|
||||
uint8_t *buf = umalloc(statbuf.size+1);
|
||||
string_memset(buf, 0, statbuf.size+1);
|
||||
|
||||
if (ioctl(ioh, IOCTL_READ, (uint64_t)buf, statbuf.size, 0) < 0) {
|
||||
uprintf("fs: coult not read %s\n", path);
|
||||
ufree(buf);
|
||||
ioctl(ioh, IOCTL_CLOSEF, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
uprintf("%s", buf);
|
||||
}
|
||||
}
|
19
user/fs/main.c
Normal file
19
user/fs/main.c
Normal file
@ -0,0 +1,19 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <ulib.h>
|
||||
|
||||
extern void fs_fetch(void);
|
||||
|
||||
void main(void) {
|
||||
if (argslen() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
char *cmd = args()[0];
|
||||
|
||||
if (string_strcmp(cmd, "fetch") == 0) {
|
||||
fs_fetch();
|
||||
} else {
|
||||
uprintf("fs: unknown command %s\n", cmd);
|
||||
}
|
||||
}
|
@ -18,38 +18,6 @@ static Arg ARGS[] = {
|
||||
ARG_END(),
|
||||
};
|
||||
|
||||
const char *human_size(uint64_t bytes, char *buf, size_t bufsize) {
|
||||
static const char *units[] = { "B", "KiB", "MiB", "GiB", "TiB", "PiB" };
|
||||
int unit = 0;
|
||||
|
||||
// Scale down until value fits nicely
|
||||
uint64_t rem = 0;
|
||||
while (bytes >= 1024 && unit < (int)(sizeof(units)/sizeof(units[0])) - 1) {
|
||||
rem = bytes % 1024;
|
||||
bytes /= 1024;
|
||||
unit++;
|
||||
}
|
||||
|
||||
if (unit == 0) {
|
||||
// Just bytes
|
||||
usnprintf(buf, bufsize, "%llu %s", (unsigned long long)bytes, units[unit]);
|
||||
} else {
|
||||
// Show one decimal place without using floats
|
||||
// Multiply remainder by 10 to get first decimal digit
|
||||
uint64_t frac = (rem * 10 + 512) / 1024; // rounded
|
||||
if (frac == 10) { // handle carry, e.g. 1023.9 -> 1024.0
|
||||
bytes++;
|
||||
frac = 0;
|
||||
}
|
||||
|
||||
if (frac > 0) usnprintf(buf, bufsize, "%llu.%llu %s", (unsigned long long)bytes, (unsigned long long)frac, units[unit]);
|
||||
else usnprintf(buf, bufsize, "%llu %s", (unsigned long long)bytes, units[unit]);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
void pctl_ls(void) {
|
||||
int32_t ret;
|
||||
if ((ret = parse_args(SUBCMD_ARGS(), SUBCMD_ARGSLEN(), ARGS)) < 0) {
|
||||
|
Reference in New Issue
Block a user