/* Placed in the public domain 2009 by Sam Trenholme */
/* Yash: A usable command shell in under 4k (yet another shell)
*
* This is a simple thought experiment: How small can we make a *NIX command
* line shell? This is as simple as it gets; it will run a command typed
* in if it's an external command like "ls" or "cc", with arguments separated
* by space; if one types in "-cd {directory}", it will go to that directory.
*
* CNTL-C exits the shell
*
* BUGS: CNTL-D reruns the previous command instead of exiting the shell.
*/
#define LINEMAX 80
#define ARGMAX 16
#include <stdio.h>
#include <unistd.h>
/* Given a pointer to arguments, destroy the string */
void yash_zap_args(char **zap) {
int a = 0;
if(zap == 0) {
return;
}
for(a = 0; a < ARGMAX; a++) {
if(zap[a] != 0) {
free(zap[a]);
zap[a] = 0;
}
}
free(zap);
}
/* Given a line separated by whitespace, return an array of strings
* of the individual arguments */
char **yash_args(char *in) {
char **out = 0;
int a = 0, b = 0;
/* Sanity checks */
if(in == 0) {
return 0;
}
out = malloc(ARGMAX * sizeof(char *));
for(a = 0; a < ARGMAX; a++) {
out[a] = 0;
}
a = 0;
if(out == 0) {
return 0;
}
while(*in != 0) {
if(*in != ' ' && *in != '\n') {
if((out[a] = malloc(LINEMAX)) == 0) {
goto catch_yash_args;
}
b = 0;
while(b < LINEMAX - 2 && *in != ' ' && *in != 0 &&
*in != '\n') {
out[a][b] = *in;
b++;
in++;
}
out[a][b] = 0;
a++;
if(a >= ARGMAX) {
goto catch_yash_args;
}
}
in++;
}
return out;
catch_yash_args:
yash_zap_args(out);
return 0;
}
/* Meta commands for yash; right now this is just the cd command */
void yash_meta(char **args) {
if(args == 0 || args[0] == 0) {
return;
}
if(args[0][1] == 'c' && args[0][2] == 'd') {
if(args[1] == 0) {
chdir("/"); /* Should be $HOME, isn't */
} else {
chdir(args[1]);
}
return;
}
}
main() {
char in[LINEMAX], **args = 0;
for(;;) {
printf("$ ");
fgets(in,LINEMAX,stdin);
args = yash_args(in);
if(args != 0 && args[0] != 0) {
if(*args[0] == '-') {
yash_meta(args);
}
else if(fork()) {
wait(0);
} else {
execvp(args[0],args);
printf("Command not found\n");
exit(-1);
}
}
yash_zap_args(args);
}
}
源自:http://samiam.org/software/yash.html