@ author: Charles Hau @ date: Thu 3 Oct 2019 19:51:38 EDT
Download the source code. In the home folder of the project(also where Makefile located), run make A
to compile, where A is one of these: cat cp diff ls mv rm stat
The binary file will be stored in /bin
. I also put some sample files and directories for test. The source code is in src/source
and src/header
Run ./myA
to run the command, where A is same thing above.
All the programs has been run on Linux raspberry 4.19.0-6-686 #1 SMP Debian 4.19.67-2+deb10u1 (2019-09-20) i686 GNU/Linux
, with compiler g++ 8.3.0
.
Feel free to email me and have fun!
The key point of this program, is to encapsulate a buildin file management kit into a class called File
.
The properties of File
is mainly from stat()
:
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* file type and mode */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for filesystem I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
/* Since Linux 2.6, the kernel supports nanosecond
precision for the following timestamp fields.
For the details before Linux 2.6, see NOTES. */
struct timespec st_atim; /* time of last access */
struct timespec st_mtim; /* time of last modification */
struct timespec st_ctim; /* time of last status change */
#define st_atime st_atim.tv_sec /* Backward compatibility */
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
};
(reference: https://manpages.debian.org/stretch/manpages-dev/stat.2.en.html)
About mode_t
and how to check file type, see Appendix I
Besides, struct passwd
and struct group
are also used.
struct group {
char *gr_name; /* group name */
char *gr_passwd; /* group password */
gid_t gr_gid; /* group ID */
char **gr_mem; /* NULL-terminated array of pointers
to names of group members */
};
struct passwd {
char *pw_name; // username
char *pw_passwd; // user password
uid_t pw_uid; // user ID
gid_t pw_gid; // group ID
char *pw_gecos; // user information
char *pw_dir; // home directory
char *pw_shell; // shell program
};
(reference https://manpages.debian.org/stretch/manpages-dev/getpwuid.3.en.html)
In the program, we mainly use passwd getpwuid(st_uid)
and group getgrgid(st_gid)
to get user's group and owner.
- Firstly use type
bitset
, transfer from int to binary, then to string. - Then use function
string to_rwx(int)
switch to string.
std::bitset<9> res (sb.st_mode); // new a bitset res
string s_res = res.to_string('-','*'));
to_rwx(s_res)
A string with formatted date.
ctime(&sb.st_atime)
ctime
is a classical function from time.h
, which take const *t_time
as a param and return a string
Also, st_atime
is from
#define st_atime st_atim.tv_sec
and tv_sec
actually is t_time
The Status Change Time and Modification Time is the same principle
print the error, with the format
pre-information, error number, error information
If a file is a context, read from it and return a string storing it.
It will have two errors: 1. size; 2. existence;
The instance variable children
is made by pair<File, string>
The second string store a brief name of a file. Because in File.name
, you have to store the whole path, so, in case of ls
, it could be super inconvenient.
In File.expand()
, we use two builtin class, dirent
and DIR
, referring to files and directories in file system.
What's noticeable is, in File.expand()
, the File.name
keeps increasing, from /f
to /f/ff
to /f/ff/fff
, but we always keep its original name fff
in pair<File, string>
.
I use three versions of dump
here. It will copy from a file, and store it in file or stream or char buffer.
There is bunches of system types built-in. It will mainly be used in class and myls
.
S_IFMT 0170000 bit mask for the file type bit field
S_IFSOCK 0140000 socket
S_IFLNK 0120000 symbolic link
S_IFREG 0100000 regular file
S_IFBLK 0060000 block device
S_IFDIR 0040000 directory
S_IFCHR 0020000 character device
S_IFIFO 0010000 FIFO
Compare the above things with st_mode
is illegal. You have to call those functions:
S_ISREG(m) is it a regular file?
S_ISDIR(m) directory?
S_ISCHR(m) character device?
S_ISBLK(m) block device?
S_ISFIFO(m) FIFO (named pipe)?
S_ISLNK(m) symbolic link? (Not in POSIX.1-1996.)
S_ISSOCK(m) socket? (Not in POSIX.1-1996.)