view toys/toysh.c @ 2:67b517913e56

Infrastructure, first drop of toy shell, and a bit of work on df.
author landley@driftwood
date Thu, 05 Oct 2006 16:18:03 -0400
parents
children 266a462ed18c
line wrap: on
line source

/* vi: set sw=4 ts=4:
 * 
 * toysh - toybox shell
 *
 * Copyright 2006 Rob Landley <rob@landley.net>
 *
 * The spec for this is at:
 * http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
 *
 * Although things like the bash man page are good to read too.
 */

// Handle embedded NUL bytes in the command line.

#include "toys.h"

static int handle(char *command)
{
	int argc = 0, status;
	char *argv[10], *start = command;
	pid_t pid;
	struct toy_list *tl;

	// Parse command into argv[]
	for (;;) {
		char *end;

		// Skip leading whitespace and detect EOL.
		while(isspace(*start)) start++;
		if (!*start || *start=='#') break;

		// Grab next word.  (Add dequote and envvar logic here)
		end = start;
		while (*end && !isspace(*end)) end++;
		argv[argc++] = xstrndup(start, end-start);
		start=end;
	}
	argv[argc]=0;

	if (!argc) return 0;

	tl = toy_find(argv[0]);
	// This is a bit awkward, next design cycle should clean it up.
	// Should vfork(), move to tryspawn()?
	pid = 0;
	if (tl && (tl->flags & TOYFLAG_NOFORK))
		status = tl->toy_main();
	else {
		pid=fork();
		if(!pid) {
			toy_exec(argv);
			xexec(argv);
		} else waitpid(pid, &status, 0);
	}
	while(argc) free(argv[--argc]);

	return 0;
}

int cd_main(void)
{
	char *dest = toys.argc>1 ? toys.argv[1] : getenv("HOME");
	if (chdir(dest)) error_exit("chdir %s",dest);
	return 0;
}

int exit_main(void)
{	
	exit(toys.argc>1 ? atoi(toys.argv[1]) : 0);
}

int toysh_main(void)
{
	char *command=NULL;
	FILE *f;

	// TODO get_optflags(argv, "c:", &command);

	f = toys.argv[1] ? xfopen(toys.argv[1], "r") : NULL;
	if (command) handle(command);
	else {
		unsigned cmdlen=0;
		for (;;) {
			if (!f) putchar('$');
			if (1 > getline(&command, &cmdlen, f ? : stdin)) break;
			handle(command);
		}
		if (CFG_TOYS_FREE) free(command);
	}
		
	return 1;
}