Skip to content
This repository was archived by the owner on Dec 25, 2018. It is now read-only.

Commit 4297a4a

Browse files
committed
builtin basic function
1 parent 3aeb66d commit 4297a4a

File tree

1 file changed

+100
-34
lines changed

1 file changed

+100
-34
lines changed

builtin.c

Lines changed: 100 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,64 @@
1+
#include <dirent.h>
2+
#include <fcntl.h>
13
#include <stdio.h>
24
#include <stdlib.h>
35
#include <string.h>
46
#include <sys/stat.h>
7+
#include <sys/time.h>
58
#include <sys/types.h>
9+
#include <time.h>
610
#include <unistd.h>
11+
#include <utime.h>
712
#define N 1024
813

14+
const char *help_string[] = {
15+
"cat {file}: Display content of {file}.",
16+
"cd {dir}: Switch current working directory to {dir}.",
17+
"chmod {mode} {file/dir}: Change the mode (permission) of a file or "
18+
"directory.",
19+
" {mode} is an octal number.",
20+
" Please do not follow symbolc links.",
21+
"echo {str} [filename]: Display {str}. If [filename] is given,",
22+
" open [filename] and append {str} to the file.",
23+
"exit: Leave the shell.",
24+
"find [dir]: List files/dirs in the current working "
25+
"directory",
26+
" or [dir] if it is given.",
27+
" Minimum outputs contatin file type, size, and "
28+
"name.",
29+
"help: Display help message.",
30+
"id: Show current euid and egid.",
31+
"mkdir {dir}: Create a new directory {dir}.",
32+
"pwd: Print the current working directory.",
33+
"rm {file}: Remove a file.",
34+
"rmdir {dir}: Remove an empty directory.",
35+
"stat {file/dir}: Display detailed information of the given "
36+
"file/dir.",
37+
"touch {file}: Create {file} if it does not exist,",
38+
" or update its access and modification "
39+
"timestamp.",
40+
"umask {mode}: Change the umask of the current session."};
41+
42+
const char *get_file_type(int mode) {
43+
const char *file_type[] = {"named pipe (fifo)",
44+
"character special file",
45+
"directory",
46+
"block special file",
47+
"regular file",
48+
"symbolic link",
49+
"socket",
50+
"unknown"};
51+
const int file_mask[] = {S_IFIFO, S_IFCHR, S_IFDIR, S_IFBLK,
52+
S_IFREG, S_IFLNK, S_IFSOCK};
53+
54+
for (size_t i = 0; i < 7; ++i) {
55+
if (mode == file_mask[i]) {
56+
return file_type[i];
57+
}
58+
}
59+
return file_type[7];
60+
}
61+
962
int builtin_cat(char *line) {
1063
char arg[N], extra[N];
1164
if (sscanf(line, "%*s %s %s", arg, extra) != 1) return -1;
@@ -64,40 +117,31 @@ int builtin_exit(char *line) {
64117
return 1;
65118
}
66119

67-
int builtin_find(char *cmd) { return 0; }
120+
int builtin_find(char *line) {
121+
char arg[N], extra[N];
122+
int argc;
123+
if ((argc = sscanf(line, "%*s %s %s", arg, extra)) > 1) return -1;
124+
125+
DIR *dir = opendir(argc == 1 ? arg : ".");
126+
struct dirent *dp;
127+
struct stat info;
128+
int ret;
129+
while ((dp = readdir(dir)) != NULL) {
130+
printf("%-20s", dp->d_name);
131+
ret = stat(dp->d_name, &info);
132+
// if (ret == -1) { ; continue; }
133+
printf("\t%-20s\t%-5ld\n", get_file_type(info.st_mode & S_IFMT),
134+
info.st_size);
135+
}
136+
closedir(dir);
137+
return 0;
138+
}
68139

69140
int builtin_help(char *line) {
70141
char extra[N];
71142
if (sscanf(line, "%*s %s", extra) > 0) return -1;
72143

73-
const char *help_string[] = {
74-
"cat {file}: Display content of {file}.",
75-
"cd {dir}: Switch current working directory to {dir}.",
76-
"chmod {mode} {file/dir}: Change the mode (permission) of a file or "
77-
"directory.",
78-
" {mode} is an octal number.",
79-
" Please do not follow symbolc links.",
80-
"echo {str} [filename]: Display {str}. If [filename] is given,",
81-
" open [filename] and append {str} to the file.",
82-
"exit: Leave the shell.",
83-
"find [dir]: List files/dirs in the current working "
84-
"directory",
85-
" or [dir] if it is given.",
86-
" Minimum outputs contatin file type, size, and "
87-
"name.",
88-
"help: Display help message.",
89-
"id: Show current euid and egid.",
90-
"mkdir {dir}: Create a new directory {dir}.",
91-
"pwd: Print the current working directory.",
92-
"rm {file}: Remove a file.",
93-
"rmdir {dir}: Remove an empty directory.",
94-
"stat {file/dir}: Display detailed information of the given "
95-
"file/dir.",
96-
"touch {file}: Create {file} if it does not exist,",
97-
" or update its access and modification "
98-
"timestamp.",
99-
"umask {mode}: Change the umask of the current session."};
100-
size_t len = sizeof(help_string) / sizeof(char *);
144+
const size_t len = sizeof(help_string) / sizeof(char *);
101145
for (size_t i = 0; i < len; ++i) printf("%s\n", help_string[i]);
102146
return 0;
103147
}
@@ -148,16 +192,38 @@ int builtin_rmdir(char *line) {
148192
return 0;
149193
}
150194

151-
int builtin_stat(char *cmd) { return 0; }
195+
int builtin_stat(char *line) {
196+
char arg[N], extra[N];
197+
if (sscanf(line, "%*s %s %s", arg, extra) != 1) return -1;
198+
199+
struct stat info;
200+
int ret = stat(arg, &info);
201+
// if (ret == -1)
202+
printf(
203+
"\
204+
File: %s\n\
205+
Size: %lld Blocks: %lld IO Block: %ld %s\n\
206+
Device: %s Inode: %ld Links: %d\n\
207+
Access: (%lo) Uid: (%ld) Gid: (%ld)\n\
208+
Access: %s\
209+
Modify: %s\
210+
Change: %s",
211+
arg, info.st_size, info.st_blocks, info.st_blksize,
212+
get_file_type(info.st_mode & S_IFMT),
213+
"", // info.st_dev,
214+
info.st_ino, info.st_nlink, info.st_mode & 0777, info.st_uid, info.st_gid,
215+
ctime(&info.st_atime), ctime(&info.st_mtime), ctime(&info.st_ctime));
216+
return 0;
217+
}
152218

153219
int builtin_touch(char *line) {
154220
char arg[N], extra[N];
155221
if (sscanf(line, "%*s %s %s", arg, extra) != 1) return -1;
156222

157-
FILE *file;
158-
// if (access(arg, F_OK) != -1)
159-
file = fopen(arg, "a+");
160-
fclose(file);
223+
int fd = open(arg, O_WRONLY | O_CREAT | O_NOCTTY | O_NONBLOCK, 0666);
224+
// if (fd < 0)
225+
int rc = utimensat(AT_FDCWD, arg, NULL, 0);
226+
// if (rc)
161227
return 0;
162228
}
163229

0 commit comments

Comments
 (0)