Implement internal commands, clean up a bit
This commit is contained in:
parent
360cf24ae2
commit
df27b4f66c
13
src/common.h
13
src/common.h
@ -1,13 +0,0 @@
|
|||||||
#ifndef COMMON_H
|
|
||||||
#define COMMON_H
|
|
||||||
|
|
||||||
|
|
||||||
#define CONCAT(x,y) _CONCAT(x,y)
|
|
||||||
#define _CONCAT(x,y) (x##y)
|
|
||||||
|
|
||||||
|
|
||||||
#define TOSTR(x) _TOSTR(x)
|
|
||||||
#define _TOSTR(x) (#x)
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* COMMON_H */
|
|
156
src/icmd.c
156
src/icmd.c
@ -1,68 +1,172 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include "icmd.h"
|
#include "icmd.h"
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define ICMDS_SIZE \
|
#define ICMDS_SIZE \
|
||||||
(sizeof(g_icmds) / sizeof(g_icmds[0]))
|
(sizeof(g_icmds) / sizeof(g_icmds[0])) \
|
||||||
|
|
||||||
|
|
||||||
#define ICMD(name) \
|
#define ICMD(name) \
|
||||||
{ \
|
{ \
|
||||||
.cmd = TOSTR(name), \
|
.cmd = #name, \
|
||||||
.len = sizeof(TOSTR(name))-1, \
|
.len = sizeof(#name) - 1, \
|
||||||
.func = CONCAT(icmd_, name), \
|
.func = icmd_##name, \
|
||||||
}
|
} \
|
||||||
|
|
||||||
|
|
||||||
struct icmd g_icmds[] =
|
struct icmd
|
||||||
{
|
{
|
||||||
|
char *cmd;
|
||||||
|
int len;
|
||||||
|
int (*func)(int, char **);
|
||||||
|
|
||||||
|
} g_icmds[] =
|
||||||
|
{
|
||||||
|
ICMD(help),
|
||||||
ICMD(exit),
|
ICMD(exit),
|
||||||
|
ICMD(cls),
|
||||||
ICMD(cd),
|
ICMD(cd),
|
||||||
ICMD(ls),
|
ICMD(ls),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define icmd_die(status, ...) \
|
||||||
|
{ \
|
||||||
|
_icmd_die(status, argv[0], __VA_ARGS__); \
|
||||||
|
return status; \
|
||||||
|
} \
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
_icmd_die(int status, char *func, char *format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, format);
|
||||||
|
if (status != 0)
|
||||||
|
printf("%s: Error: ", func);
|
||||||
|
vprintf(format, args);
|
||||||
|
if (status != 0)
|
||||||
|
putchar('!');
|
||||||
|
putchar('\n');
|
||||||
|
if (status < 0)
|
||||||
|
perror("Reason");
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
call_icmds(char *line)
|
call_icmd(int argc, char **argv)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < ICMDS_SIZE; i++)
|
for (i = 0; i < ICMDS_SIZE; i++)
|
||||||
{
|
if (strncmp(g_icmds[i].cmd, argv[0], g_icmds[i].len) == 0)
|
||||||
printf("cmp: '%s' : '%s' with len %d \n", g_icmds[i].cmd, line, g_icmds[i].len);
|
return g_icmds[i].func(argc, argv);
|
||||||
if (strncmp(g_icmds[i].cmd, line, g_icmds[i].len) == 0)
|
|
||||||
return g_icmds[i].func(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* todo: find better way to signal this? */
|
|
||||||
/* maybe return function pointer? */
|
|
||||||
return INT_MAX;
|
return INT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
icmd_exit(char *line)
|
icmd_help(int argc, char **argv)
|
||||||
{
|
{
|
||||||
printf("exiting with reason: %s", line);
|
size_t i;
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
puts(
|
||||||
|
"\n psh - poor man's shell"
|
||||||
|
"\n "
|
||||||
|
"\n internal commands: "
|
||||||
|
);
|
||||||
|
|
||||||
|
for (i = 0; i < ICMDS_SIZE; i++)
|
||||||
|
printf(" - %s\n", g_icmds[i].cmd);
|
||||||
|
|
||||||
|
putchar('\n');
|
||||||
|
|
||||||
int
|
|
||||||
icmd_cd(char *line)
|
|
||||||
{
|
|
||||||
printf("I'm a cd! line: %s\n", line);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
icmd_ls(char *line)
|
icmd_exit(int argc, char **argv)
|
||||||
{
|
{
|
||||||
printf("I'm a ls! line: %s\n", line);
|
puts("good bye!");
|
||||||
return 1;
|
exit(0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
icmd_cls(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i = 24;
|
||||||
|
|
||||||
|
while (i--)
|
||||||
|
putchar('\n');
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
icmd_cd(int argc, char **argv)
|
||||||
|
{
|
||||||
|
char def_path[] = ".";
|
||||||
|
char *path = def_path;
|
||||||
|
|
||||||
|
if (argc > 2)
|
||||||
|
icmd_die(1, "too many arguments given");
|
||||||
|
|
||||||
|
if (argc == 2)
|
||||||
|
path = argv[1];
|
||||||
|
|
||||||
|
if (chdir(path))
|
||||||
|
icmd_die(-1, "could not change directory");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
icmd_ls(int argc, char **argv)
|
||||||
|
{
|
||||||
|
char def_path[] = ".";
|
||||||
|
char *path = def_path;
|
||||||
|
struct dirent *d;
|
||||||
|
DIR *dir;
|
||||||
|
int i = 1;
|
||||||
|
|
||||||
|
if (argc > 1)
|
||||||
|
path = argv[1];
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if ((dir = opendir(path)) == NULL)
|
||||||
|
icmd_die(-1, "could not open directory '%s'", path);
|
||||||
|
|
||||||
|
puts(path);
|
||||||
|
while ((d = readdir(dir)) != NULL)
|
||||||
|
/* don't print current directory '.' and parent directory '..' */
|
||||||
|
if (!(d->d_name[0] == '.' && (d->d_name[1] == '\0' || d->d_name[1] == '.')))
|
||||||
|
printf(" %s\n", d->d_name);
|
||||||
|
|
||||||
|
closedir(dir);
|
||||||
|
putchar('\n');
|
||||||
|
path = argv[++i];
|
||||||
|
|
||||||
|
} while (i < argc);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
22
src/icmd.h
22
src/icmd.h
@ -2,22 +2,16 @@
|
|||||||
#define ICMD_H
|
#define ICMD_H
|
||||||
|
|
||||||
|
|
||||||
struct icmd
|
/* API */
|
||||||
{
|
int call_icmd(int argc, char **argv);
|
||||||
char *cmd;
|
|
||||||
int len;
|
|
||||||
int (*func)(char *);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* interface */
|
/* internal commands */
|
||||||
int call_icmds(char *line);
|
int icmd_help(int argc, char **argv);
|
||||||
|
int icmd_exit(int argc, char **argv);
|
||||||
|
int icmd_cls(int argc, char **argv);
|
||||||
/* internal commands as functions */
|
int icmd_cd(int argc, char **argv);
|
||||||
int icmd_exit(char *line);
|
int icmd_ls(int argc, char **argv);
|
||||||
int icmd_cd(char *line);
|
|
||||||
int icmd_ls(char *line);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* ICMD_H */
|
#endif /* ICMD_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user