7--UNIX系统接口

文件描述符

Unix上用文件描述符,指代文件。
文件描述符是整型
0/1/2分别代表标准输入,输出,错误

低级I/O

#include "syscalls.h"
/* getchar: simple buffered version */
int getchar(void)
{
    
    
	static char buf[BUF	SIZ];
	static char *bufp = buf;
	static int n = 0;
	if (n == 0) 
	{
    
     
		/* buffer is empty */
		n = read(0, buf, sizeof buf);
		bufp = buf;
	}
	
	return (--n >= 0) ? (unsigned char) *bufp++ : EOF;
}

Open/Creat/Close/Unlink

	#include <fcntl.h>
	int fd;
	int open(char *name, int flags, int perms);
	int creat(char *name, int perms);

	#include <stdio.h>
	#include <stdarg.h>
	/* error: print an error message and die */
	void error(char *fmt, ...)
	{
    
    
		va_list args;
		va_start(args, fmt);
		fprintf(stderr, "error: ");
		vprintf(stderr, fmt, args);
		fprintf(stderr, "\n");
		va_end(args);
		exit(1);
	}
unlink将文件name从文件系统删除

随机访问

	long lseek(int fd, long offset, int origin);
	#include "syscalls.h"
	/*get: read n bytes from position pos */
	int get(int fd, long pos, char *buf, int n)
	{
    
    
		if (lseek(fd, pos, 0) >= 0) /* get to pos */
			return read(fd, buf, n);
		else
			return -1;
	}

例子-实现Fopen and Getc

	#define NULL 0
	#define EOF (-1)
	#define BUFSIZ 1024
	#define OPEN_MAX 20 /* max #files open at once */
	typedef struct _iobuf 
	{
    
    
		int cnt; /* characters left */
		char *ptr; /* next character position */
		char *base; /* location of buffer */
		int flag; /* mode of file access */
		int fd; /* file descriptor */
	} FILE;

	extern FILE _iob[OPEN_MAX];
	#define stdin (&_iob[0])
	#define stdout (&_iob[1])
	#define stderr (&_iob[2])
	enum _flags 
	{
    
    
		_READ = 01, /* file open for reading */
		_WRITE = 02, /* file open for writing */
		_UNBUF = 04, /* file is unbuffered */
		_EOF = 010, /* EOF has occurred on this file */
		_ERR = 020 /* error occurred on this file */
	};

	int _fillbuf(FILE *);
	int _flushbuf(int, FILE *);
	#define feof(p) ((p)->flag & _EOF) != 0)
	#define ferror(p) ((p)->flag & _ERR) != 0)
	#define fileno(p) ((p)->fd)
	#define getc(p) (--(p)->cnt >= 0 \
	? (unsigned char) *(p)->ptr++ : _fillbuf(p))
	#define putc(x,p) (--(p)->cnt >= 0 \
	? *(p)->ptr++ = (x) : _flushbuf((x),p))
	#define getchar() getc(stdin)
	#define putcher(x) putc((x), stdout)


	#include <fcntl.h>
	#include "syscalls.h"
	#define PERMS 0666 /* RW for owner, group, others */
	FILE *fopen(char *name, char *mode)
	{
    
    
		int fd;
		FILE *fp;
		if (*mode != 'r' && *mode != 'w' && *mode != 'a')
			return NULL;
		for (fp = _iob; fp < _iob + OPEN_MAX; fp++)
			if ((fp->flag & (_READ | _WRITE)) == 0)
				break; /* found free slot */
		if (fp >= _iob + OPEN_MAX) /* no free slots */
			return NULL;

		if (*mode == 'w')
			fd = creat(name, PERMS);
		else if (*mode == 'a') 
		{
    
    
			if ((fd = open(name, O_WRONLY, 0)) == -1)
				fd = creat(name, PERMS);
			lseek(fd, 0L, 2);
		} 
		else
			fd = open(name, O_RDONLY, 0);
		
		if (fd == -1) /* couldn't access name */
			return NULL;
		fp->fd = fd;
		fp->cnt = 0;
		fp->base = NULL;
		fp->flag = (*mode == 'r') ? _READ : _WRITE;
		return fp;
	}

	#include "syscalls.h"
	/* _fillbuf: allocate and fill input buffer */
	int _fillbuf(FILE *fp)
	{
    
    
		int bufsize;
		if ((fp->flag&(_READ|_EOF_ERR)) != _READ)
			return EOF;
		bufsize = (fp->flag & _UNBUF) ? 1 : BUFSIZ;
		if (fp->base == NULL) /* no buffer yet */
			if ((fp->base = (char *) malloc(bufsize)) == NULL)
				return EOF; /* can't get buffer */
		fp->ptr = fp->base;
		fp->cnt = read(fp->fd, fp->ptr, bufsize);
		if (--fp->cnt < 0) 
		{
    
    
			if (fp->cnt == -1)
				fp->flag |= _EOF;
			else
				fp->flag |= _ERR;
			fp->cnt = 0;
			return EOF;
		}
		
		return (unsigned char) *fp->ptr++;
	}

	FILE _iob[OPEN_MAX] = 
	{
    
     
		/* stdin, stdout, stderr */
		{
    
     0, (char *) 0, (char *) 0, _READ, 0 },
		{
    
     0, (char *) 0, (char *) 0, _WRITE, 1 },
		{
    
     0, (char *) 0, (char *) 0, _WRITE | _UNBUF, 2 }
	};

