# 110-1 Computer Architecture Final Project
#### Outline
[TOC]
# Final Project
:::info
Contribute to Ripes: pick up pending issues, work on them, and finally send pull request(s).
:::
Take reference from mortbopet/[Ripes](https://github.com/mortbopet/Ripes)
## The problem to be solved
:::info
As indicated by [#123](https://github.com/mortbopet/Ripes/issues/123), there should be an example program to demonstrate the use of the various file-related system calls.
The example program could:
* open a new file for writing
* write something to the file
* seeking in the file
* closing the file
* reopening the file and printing the contents of the file

:::
## Pre-work
:::success
* Get the Ripes source code
* Check the __Cmake__ and __Qt__ environment setting
```shell=
$ git clone --recursive https://github.com/mortbopet/Ripes.git
$ sudo apt-get install cmake
$ sudo apt-get install qt5-default
$ sudo apt-get install qttools5-dev
$ sudo apt-get install qttools5-dev-tools
$ sudo apt-get install qtmultimedia5-dev
$ sudo apt-get install libqt5svg5-dev
$ sudo apt-get install libqt5webkit5-dev
$ sudo apt-get install libqt5charts5-dev
```
* Generate the Make files with Cmake, follow the below command
* build
```shell=
$ cmake .
$ make
```
:::warning
* Using the below instruction if the system can not find the CXX compiler identification:
```
sudo apt-get update
sudo apt-get install -y build-essential
```
:::
## Updating and Modifying
### Breakthrough
:::success
* The author already add system call inside app, but is not really communicated in the system call dialog.

* Therefore, we start to learn more about the code relate to this part.
:::
### Version 1
:::info
* The flags are intended to follow values generally used in a unix environment.
* The flags are defined here:

#### Seek
* Ensure that SystemIO is constructed
``` shell=
static int seek(int fd, int offset, int base) {
SystemIO::get();
if (!FileIOData::fdInUse(fd, 0))
{
s_fileErrorString = "File descriptor " + QString::number(fd) + " is not open for reading";
return -1;
}
if (fd < 0 || fd >= SYSCALL_MAXFILES)
return -1;
auto& stream = FileIOData::getStreamInUse(fd);
if (base == SEEK_SET) {
offset += 0;
} else if (base == SEEK_CUR) {
offset += stream.pos();
} else if (base == SEEK_END) {
offset += FileIOData::files[fd].size();
} else {
return -1;
}
if (offset < 0) {
return -1;
}
stream.seek(offset);
return offset;
}
```
##### Open
* Ensure that SystemIO is constructed Internally, a "file descriptor" is an index into a table of the filename, flag, and the File???putStream associated with that file descriptor.
```shell=
static int openFile(QString filename, int flags) {
SystemIO::get();
int retValue = -1;
int fdToUse;
fdToUse = FileIOData::nowOpening(filename, flags);
retValue = fdToUse;
if (fdToUse < 0) {
return -1;
}
try {
FileIOData::openFilestream(fdToUse, filename);
} catch (int) {
s_fileErrorString = "File " + filename + " could not be opened.";
retValue = -1;
}
return retValue;
}
```
#### Write
* Check the existence of the "write" fd
``` shell=
static int writeToFile(int fd, const QString& myBuffer, int lengthRequested) {
SystemIO::get();
if (fd == STDOUT || fd == STDERR) {
emit get().doPrint(myBuffer);
return myBuffer.size();
}
if (!FileIOData::fdInUse(fd, O_WRONLY | O_RDWR))
{
s_fileErrorString = "File descriptor " + QString::number(fd) + " is not open for writing";
return -1;
}
auto& outputStream = FileIOData::getStreamInUse(fd);
outputStream << myBuffer;
outputStream.flush();
return lengthRequested;
}
```
#### Close
``` shell=
static void closeFile(int fd) {
FileIOData::close(fd);
}
```
:::
### Code flow
:::info
#### Fstat
* These functions return information about a file. No permissions are required on the file itself, but-in the case of stat() and lstat() - execute (search) permission is required on all of the directories in path that lead to the file.
* stat() stats the file pointed to by path and fills in buf.
* lstat() is identical to stat(), except that if path is a symbolic link, then the link itself is stat-ed, not the file that it refers to.
* fstat() is identical to stat(), except that the file to be stat-ed is specified by the file descriptor fd.
* All of these system calls return a stat structure, which contains the following fields:
```shell=
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection */
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 file system I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};
```
#### Lseek
* The lseek() function repositions the offset of the open file associated with the file descriptor fd to the argument offset according to the directive whence as follows:
* SEEK_SET
> The offset is set to offset bytes.
* SEEK_CUR
> The offset is set to its current location plus offset bytes.
* SEEK_END
> The offset is set to the size of the file plus offset bytes.
* The lseek() function allows the file offset to be set beyond the end of the file (but this does not change the size of the file). If data is later written at this point, subsequent reads of the data in the gap (a "hole") return null bytes (aq\0aq) until data is actually written into the gap.
```shell=
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
```
#### Close
* close() closes a file descriptor, so that it no longer refers to any file and may be reused. Any record locks (see fcntl(2)) held on the file it was associated with, and owned by the process, are removed (regardless of the file descriptor that was used to obtain the lock).
* If fd is the last file descriptor referring to the underlying open file description (see open(2)), the resources associated with the open file description are freed; if the descriptor was the last reference to a file which has been removed using unlink(2) the file is deleted.
```shell=
#include <unistd.h>
int close(int fd);
```
:::
### comment and reply
#### 2022/01/05 - [Link](https://github.com/mortbopet/Ripes/issues/123#issuecomment-1005666982)

#### 2022/01/06 - [Link](https://github.com/mortbopet/Ripes/issues/123#issuecomment-1006296415)

#### 2022/01/06 - [Link](https://github.com/mortbopet/Ripes/issues/123#issuecomment-1006343934)

#### 2022/01/06 - [Link](https://github.com/mortbopet/Ripes/issues/123#issuecomment-1006672527)
