do not edit — generated by btf.
git.druid.rocksindexdruid520kaboomsrc/user/ls.nsc

src/user/ls.nsc


include "syscalls.nsh";
include "lib.nsh";
include "string.nsh";
include "stdio.nsh";
 
void
print_names(ptr names, i32 count)
{
	i32 i;
	ptr entry;
 
	i = 0;
	while(i < count)
	{
		/* puts, not a hand-rolled 24-byte-capped length scan -- safe
		 * because every kfs dirent name is guaranteed null-terminated
		 * within its 24-byte field (kfs_name_matches on the kernel
		 * side refuses any name over 23 bytes in the first place), so
		 * puts's own byte-at-a-time scan for the terminator never
		 * reads into the next entry. */
		entry = names + (u64)i * (u64)24;
		puts(entry);
		putchar((u8)10);
		i = i + 1;
	}
}
 
/* with no argument, lists the cwd (the only thing this ever did
 * before). with one, "ls name" or "ls /a/b" -- resolves the argument
 * as a real path (kfs_resolve, by way of sys_stat/sys_listdir_path,
 * handles both a bare relative name and a real multi-component or
 * absolute path) and either lists it (a directory) or just prints
 * its own name back (a file, matching real ls's own behavior on a
 * file argument). "ls doc" (a subdirectory of cwd) previously did
 * nothing useful at all -- this argument handling never existed. */
global i32
main(i32 argc, ptr argv)
{
	i8 names[1536]; /* 64 entries * 24 bytes -- directories can chain
	                  * past 15 entries/block now (see kfs.nsc's
	                  * kfs_dir_next_block), so 16 stopped being a
	                  * real ceiling the moment /bin itself grew past
	                  * it. 64 is comfortably past anything real yet. */
	i32 count;
	ptr path;
	u64 path_len;
	i64 kind;
 
	if(argc < 2)
	{
		count = sys_listdir(&names[0], 64);
		if(count < 0)
		{
			print_err(2, "ls", "listing failed");
			return 1;
		}
		print_names(&names[0], count);
		stdio_flush();
		return 0;
	}
 
	path = argv_get(argv, 1);
	path_len = strlen(path);
	kind = sys_stat(path, path_len);
 
	if(kind == (i64)1) /* a file: print its own name, like real ls */
	{
		puts(path);
		putchar((u8)10);
		stdio_flush();
		return 0;
	}
	if(kind == (i64)2) /* a directory: list it */
	{
		count = sys_listdir_path(path, path_len, &names[0], 64);
		if(count < 0)
		{
			print_err(2, "ls", "listing failed");
			return 1;
		}
		print_names(&names[0], count);
		stdio_flush();
		return 0;
	}
 
	print_err(2, "ls", "not found");
	return 1;
}
powered by btf.