~rabbits/public-inbox

Update file_stat to match the existing documentation. v1 PROPOSED

d6: 1
 Update file_stat to match the existing documentation.

 1 files changed, 29 insertions(+), 6 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~rabbits/public-inbox/patches/55104/mbox | git am -3
Learn more about email & git

[PATCH] Update file_stat to match the existing documentation. Export this patch

From: d_m <d_m@plastic-idolatry.com>

Previously, writing to the stat port would produce a line of text
similar to the listing used when reading a directory. This did not
match the documentation around the stat port.

After the change, writing an address to the stat port will fill that
address with bytes equal to the length parameter. These will either be
a hexadecimal file size, or else the same character repeated N times
according to the following logic:

 - path is a directory
 ? file size of path does not fit in N hexadecimal characters
 ! path is not readable

Note that unlike when reading a directory, the string will not include
the requested path, a newline, or a null terminator.
---
 src/devices/file.c | 35 +++++++++++++++++++++++++++++------
 1 file changed, 29 insertions(+), 6 deletions(-)

diff --git a/src/devices/file.c b/src/devices/file.c
index a7487d4..56a1baf 100644
--- a/src/devices/file.c
+++ b/src/devices/file.c
@@ -267,16 +267,39 @@ file_write(UxnFile *c, void *src, Uint16 len, Uint8 flags)
	return ret;
}

static Uint16
stat_fill(Uint8 *dest, Uint16 len, char c)
{
	Uint16 i;
	for (i = 0; i < len; i++)
		*(dest++) = c;
	return len;
}

static Uint16
stat_size(Uint8 *dest, Uint16 len, off_t size)
{
	Uint16 i;
	dest += len - 1;
	for (i = 0; i < len; i++) {
		*(dest--) = '0' + (Uint8)(size & 0xf);
		size = size >> 4;
	}
	return size == 0 ? len : stat_fill(dest, len, '?');
}

static Uint16
file_stat(UxnFile *c, void *dest, Uint16 len)
{
	char *basename = strrchr(c->current_filename, DIR_SEP_CHAR);
	if(c->outside_sandbox) return 0;
	if(basename != NULL)
		basename++;
	struct stat st;
	if(c->outside_sandbox)
		return 0;
	else if(stat(c->current_filename, &st))
		return stat_fill(dest, len, '!');
	else if(S_ISDIR(st.st_mode))
		return stat_fill(dest, len, '-');
	else
		basename = c->current_filename;
	return get_entry(dest, len, c->current_filename, basename, 0);
		return stat_size(dest, len, st.st_size);
}

static Uint16
-- 
2.39.2