全部博文(293)
分类: C/C++
2010-01-28 20:11:44
第3章 文件I/O
* ssize_t read(int fd, void *buf, size_t count); 函数在从文件描述符中读时,很多原因导致读不到count个字符,所以在进行读取操作时需要处理一下,特别是在进行网络和管道读取的时候。
一般的处理方式是 while((rt = read(fd, buffer, size) == -1) && (errno == EINTR) );
另外,在网络编程中需要特殊处理。
*原子操作的概念。
*用open函数创建新文件,定位文件的写位置;当文件存在时的处理方式。
文件不存在就创建,文件存在就截断成0,
open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
文件不存在就创建:
open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0666)
*dup 和 dup2 的使用,下面是一个例子:
view plaincopy to clipboardprint?
if ((fd = open("temp", O_RDWR | O_APPEND | O_CREAT | O_TRUNC, 0766)) < 0) {
perror("open(): ");
exit(1);
}
//save 2
fd1 = dup(2);
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, 2);
write(fd, "123\n", 4);
printf("456\n");
fprintf(stderr, "8910\n");
//restore 2
dup2(fd1, 2);
fprintf(stderr, "11 12 13 14 15\n");
return 0;
if ((fd = open("temp", O_RDWR | O_APPEND | O_CREAT | O_TRUNC, 0766)) < 0) {
perror("open(): ");
exit(1);
}
//save 2
fd1 = dup(2);
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, 2);
write(fd, "123\n", 4);
printf("456\n");
fprintf(stderr, "8910\n");
//restore 2
dup2(fd1, 2);
fprintf(stderr, "11 12 13 14 15\n");
return 0;
为了恢复重定向的描述符,需要先用dup进行保存,再用dup2来恢复,如上面的代码。
*缓冲区高速缓存函数sync,fsync,fdatasync的功能和区别
磁盘i/o的缓冲机制: 数据->缓冲区->缓冲区满或内核需要使用该缓冲区->输出队列->到达队列首->进行i/o操作
sync : 将所有修改的缓冲区排入写队列
fsync: 等待写磁盘操作结束,会改变文件的属性
fdatasync: 和fsync类似,但只针对数据,不改变文件属性
*fcntl函数的用法 ????
*ioctl函数的用法????
第4章 文件和目录
*state,fstate,lstat这几个函数的区别和用法
*如何判断一个文件的类型
+ expand sourceview plaincopy to clipboardprint?
int
main(int argc, char *argv[])
{
struct stat buf;
if (argc != 2) {
fprintf(stderr, "Usage : %s filename\n", argv[0]);
exit(1);
}
if (lstat(argv[1], &buf) < 0) {
perror("lstat : %s\n");
return -1;
}
if (S_ISREG(buf.st_mode))
printf("regular file\n");
return 0;
}
~
int
main(int argc, char *argv[])
{
struct stat buf;
if (argc != 2) {
fprintf(stderr, "Usage : %s filename\n", argv[0]);
exit(1);
}
if (lstat(argv[1], &buf) < 0) {
perror("lstat : %s\n");
return -1;
}
if (S_ISREG(buf.st_mode))
printf("regular file\n");
return 0;
}
~
上面的代码只能判断 regular类型的文件,若想判断其他的文件类型,请查询手册 man lstate 的st_mode节
*进程相关联的几个ID: 实际用户ID,有效用户ID,设置用户ID
实际用户ID: 来自/etc/passwd 的用户名和组名
有效用户ID: 访问文件时的用户ID或组ID
设置用户ID: 保存了实际用户ID,如果设置了S属性,就把有效用户ID设置成文件的所有者,如程序 passwd
对设置用户ID进行测试可以用: stat 函数的 S_ISUID 和 S_ISGID来进行测试是否设置了该字段
*文件的访问权限???
*新文件和目录的所有权是如何设置的?
文件和目录的权限设置基本上一样。
view plaincopy to clipboardprint?
[zhengxh@jsdlinux temp]$ chmod a+s test
[zhengxh@jsdlinux temp]$ ls
[zhengxh@jsdlinux test]$ sudo su
[root@jsdlinux test]# ls
[root@jsdlinux test]# cat > tt
adfadf
[root@jsdlinux test]# ls -l
总计 4
-rw-r--r-- 1 root zhengxh 7 02-06 16:11 tt
[root@jsdlinux test]# cd ..
[zhengxh@jsdlinux temp]$ chmod a+s test
[zhengxh@jsdlinux temp]$ ls
[zhengxh@jsdlinux test]$ sudo su
[root@jsdlinux test]# ls
[root@jsdlinux test]# cat > tt
adfadf
[root@jsdlinux test]# ls -l
总计 4
-rw-r--r-- 1 root zhengxh 7 02-06 16:11 tt
[root@jsdlinux test]# cd ..
(1)新文件的用户ID设置成进程的有效用户ID
(2)新文件的组ID的设置分成两种情况:如果所在目录设置了设置用户ID,则该新文件的组ID设置成所在目录的设置用户ID
否则,设置成进程的组用户ID
如上面代码所示。
*文件屏蔽字的设置--umask函数
1,每个系统都有一个默认的umask值,当建立新文件时,将按照这个值来进行权限的设定: 0777-umask(0022)
2,如果不确定系统的默认权限,需要使用umask对权限进行设定。
3,目录的默认权限中有x位,但新文件却没有x位
4,具体使用请参考: man umask
*改变文件的访问权限
只有文件的所有者,和超级用户才能改变文件的权限。
(1) 在原有的基础上更改:
stat(filename, &statbuf)
chmod(filename, (statbuf.st_mode & S_IXGRP) | S_ISGID)
(2) 设置成固定的值
chmod(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
*
第7章 进程环境
*main函数是如何开始执行的?
内核exec一个启动例程(准备好main的参数和环境变量等) ----> main()--->其他函数
*进程终止的方式?
从main返回;exit;_exit或_Exit;调用abort;接到一个信号并终止。
*线程终止的方式?
最后一个线程从启动例程返回;最后一个线程调用pthread_exit;最后一个线程对取消请求做出响应。
*exit和_exit的区别?
exit 函数总是执行一个标准I/O库的清理关闭操作(fclose),调用执行各种终止处理程序(由atexit注册的函数)。
*什么是进程的返回状态?
每个进程都会返回一个整数值给shell,来表示他的状态是正常返回还是错误返回。
在main函数中调用:exit(int) 或 return(int)就向shell返回这个状态。
如果这样调用返回状态是未知的: return; 或这样申明main函数: void/char main; 或根本不调用return或exit;
*进程的环境表是什么?如何操作环境表?
进程的环境表是一个字符指针数组,其中每个字符串以null结尾。
全局变量environ指向这个字符串数组的首地址,通过它可以访问整个环境表。
getenv和putenv函数可以对某个环境表的项进行操作。
*进程的存储空间布局是怎样的?
.低地址--------------------------------------------------------------------------->高地址
.正文段-->初始化数据(数据段)-->未初始化的数据(bss段,由exec初始化为0)-->堆-->栈-->环境变量,参数
.说明:正文段和初始化段数据是由内核从程序文件中读入。其他的段都不从程序文件中读入。
.size命令可以查看一个可以执行文件的各段的长度。
*共享库的概念?如何制作共享库?????
*如何动态分配内存,各个函数调用的区别?
malloc 分配指定字节数的内存,不初始化。
calloc 分配指定对象,和指定数量的内存,每位都初始化为0。
realloc 在原来的基础上增加内存,不初始化。
free 释放由上面的三个函数分配的内存。
alloca 在栈段上分配内存,自动释放分配的空间。但有的系统不能增加栈空间,该函数将失败。
*如何修改环境变量?如何添加环境变量?
可以用以下函数实现这些功能:
putenv; setenv; unsetenv
*setjmp和longjmp的用法?
请看例子:
+ expand sourceview plaincopy to clipboardprint?
#include
#include
#include
#include
void do_line(char *ptr);
void f2(void);
#define MAXLINE 128
jmp_buf jbuf; //定义全局跳转变量
int
main(void)
{
char line[MAXLINE];
int jd;
/*
* 若setjmp直接返回正确,返回值为0;如:第一次设定正确时
* 若用于longjmp的调用而返回,
* 返回值为longjmp的第2个参数的数值。
*/
if ((jd = setjmp(jbuf)) != 0)
fprintf(stderr, "setjmp = %d\n", jd);
if (fgets(line, MAXLINE, stdin) != NULL)
do_line(line);
fprintf(stderr, "Now I go away!\n");
exit(0);
}
void
do_line(char *ptr)
{
if (strstr(ptr, "exit") != NULL)
return;
if (strstr(ptr, "zhengxh") != NULL)
f2();
else
longjmp(jbuf, 20); //跳转到设置(setjmp)jbuf变量的地方,使得setjmp返回值为20
}
void
f2(void)
{
//跳转到设置jbuf的地方,使得setjmp返回值为1
longjmp(jbuf, 1);
}
~
#include
#include
#include
#include
void do_line(char *ptr);
void f2(void);
#define MAXLINE 128
jmp_buf jbuf; //定义全局跳转变量
int
main(void)
{
char line[MAXLINE];
int jd;
/*
* 若setjmp直接返回正确,返回值为0;如:第一次设定正确时
* 若用于longjmp的调用而返回,
* 返回值为longjmp的第2个参数的数值。
*/
if ((jd = setjmp(jbuf)) != 0)
fprintf(stderr, "setjmp = %d\n", jd);
if (fgets(line, MAXLINE, stdin) != NULL)
do_line(line);
fprintf(stderr, "Now I go away!\n");
exit(0);
}
void
do_line(char *ptr)
{
if (strstr(ptr, "exit") != NULL)
return;
if (strstr(ptr, "zhengxh") != NULL)
f2();
else
longjmp(jbuf, 20); //跳转到设置(setjmp)jbuf变量的地方,使得setjmp返回值为20
}
void
f2(void)
{
//跳转到设置jbuf的地方,使得setjmp返回值为1
longjmp(jbuf, 1);
}
~
注意: 在使用这两个函数进行跳转时,在函数中的自动变量的值的改变将会丢失,
而volatile 定义的变量,全局变量,静态变量则不会。所以在编程时要注意。
*如何对每个进程的资源进行限制?
.用getrlimit 和 setrlimit可以做到,具体查看手册:man getrlimit
第8章 进程控制
*进程控制包括:创建新进程,执行进程,终止进程。
*基础知识
*进程标识
每个进程由一个正整数唯一标识,若该进程终止,它的进程标识整数可以被其他进程使用。
L/Unix系统中 0进程表示swapper进程,它不执行磁盘上的代码,所以被称为系统进程。
1 负责在自举后启动一个UNIX系统,通常配合/etc/rc*等文件启动系统。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zg_hover/archive/2009/02/06/3866041.aspx