UNIX环境C语言编程(1)-概述

1、用户登录

系统密码文件: / etc / passwd
登录信息由半角冒号分隔的 7 个域组成,依次为:

  登录名称:密文口令:用户ID:ID:注释信息:HOME:SHELL

  示例:billing:!:207:202::/billing:/usr/bin/ksh

密文口令存储于 / etc /security/ passwd

 

2、文件与目录

两个特殊名称: . 当前目录  .. 父目录
当前工作目录用以解析相对路径,相关调用:

  char *getcwd (char *Buffer,size_t Size)  //获取当前工作目录

  int chdir (const char *Path)   //改变当前工作目录

例子:程序实现目录列表
#include <stdio.h>
#include <dirent.h>

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

    if( argc != 2 )
    {
        printf("usage: %s <directory_name>\n", argv[0]);
        exit(0);
    }

    /* 打开目录 */
    if( (dp = opendir(argv[1])) == NULL )
    {
        perror(argv[1]);
        exit(1);
    }

    /* 逐一读取目录条目 */
    while( (dirp = readdir(dp)) != NULL )
    {
        printf("%s\n", dirp->d_name);
    }

    /* 关闭目录 */
    closedir(dp);
    exit(0);
}

问题:如何删除名字为 -1 的文件?

  rm -- -1

 

3、输入/输出

无缓冲 I/O

  操作对象为文件描述符,非负小整数

  特殊描述符:STDIN_FILENOSTDOUT_FILENOSTDERR_FILENO

  相关调用示例:open()read()write()lseek()close() …

  例子:

#include <stdio.h>
#include <unistd.h>

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

    /* 读取标准输入 */
    while( (n = read(STDIN_FILENO, buf, BUFSIZ)) > 0 )
    {
        /* 写入标准输出 */
        if( write(STDOUT_FILENO, buf, n) != n )
        {
            perror("write");
            exit(-1);
        }
    }

    if( n < 0 )
    {
        perror("read");
    }

    exit(0);
}


 

缓冲 I/O

  操作对象为文件指针,FILE *

  特殊指针:stdinstdoutstderr

  相关调用示例:printf()fgets()fputs() …

 

4、程序与进程

程序 指一个可执行文件
进程 程序 的一个执行实例
程序 进程 是一对多的关系,即一个 程序 可以多次执行
  pid_t getpid (void)  // 获取自己的进程 ID
例子:从键盘读取指令并执行
#include <stdio.h>
#include <sys/wait.h>

int main(void)
{
    pid_t   pid;
    int     status;
    char    buf[1024];

    /* print prompt (%% to print %) */
    printf("%% ");

    /* 读取标准输入 */
    while( fgets(buf, sizeof(buf), stdin) != NULL )
    {
        /* replace newline with null */
        if( buf[strlen(buf) - 1] == '\n' )
        {
            buf[strlen(buf) - 1] = 0;
        }

        /* 派生子进程 */
        if( (pid = fork()) < 0 )
        {
            perror("fork");
            exit(-1);
        }
        else if( pid == 0 )        /* child */
        {
            /* 执行读取的指令 */
            execlp(buf, buf, (char *)0);
            perror(buf);
            exit(127);
        }

        /* parent */
        if( (pid = waitpid(pid, &status, 0)) < 0 )
        {
            perror("waitpid");
        }
        printf("%% ");
    }

    exit(0);
}

5、错误处理
全局变量: extern int errno
两点说明:

  函数执行成功并不清除上次的errno取值;

  函数不会将errno设置为0

相关调用:

  char *strerror (int ErrorNumber//获取错误编号对应的错误信息

  void perror (const char *String//显示错误信息

错误恢复
 
6、用户身份识别
超级用户 root 的用户 ID 0
组文件为: / etc /group
相关调用:

  uid_t getuid (void) //获取用户ID

  gid_t getgid (void) //获取组ID

辅助组 ID

  允许一个用户属于多个组,示例:

  uid=207(billing)gid=202(dba) groups=205(billing)

 

7、信号

信号用以通知进程某些情况已经发生,属于一种异步机制
信号处理动作: 忽略信号 捕获信号 系统缺省
例子:从键盘读取指令并执行,捕获信号
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <sys/wait.h>

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

int main(void)
{
    pid_t   pid;
    int     status;
    char   *p, buf[1024];

    struct  sigaction  sa;

    /* 初始化 */
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;

    /* 设置信号处理动作 */
    sa.sa_handler = sig_int;
    sigaction(SIGINT, &sa, NULL);

    /* print prompt (%% to print %) */
    printf("%% ");

    while( 1 )
    {
        errno = 0;

        /* 读取指令 */
        p = fgets(buf, sizeof(buf), stdin);

        if( p == NULL )
        {
            if( errno == EINTR ) continue;
            else break;
        }

        /* replace newline with null */
        if( buf[strlen(buf) - 1] == '\n' )
        {
            buf[strlen(buf) - 1] = 0;
        }

        /* 派生子进程 */
        if( (pid = fork()) < 0 )
        {
            perror("fork");
            exit(-1);
        }
        else if( pid == 0 )        /* child */
        {
            /* 执行指令 */
            execlp(buf, buf, (char *)0);
            perror(buf);
            exit(127);
        }

        /* parent,等待子进程终止 */
        if( (pid = waitpid(pid, &status, 0)) < 0 )
        {
            perror("waitpid");
        }
        printf("%% ");
    }

    exit(0);
}


8、时间值

两类时间:日历时间、进程时间

  日历时间,表示自1970.1.1零点以来UTC的秒数累计

  进程时间,用以度量进程对CPU资源的占用

进程时间的度量:时钟时间、用户 CPU 时间、系统 CPU 时间

  时钟时间的取值与系统活动有关

示例,使用 time 命令度量进程的时间占用

  time find / -name a.txt

 

9、系统调用与库函数

应用程序可以调用库函数或系统调用
很多库函数也调用系统调用,如: printf () 调用 write()
库函数在用户空间执行,如: strcpy () atoi ()
系统调用在内核空间执行,如: fork() exec()
应用开发中通常无需区分
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值