UNIX编程(1)-基础知识

1.登陆名
登陆名放在/etc/passwd口令文件中,口令文件中的登陆项由7个以冒号分隔的字段组成,他们是:登陆名,加密口令,用户ID,用户组ID,注释字段,起始目录,shell程序
daemon:x:2:2:daemon:/sbin:/sbin/nologin
2.文件和目录
例:列出目录中所有的文件

#include "apue.h"
#include <dirent.h>

int
main(int argc, char *argv[])
{
DIR *dp;
struct dirent *dirp;

if (argc != 2)
err_quit("usage: ls directory_name");

if ((dp = opendir(argv[1])) == NULL)
err_sys("can't open %s", argv[1]);
while ((dirp = readdir(dp)) != NULL)
printf("%s\n", dirp->d_name);

closedir(dp);
exit(0);
}

3.输入和输出
1)文件描述符
通常是一个小的非负整数,内核用它标识一个特定进程正在访问的文件。每当运行一个新的程序时,所有的shell都为其打开三个文件描述符:标准输入,标准输出,标准出错
2)不用缓冲的IO
例:将标准输入复制到标准输出

#include "apue.h"

#define BUFFSIZE 4096

int
main(void)
{
int n;
char buf[BUFFSIZE];

while ((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0)
if (write(STDOUT_FILENO, buf, n) != n)
err_sys("write error");

if (n < 0)
err_sys("read error");

exit(0);
}

3)标准IO
标准IO函数提供一种对不用缓冲IO函数的带缓冲的借口
例:用标准IO将标准输入复制到标准输出

#include "apue.h"

int
main(void)
{
int c;

while ((c = getc(stdin)) != EOF)
if (putc(c, stdout) == EOF)
err_sys("output error");

if (ferror(stdin))
err_sys("input error");

exit(0);
}


4.进程和线程
UNIX系统确保每个进程都有一个唯一的数字标识符,称为进程ID
例:打印进程ID

#include "apue.h"

int
main(void)
{
printf("hello world from process ID %d\n", getpid());
exit(0);
}

有三个用于进程控制的主要函数:fork,exec, waitpid
例:从标准输入读命令并执行

#include "apue.h"
#include <sys/wait.h>

int
main(void)
{
char buf[MAXLINE]; /* from apue.h */
pid_t pid;
int status;

printf("%% "); /* print prompt (printf requires %% to print %) */
while (fgets(buf, MAXLINE, stdin) != NULL) {
if (buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = 0; /* replace newline with null */

if ((pid = fork()) < 0) {
err_sys("fork error");
} else if (pid == 0) { /* child */
execlp(buf, buf, (char *)0);
err_ret("couldn't execute: %s", buf);
exit(127);
}

/* parent */
if ((pid = waitpid(pid, &status, 0)) < 0)
err_sys("waitpid error");
printf("%% ");
}
exit(0);
}

通常一个进程只有一个控制线程,在同一进程里的所有线程共享同一地址空间,文件描述符,栈以及与进程相关的属性。

5.出错处理
当UNIX函数出错时,常返回一个负值,而且整形变量errno通常被设置为含有附加信息的一个值。
有两个函数帮助打印出错信息:
1)将errno映射为出错信息字符串
#include <string.h>
char *strerror(int errnum);
2)基于当前errno值,在标准出错上产生一条出错信息,它首先输出由msg指向的字符串,然后是一个冒号,一个空格,接着是对应于errno值的出错信息,最后是一个换行符
#include <stdio.h>
void perror(const char *msg);
例:strerror和perror的用法

#include "apue.h"
#include <errno.h>

int
main(int argc, char *argv[])
{
fprintf(stderr, "EACCES: %s\n", strerror(EACCES));
errno = ENOENT;
perror(argv[0]);
exit(0);
}

6.用户标识
用户标识有用户ID,组ID,附加组ID
例:打印用户ID和组ID

#include "apue.h"

int
main(void)
{
printf("uid = %d, gid = %d\n", getuid(), getgid());
exit(0);
}

7.信号
信号是通知进程已发生某种情况的一种技术,进程如何处理信号有三种选择
1)忽略该信号
2)按系统默认的方式处理
3)提供一个函数处理
例:从标准输入读命令并执行

#include "apue.h"
#include <sys/wait.h>

static void sig_int(int); /* our signal-catching function */

int
main(void)
{
char buf[MAXLINE]; /* from apue.h */
pid_t pid;
int status;

if (signal(SIGINT, sig_int) == SIG_ERR)
err_sys("signal error");

printf("%% "); /* print prompt (printf requires %% to print %) */
while (fgets(buf, MAXLINE, stdin) != NULL) {
if (buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = 0; /* replace newline with null */

if ((pid = fork()) < 0) {
err_sys("fork error");
} else if (pid == 0) { /* child */
execlp(buf, buf, (char *)0);
err_ret("couldn't execute: %s", buf);
exit(127);
}

/* parent */
if ((pid = waitpid(pid, &status, 0)) < 0)
err_sys("waitpid error");
printf("%% ");
}
exit(0);
}

void
sig_int(int signo)
{
printf("interrupt\n%% ");
}



8.时间值
UNIX使用两种时间:
日历时间,从1970-01-01 00:00:00所经的秒数累计值,以time_t保存这种值。
进程时间,也称为CPU时间,用以度量进程使用的CPU资源,用clock_t保存这种值,UNIX系统使用三个进程时间值:时钟时间,用户CPU时间,系统CPU时间
9.系统调用和库函数
UNIX提供定义明确,数量有限,可直接进入内核的入口点,这些入口点称为系统调用。库函数并不是内核的入口点。UNIX为每个系统调用在标准C库中设置一个具有同样名字的函数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值