例子-列举目录

目录是一个文件,包含文件名列表,和文件位置。
文件位置用索引号指示。
目录项通常仅仅包含:the filename and an inode number.
文件i节点存放除文件名外文件信息
Dirent
opendir
readdir
closedir

The Dirent structure contains the inode number and the name. 
The maximum length of a filename component is NAME_MAX, 
which is a system-dependent value.
opendir returns a pointer to a structure called DIR, 
analogous to FILE, which is used by readdir and closedir.
	// dirent.h.
	#define NAME_MAX 14 /* longest filename component; */
	/* system-dependent */
	typedef struct 
	{
    
     
		/* portable directory entry */
		long ino; /* inode number */
		char name[NAME_MAX+1]; /* name + '\0' terminator */
	} 
	Dirent;
	typedef struct 
	{
    
     
		/* minimal DIR: no buffering, etc. */
		int fd; /* file descriptor for the directory */
		Dirent d; /* the directory entry */
	} 
	DIR;
	DIR *opendir(char *dirname);
	Dirent *readdir(DIR *dfd);
	void closedir(DIR *dfd);

	char *name;
	struct stat stbuf;
	int stat(char *, struct stat *);
	stat(name, &stbuf);

	<sys/stat.h>
	<sys/types.h>
	struct stat /* inode information returned by stat */
	{
    
    
		dev_t st_dev; /* device of inode */
		ino_t st_ino; /* inode number */
		short st_mode; /* mode bits */
		short st_nlink; /* number of links to file */
		short st_uid; /* owners user id */
		short st_gid; /* owners group id */
		dev_t st_rdev; /* for special files */
		off_t st_size; /* file size in characters */
		time_t st_atime; /* time last accessed */
		time_t st_mtime; /* time last modified */
		time_t st_ctime; /* time originally created */
	};


	#define S_IFMT 0160000 /* type of file: */
	#define S_IFDIR 0040000 /* directory */
	#define S_IFCHR 0020000 /* character special */
	#define S_IFBLK 0060000 /* block special */
	#define S_IFREG 0010000 /* regular */

	<sys/dir.h>
	#ifndef DIRSIZ
	#define DIRSIZ 14
	#endif
	struct direct 
	{
    
     
		/* directory entry */
		ino_t d_ino; /* inode number */
		char d_name[DIRSIZ]; /* long name does not have '\0' */
	};

一个存储空间分配器

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/x13262608581/article/details/108724872