diff options
| author | Jacob McDonnell <jacob@jacobmcdonnell.com> | 2024-03-05 18:46:44 -0500 |
|---|---|---|
| committer | Jacob McDonnell <jacob@jacobmcdonnell.com> | 2024-03-05 18:46:44 -0500 |
| commit | c40f400f6ab879e08d54de753aabc987fd6ba07a (patch) | |
| tree | 295f95070362d14d987638b558ad6bb1ba2415e2 /src/cmd | |
| parent | e32262d86c90e2ac73b2c38a47a1bb6b60935098 (diff) | |
Added a simple shell, jsh
Diffstat (limited to 'src/cmd')
| -rw-r--r-- | src/cmd/.DS_Store | bin | 6148 -> 6148 bytes | |||
| -rwxr-xr-x | src/cmd/cat/cat.c | 54 | ||||
| -rwxr-xr-x | src/cmd/cat/makefile | 12 | ||||
| -rw-r--r-- | src/cmd/coin/coin.c | 37 | ||||
| -rwxr-xr-x[-rw-r--r--] | src/cmd/coin/makefile | 8 | ||||
| -rw-r--r-- | src/cmd/dice/dice.c | 2 | ||||
| -rwxr-xr-x[-rw-r--r--] | src/cmd/dice/makefile | 8 | ||||
| -rw-r--r-- | src/cmd/echo/echo.c | 2 | ||||
| -rwxr-xr-x[-rw-r--r--] | src/cmd/echo/makefile | 10 | ||||
| -rwxr-xr-x | src/cmd/jsh/README.md | 3 | ||||
| -rwxr-xr-x | src/cmd/jsh/jsh.c | 81 | ||||
| -rwxr-xr-x | src/cmd/jsh/makefile | 12 | ||||
| -rwxr-xr-x | src/cmd/ls/ls.c | 78 | ||||
| -rwxr-xr-x | src/cmd/ls/makefile | 12 | ||||
| -rw-r--r-- | src/cmd/makefile | 2 | ||||
| -rwxr-xr-x | src/cmd/pwd/makefile | 12 | ||||
| -rwxr-xr-x | src/cmd/pwd/pwd.c | 30 |
17 files changed, 330 insertions, 33 deletions
diff --git a/src/cmd/.DS_Store b/src/cmd/.DS_Store Binary files differindex ddbc73c..5047d2a 100644 --- a/src/cmd/.DS_Store +++ b/src/cmd/.DS_Store diff --git a/src/cmd/cat/cat.c b/src/cmd/cat/cat.c new file mode 100755 index 0000000..1c3e40a --- /dev/null +++ b/src/cmd/cat/cat.c @@ -0,0 +1,54 @@ +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <stdbool.h> + +void fileoutput(FILE *, const char *); +bool isdir(const char *); + +/* concatinate files to a file stream */ +int main(int argc, char **argv) +{ + FILE *fp; + if (argc == 1) { + fileoutput(stdin, "stdin"); + } else { + while (--argc > 0 && !ferror(stdout)) { + if (isdir(*++argv)) { + perror("cat"); + continue; + } + if ((fp = fopen(*argv, "r")) == NULL) { + perror("cat"); + continue; + } + fileoutput(fp, *argv); + } + } + if (ferror(stdout)) { + perror("cat"); + return -1; + } + return 0; +} + +/* fileoutput: output a file to stdout */ +void fileoutput(FILE *fp, const char *name) +{ + int c; + while ((c = getc(fp)) != EOF) + putc(c, stdout); + if (ferror(fp)) { + perror("cat"); + } + fclose(fp); +} + +/* isdir: return true if the file as the path is a directory */ +bool isdir(const char *path) +{ + struct stat sbuf; + stat(path, &sbuf); + return S_ISDIR(sbuf.st_mode); +} + diff --git a/src/cmd/cat/makefile b/src/cmd/cat/makefile new file mode 100755 index 0000000..bb8db9e --- /dev/null +++ b/src/cmd/cat/makefile @@ -0,0 +1,12 @@ +CFLAGS=-Wall -Werror + +build: cat + @cp cat $(PROROOT)/build/bin/cat + +cat: cat.c + $(CC) $(CFLAGS) -o cat cat.c + +clean: + @rm -r cat + +.PHONY: build clean diff --git a/src/cmd/coin/coin.c b/src/cmd/coin/coin.c index c18d66c..4471959 100644 --- a/src/cmd/coin/coin.c +++ b/src/cmd/coin/coin.c @@ -4,61 +4,58 @@ #include <string.h> #include <limits.h> -unsigned long coinFlip (unsigned long times); +int coinFlip (int times); int main (int argc, char *argv[]) { - int nflag = 0, i, mflag = 0; - unsigned long times = 1, tails, heads; + int nflag = 0, times = 1, i, tails, heads; + float ph, pt; argc--; for (i = 1; i <= argc; i++) { - if (strcmp(argv[i], "-n") == 0) + if (strcmp(argv[i], "-n") == 0) { nflag++; - else if (strcmp(argv[i], "-m") == 0) { - mflag++; + } else if (strcmp(argv[i], "-m") == 0) { + times = INT_MAX; break; - } else if (nflag == 1) + } else if (nflag == 1) { times = atoi(argv[i]); if (times == 0) { printf("Non Integer Value Inputted\n"); return -1; } + break; + } } - if (mflag == 1) - times = ULONG_MAX; - if (times == 1) printf("%s\n", coinFlip(times) ? "Heads" : "Tails"); else { tails = coinFlip(times); heads = times - tails; - float ph = (float)heads/times, pt = (float)tails/times; + ph = (float)heads/times; + pt = (float)tails/times; - printf("Heads: %lu\nTails: %ld\nProb Heads: %f\nProb Tails: %f\n", heads, tails, ph, pt); + printf("Heads: %d\nTails: %d\nProb Heads: %f\nProb Tails: %f\n", heads, tails, ph, pt); } return 0; } /* coinFlip: Flips a coin n numbers of times and returns the number of tails */ -unsigned long -coinFlip (unsigned long times) +int +coinFlip (int times) { - unsigned long tails, i; - int c; + int tails, i, c; time_t t; srand((unsigned) time(&t)); - tails = 0; - - for (i = 0; i < times; i++) { + for (i = tails = 0; i < times; i++) { c = rand() % 2; if (c == 1) tails++; } return tails; -}
\ No newline at end of file +} diff --git a/src/cmd/coin/makefile b/src/cmd/coin/makefile index cf8289d..7cd5d6e 100644..100755 --- a/src/cmd/coin/makefile +++ b/src/cmd/coin/makefile @@ -1,10 +1,12 @@ -all: coin +CFLAGS=-Wall -Werror + +build: coin @cp coin $(PROROOT)/build/bin/coin coin: coin.c - $(CC) -o coin coin.c + $(CC) $(CFLAGS) -o coin coin.c clean: @rm -r coin -.PHONY: all clean
\ No newline at end of file +.PHONY: build clean diff --git a/src/cmd/dice/dice.c b/src/cmd/dice/dice.c index f211d67..b31670f 100644 --- a/src/cmd/dice/dice.c +++ b/src/cmd/dice/dice.c @@ -12,4 +12,4 @@ main (void) printf("%d\n", (rand() % sides) + 1); return 0; -}
\ No newline at end of file +} diff --git a/src/cmd/dice/makefile b/src/cmd/dice/makefile index 5c0e384..2acc850 100644..100755 --- a/src/cmd/dice/makefile +++ b/src/cmd/dice/makefile @@ -1,10 +1,12 @@ -all: dice +CFLAGS=-Wall -Werror + +build: dice @cp dice $(PROROOT)/build/bin/dice dice: dice.c - $(CC) -o dice dice.c + $(CC) $(CFLAGS) -o dice dice.c clean: @rm -r dice -.PHONY: all clean
\ No newline at end of file +.PHONY: build clean diff --git a/src/cmd/echo/echo.c b/src/cmd/echo/echo.c index 3dc8334..4733830 100644 --- a/src/cmd/echo/echo.c +++ b/src/cmd/echo/echo.c @@ -14,4 +14,4 @@ main (int argc, char *argv[]) printf("%s%c", argv[i], (i == argc) ? ((nflag == 1) ? '\0' : '\n') : ' '); } return 0; -}
\ No newline at end of file +} diff --git a/src/cmd/echo/makefile b/src/cmd/echo/makefile index 0301f23..59f976f 100644..100755 --- a/src/cmd/echo/makefile +++ b/src/cmd/echo/makefile @@ -1,10 +1,12 @@ -all: echo +CFLAGS=-Wall -Werror + +build: echo @cp echo $(PROROOT)/build/bin/echo echo: echo.c - $(CC) -o echo echo.c + $(CC) $(CFLAGS) -o echo echo.c clean: @rm -r echo - -.PHONY: all clean
\ No newline at end of file + +.PHONY: build clean diff --git a/src/cmd/jsh/README.md b/src/cmd/jsh/README.md new file mode 100755 index 0000000..db638ed --- /dev/null +++ b/src/cmd/jsh/README.md @@ -0,0 +1,3 @@ +#J-Shell (jsh) + +J-Shell is a simple unix shell written in C. diff --git a/src/cmd/jsh/jsh.c b/src/cmd/jsh/jsh.c new file mode 100755 index 0000000..320a93d --- /dev/null +++ b/src/cmd/jsh/jsh.c @@ -0,0 +1,81 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <stdbool.h> +#include <ctype.h> + +size_t getargs(const size_t n, char *args[n], FILE * const stream); +int shellexec(size_t n, char * const args[n]); + +static bool run = true; + +int main(int argc, char *argv[]) { + char *words[BUFSIZ] = {NULL}; + FILE *fp = stdin; + size_t numberofwords = 0; + if (argc == 2) { + if ((fp = fopen(argv[1], "r")) == NULL) { + perror("jsh"); + return EXIT_FAILURE; + } + } + while (run) { + printf("$ "); + numberofwords = getargs(BUFSIZ, words, fp); + shellexec(BUFSIZ, words); + for (int i = 0; i < numberofwords; i++) { + free(words[i]); + words[i] = NULL; + } + } + return 0; +} + +size_t getargs(const size_t n, char *args[n], FILE * const stream) { + size_t i = 0; + char c = 0, s[BUFSIZ], *sp = s; + memset(s, '\0', sizeof(s)); + while ((c = fgetc(stream)) != EOF && i < n && sp < s + BUFSIZ) { + if (isspace(c)) { + *sp = '\0'; + args[i++] = strdup(s); + sp = s; + if (strcmp(args[i-1], "") == 0) { + free(args[i-1]); + args[i-1] = NULL; + i--; + } + if (c == '\n') { + break; + } + } else { + *sp++ = c; + } + } + return i; +} + +int shellexec(size_t n, char * const args[n]) { + if (strcmp(args[0], "exit") == 0) { + run = false; + return 0; + } + pid_t pid = fork(); + int status; + if (pid == 0) { + if (execvp(args[0], args) == -1) { + perror("jsh"); + } + exit(EXIT_FAILURE); + } else if (pid < 0) { + perror("jsh"); + exit(EXIT_FAILURE); + } else { + do { + waitpid(pid, &status, WUNTRACED); + } while (!WIFEXITED(status) && !WIFSIGNALED(status)); + } + return 0; +} + diff --git a/src/cmd/jsh/makefile b/src/cmd/jsh/makefile new file mode 100755 index 0000000..72d7d68 --- /dev/null +++ b/src/cmd/jsh/makefile @@ -0,0 +1,12 @@ +CFLAGS=-Wall -Werror + +build: jsh + @cp jsh $(PROROOT)/build/bin/jsh + +jsh: jsh.c + $(CC) $(CFLAGS) -o jsh jsh.c + +clean: + @rm -r jsh + +.PHONY: build clean diff --git a/src/cmd/ls/ls.c b/src/cmd/ls/ls.c new file mode 100755 index 0000000..a937457 --- /dev/null +++ b/src/cmd/ls/ls.c @@ -0,0 +1,78 @@ +/* TODO: + * - add flags + * - add option to print more file information + */ +#include <stdio.h> +#include <sys/types.h> +#include <dirent.h> +#include <string.h> +#include <stdlib.h> +#include <errno.h> +#include <sys/stat.h> + +void dirwalk(DIR *); +void error(char *); +void printdirent(struct dirent *); +void printfile(char *); + +/* print information about files and directories */ +int main(int argc, char **argv) +{ + DIR *dp; + if (argc == 1) { + if ((dp = opendir(".")) == NULL) { + perror("ls"); + return -1; + } + dirwalk(dp); + } else if (argc == 2) { + if ((dp = opendir(argv[1])) == NULL) { + perror("ls"); + return -1; + } + dirwalk(dp); + } else { + while (--argc > 0 && !ferror(stdout)) { + errno = 0; + if ((dp = opendir(*++argv)) == NULL) { + perror("ls"); + continue; + } + dirwalk(dp); + } + } +} + +/* dirwalk: read all the directory entries in a directory */ +void dirwalk(DIR *d) +{ + struct dirent *dir; + while ((dir = readdir(d)) != NULL) { + errno = 0; + if (strcmp(dir->d_name, ".") == 0 || strcmp(dir->d_name, "..") == 0) + continue; + printdirent(dir); + } + if (errno != 0) { + perror("ls"); + } +} + +/* printdirent: print a directory entry and any selected information */ +void printdirent(struct dirent *dir) +{ + printf("%s\n", dir->d_name); +} + +/* printfile: print a file and any other selected information */ +void printfile(char *name) +{ + struct stat stbuf; + int e = stat(name, &stbuf); + if (e != 0) { + perror("ls"); + return; + } + printf("%s\n", name); +} + diff --git a/src/cmd/ls/makefile b/src/cmd/ls/makefile new file mode 100755 index 0000000..d6a3c8d --- /dev/null +++ b/src/cmd/ls/makefile @@ -0,0 +1,12 @@ +CFLAGS=-Wall -Werror + +build: ls + @cp ls $(PROROOT)/build/bin/ls + +ls: ls.c + $(CC) $(CFLAGS) -o ls ls.c + +clean: + @rm -r ls + +.PHONY: build clean diff --git a/src/cmd/makefile b/src/cmd/makefile index 52ddd59..481e827 100644 --- a/src/cmd/makefile +++ b/src/cmd/makefile @@ -1,4 +1,4 @@ -TOPTARGETS := all clean install +TOPTARGETS := all build clean install SUBDIRS := $(wildcard */.) diff --git a/src/cmd/pwd/makefile b/src/cmd/pwd/makefile new file mode 100755 index 0000000..85f4d06 --- /dev/null +++ b/src/cmd/pwd/makefile @@ -0,0 +1,12 @@ +CFLAGS=-Wall -Werror + +build: pwd + @cp pwd $(PROROOT)/build/bin/pwd + +pwd: pwd.c + $(CC) $(CFLAGS) -o pwd pwd.c + +clean: + @rm -r pwd + +.PHONY: build clean diff --git a/src/cmd/pwd/pwd.c b/src/cmd/pwd/pwd.c new file mode 100755 index 0000000..d8c4c2a --- /dev/null +++ b/src/cmd/pwd/pwd.c @@ -0,0 +1,30 @@ +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> + +#define MAXLEN 1024 + +/* print the current working directory */ +int main(void) +{ + char *cwd, i = 1; + + do { + size_t size = i * MAXLEN; + cwd = (char *)malloc(size); + getcwd(cwd, size); + if (errno == ERANGE) + free((void *)cwd); + } while (errno == ERANGE && ++i < 10); + + if (errno == ERANGE) { + fprintf(stderr, "pwd: directory name is too large\n"); + return -1; + } + + printf("%s\n", cwd); + free((void *)cwd); + return 0; +} + |
