CS110操作系统原理学习笔记(一)

本篇笔记主要涵盖CS110第1到第4节课。课程主要是继续UNIX6,所以新的vfs的那些东西没有涉及

https://www.youtube.com/watch?v=_LFGjZ0Sc6I&list=PLai-xIlqf4JmTNR9aPCwIAOySs1GOm8sQ

Lecture 1

  • umask, open, read和write系统调用
  • touch实现
  • copy实现

1.umask和open系统调用

1.1.umask

https://man7.org/linux/man-pages/man2/umask.2.html

umask是一个根据掩码判断文件权限的命令,也可以用作系统调用来设置新文件创建时候的权限。

#include <sys/types.h>
#include <sys/stat.h>

mode_t umask(mode_t mask); // mode_t -> Uint32

mode_t old_mask = umask(0); // umask设为0,返回的是原先的umask

第一个是d则表示是文件夹

drwx------ 2 vivek vivek 4096 2011-03-04 02:05 dir1
-rw------- 1 vivek vivek    0 2011-03-04 02:05 file

1.2.open

https://man7.org/linux/man-pages/man2/open.2.html

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode); // mode控制权限

flags用bitset控制, 必须包含下面三个中的一个读写申明

  • O_RDONLY // 只读
  • O_WRONLY // 只写
  • O_RDWR // 可读可写

处理方法(用||做or的bitset)

  • O_CREAT 如果文件不存在,新建一个
  • O_EXCL 如果文件存在,报错(写的时候才用)
    (写入方法)
  • O_APPEND 用O_APPEND就是在文件尾继续写
  • O_TRUNC 抹除文件内容,再写

可处理方法和写入方法可一起用 O_CREAT|O_WRONLY|O_TRUNC, O_CREAT|O_WRONLY| O_EXCL

1.3.read

read 会尝试从文件描述符中读取count大小的bytes,并放到buffer中(starting at buf)。返回值为成功读取的bytes,如果0表示读完了,-1表示异常(文件位置改变...)。

#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);

1.4.write

从buf指向的位置开始写入count个bytes到文件描述符fd中。 返回值为成功写入的bytes的数量,0表示没东西可写,-1表示异常。

#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);

2.简单的touch实现

errno是c的一个全局变量用来存储程序的异常, errno -l查询错误码对应的异常。

#include <stdio.h>
#include <fcntl.h> // for open
#include <unistd.h> // for read, open, write
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>

const char *kFilename = "my_file";
const int kFileExistsErr = 17;

int main() {
	umask(0); // 重置默认umask再修改umask
	int file_descriptor = open(kFilename, O_WRONLY | O_CREAT | O_EXCL, 0644); 
	if (file_descriptor == -1) {
		printf("There was a problem creating '%s'!\n", kFilename);
		if (errno == kFileExistsErr) {
			printf("The file already exist!\n");
		} else {
			printf("Unknown errono: %d\n", errno);
		}
		return -1;
	}
	close(file_descriptor);
	return 0;
}

权限也为0644

3.简单的cp实现

The read system call will block until the requested number of bytes have been read. If the return value is 0, there are no more bytes to read (e.g., the file has reached the end, or been closed).
If write returns a value less than count, it means that the system couldn't write all the bytes at once. This is why the while loop is necessary, and the reason for keeping track of bytesWritten and bytesRead.
You should close files when you are done using them, although they will get closed by the OS when your program ends. We will use valgrind to check if your files are being closed.

read会堵塞

#include <stdio.h>
#include <fcntl.h> // for open
#include <unistd.h> // for read, open, write
#include <stdbool.h>
#include <errno.h>

static const int kWrongArgumentCount = 1;
static const int kSourceFileNonExistent = 2;
static const int kDestinationFileOpenFailure = 4;
static const int kReadFailure = 8;
static const int kWriteFailure = 16;
static const int kDefaultPermissions= 0644;

int main(int argc, char *argv[]) {
  if (argc != 3) {
    fprintf(stderr, "%s <source-file> <destination-file>. \n", argv[0]);
    return kWrongArgumentCount;
  }

  int fdin = open(argv[1], O_RDONLY);
  // 只写,创建+覆盖
  int fdout = open(argv[2], O_WRONLY | O_CREAT | O_EXCL, 0644);
  char buffer[1024];
  while (true) { // 保证文件被读完
    ssize_t bytesRead = read(fdin, buffer, sizeof(buffer));
    if (bytesRead == 0) break; // 读完了
    size_t bytesWritten = 0;  // 保证readBuffer的写完
    while (bytesWritten < bytesRead) {
      bytesWritten += write(fdout, buffer + bytesWritten, bytesRead - bytesWritten);
    }
  }
  close(fdin); 
  close(fdout);
  return 0;
}

猜你喜欢

转载自www.cnblogs.com/linsinan1995/p/13394325.html