Permalink
Browse files

Looks like 'ls' is starting to work. Touch seems to work so far as well.

  • Loading branch information...
imnotlistening committed Nov 1, 2010
1 parent dd97a48 commit b3ae7c368eb3d2f49620a355c70ef7410d2543f9
Showing with 315 additions and 39 deletions.
  1. +10 −0 include/builtin.h
  2. +9 −0 include/rshio.h
  3. +161 −17 src/builtin.c
  4. +9 −0 src/fat16test.c
  5. +47 −9 src/fs.c
  6. +25 −6 src/fs_fat16.c
  7. +2 −2 src/main.c
  8. +29 −4 src/rshio.c
  9. +23 −1 src/shell_start.c
View
@@ -5,6 +5,8 @@
#ifndef _BUILTIN_H
#define _BUILTIN_H
+#include <rshio.h>
+
/* A typedef for builtin functions. */
typedef int (* builtin_func)(int argc, char **argv, int in, int out, int err);
@@ -19,4 +21,12 @@ struct builtin {
/* Some ease of use functions. */
struct builtin *rsh_identify_builtin(char *command);
+/* Use this macro to close all file descriptors passed to a built in. */
+#define RSH_BUILTIN_CLOSE(fd) \
+ do { \
+ if ( fd > 2 ) \
+ close(fd); \
+ } while (0)
+
+
#endif
View
@@ -26,6 +26,15 @@
#include <sys/types.h>
+/*
+ * This assumes two things: 1) native file descriptors are at least 16 bits
+ * wide, and 2) that the shell will not use more than 32768 native file
+ * descriptors (this seems fairly reasonable).
+ */
+#define _RSH_FD_OFFSET 0x8000
+#define _RSH_FD(fd) ( fd & _RSH_FD_OFFSET )
+#define _RSH_FD_TO_INDEX(fd) ( fd & ~_RSH_FD_OFFSET )
+
/* Definitions for RSH's version of the necessary I/O sys calls. */
ssize_t rsh_read(int fd, void *buf, size_t count);
ssize_t rsh_write(int fd, const void *buf, size_t count);
View
@@ -17,9 +17,13 @@
#include <symbol_table.h>
#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
+#include <signal.h>
+#include <sys/wait.h>
/* Prototypes for the builtins. */
int builtin_cd(int argc, char **argv, int in, int out, int err);
@@ -291,10 +295,14 @@ int builtin_xfer(int argc, char **argv, int in, int out, int err){
char buf[128];
while ( (bytes = rsh_read(in, buf, 127)) > 0 ){
- buf[127] = 0;
+ buf[bytes] = 0;
rsh_dprintf(out, "%s", buf);
}
+ RSH_BUILTIN_CLOSE(in);
+ RSH_BUILTIN_CLOSE(out);
+ RSH_BUILTIN_CLOSE(err);
+
return 0;
}
@@ -308,65 +316,201 @@ extern struct rsh_file_system fs;
extern char *rsh_cwd;
int builtin_dfs(int argc, char **argv, int in, int out, int err){
- printf("CWD: %s\n", rsh_cwd);
- printf("FS info:\n");
- printf(" ftable addr: 0x%016lx\n", (long unsigned int)fs.ftable);
- printf(" ftable length: %d, used %d\n", fs.ft_length, fs.used);
- printf(" File ops:\n");
- printf(" read: 0x%016lx\n", (long unsigned int)fs.fops->read);
- printf(" write: 0x%016lx\n", (long unsigned int)fs.fops->write);
- printf(" open: 0x%016lx\n", (long unsigned int)fs.fops->open);
- printf(" close: 0x%016lx\n", (long unsigned int)fs.fops->close);
+ rsh_dprintf(out, "CWD: %s\n", rsh_cwd);
+ rsh_dprintf(out, "FS info:\n");
+ rsh_dprintf(out, " ftable addr: 0x%016lx\n", (long unsigned int)fs.ftable);
+ rsh_dprintf(out, " ftable length: %d, used %d\n", fs.ft_length, fs.used);
+ rsh_dprintf(out, " File ops:\n");
+ rsh_dprintf(out, " read: 0x%016lx\n", (long unsigned int)fs.fops->read);
+ rsh_dprintf(out, " write: 0x%016lx\n", (long unsigned int)fs.fops->write);
+ rsh_dprintf(out, " open: 0x%016lx\n", (long unsigned int)fs.fops->open);
+ rsh_dprintf(out, " close: 0x%016lx\n", (long unsigned int)fs.fops->close);
+
+ RSH_BUILTIN_CLOSE(in);
+ RSH_BUILTIN_CLOSE(out);
+ RSH_BUILTIN_CLOSE(err);
return 0;
}
extern int native;
+/*
+ * Run a command natively. This deliberatly by passes rsh_exec() since we do
+ * not want to call rsh_exec() when we should be running in context of the
+ * shell. This will do a waitpid while the process runs. It is roughly
+ * equivalent to the system() library routine.
+ */
+int _native_command(int argc, char **argv, int in, int out, int err){
+
+ int ret;
+ int status;
+ pid_t pid;
+
+ pid = fork();
+
+ if ( pid < 0 ){
+ perror("fork");
+ return -1;
+ }
+
+ /* Parent. */
+ if ( pid ){
+ ret = waitpid(pid, &status, 0);
+ if ( ret < 0 ){
+ perror("waitpid");
+ return -1;
+ }
+ return WEXITSTATUS(status);
+ }
+
+ /* We are the child. */
+ if ( dup2(in, STDIN_FILENO) < 0 ){
+ perror("dup()");
+ return RSH_ERR;
+ }
+
+ if ( dup2(out, STDOUT_FILENO) < 0 ){
+ perror("dup()");
+ return RSH_ERR;
+ }
+
+ if ( dup2(err, STDERR_FILENO) < 0 ){
+ perror("dup()");
+ return RSH_ERR;
+ }
+
+ /* Reset signal handlers. */
+ signal(SIGINT, SIG_DFL);
+ signal(SIGQUIT, SIG_DFL);
+ signal(SIGTSTP, SIG_DFL);
+ signal(SIGTTIN, SIG_DFL);
+ signal(SIGTTOU, SIG_DFL);
+
+ /* Now do the exec. Use execve so we don't have to do PATH searching, instead
+ * let libc do that for us. */
+ fsync(STDOUT_FILENO);
+ err = execvp(*argv, argv);
+ if ( err ){
+ perror("exec");
+ }
+ exit(1);
+
+}
+
int builtin_cp(int argc, char **argv, int in, int out, int err){
+ printf("builtin: %s\n", *argv);
+
+ if ( native ){
+ return _native_command(argc, argv, in, out, err);
+ }
+
return 0;
}
int builtin_mv(int argc, char **argv, int in, int out, int err){
+ printf("builtin: %s\n", *argv);
+
+ if ( native ){
+ return _native_command(argc, argv, in, out, err);
+ }
+
return 0;
}
int builtin_ls(int argc, char **argv, int in, int out, int err){
- int no_pipe[2];
+ int dfd;
- printf("in: %d\n", in);
- printf("out: %d\n", out);
- printf("err: %d\n", err);
+ printf("builtin: %s\n", *argv);
if ( native ){
- return rsh_exec(*argv, argc, argv, in, out, err,
- 0, RSH_PIPE_NONE, no_pipe);
+ _native_command(argc, argv, in, out, err);
+ goto cleanup;
}
+ argc--;
+ argv++;
+
/* Otherwise, we have to do this ourselves. */
+ if ( ! *argv )
+ dfd = rsh_open(".", 0, 0);
+ else
+ dfd = rsh_open(*argv, 0, 0);
+
+ if ( dfd < 0 ){
+ perror("open");
+ return 1;
+ }
+
+ struct dirent *dirent;
+ while ( (dirent = rsh_readdir(dfd)) != NULL ){
+ printf("> name: %s\n", dirent->d_name);
+ }
+ if ( errno ){
+ perror("_rsh_readdir");
+ return 1;
+ }
- printf("Closing FDs\n");
+ cleanup:
RSH_BUILTIN_CLOSE(in);
RSH_BUILTIN_CLOSE(out);
RSH_BUILTIN_CLOSE(err);
+
return 0;
}
+/*
+ * Basically just open and close a file. Not hard really.
+ */
int builtin_touch(int argc, char **argv, int in, int out, int err){
+ int fd;
+
+ printf("builtin: %s\n", *argv);
+
+ if ( native ){
+ _native_command(argc, argv, in, out, err);
+ goto cleanup;
+ }
+
+ /* Ignore the name of the calling function... We already know it. */
+ argc--;
+ argv++;
+
+ /* The magic happens here. */
+ rsh_dprintf(out, "Touching file: %s\n", *argv);
+ fd = rsh_open(*argv, O_CREAT, 0);
+ if ( fd < 0 ){
+ perror("rsh_open");
+ return 1;
+ }
+
+ rsh_close(fd);
+
+ cleanup:
+ RSH_BUILTIN_CLOSE(in);
+ RSH_BUILTIN_CLOSE(out);
+ RSH_BUILTIN_CLOSE(err);
+
return 0;
}
int builtin_rm(int argc, char **argv, int in, int out, int err){
+ printf("builtin: %s\n", *argv);
+
+ if ( native ){
+ _native_command(argc, argv, in, out, err);
+ }
+
return 0;
}
View
@@ -14,6 +14,7 @@
#include <unistd.h>
#include <sys/stat.h>
+extern char *_rsh_fat16_split_path(char *path, char **name);
extern int builtin_fatinfo(int argc, char **argv, int in, int out, int err);
extern int rsh_fat16_open(struct rsh_file *file,
@@ -27,6 +28,7 @@ extern void _rsh_fat16_display_path_dir(const char *path);
extern struct dirent *_rsh_readdir(int dfd);
extern int _rsh_open(const char *path, int flags, mode_t mode);
+
int main(){
int err;
@@ -63,6 +65,13 @@ int main(){
printf(" %s\n", node);
*/
+ char *name;
+ char *a_path = "h/.";
+ a_path[0] = 'k';
+ char *a_dir = _rsh_fat16_split_path(a_path, &name);
+ printf("dir='%s' name='%s'\n", a_dir, name);
+ return 0;
+
/* Now we can traverse a path by looking at directory tables and stuff. */
struct rsh_fat_dirent ent;
int errcode = _rsh_fat16_path_to_dirent(path, &ent, NULL);
Oops, something went wrong.

0 comments on commit b3ae7c3

Please sign in to comment.