linux高级编程补充知识

F: 计算机系统结构:

-------------------------------

应用程序

-----------------

|  库函数

-------------------------------

系统调用

-------------------------------

虚拟文件系统  |    进程模块

-(文件模块)-|   进程间通信

设备文件     |

-------------------------------

硬 件

-------------------------------

G: 内存结构划分(32b)/存储空间分配:

用户空间3G:代码区,字符串常量区,数据区,堆,栈stack

内核空间1G

H: 系统数据文件:

/etc/passwd:用户相关的信息/用户的数据信息

eg:root:x:0:0:root:/root:/bin/bash,用‘:’进行分割

用户者:密码占位符:用户的id:用户所在组的id:用户的描述信息:用户的家目录:用户登录后默认使用的shell(shell 应用程序,作用:命令行解释器)

h1: /etc/group:组的相关信息

eg:bin:x:1:bin,daemon

组名:组密码占位符:组id:组成员

h2: 用户相关操作:

struct passwd *getpwnam(const char *name);

struct passwd *getpwuid(uid_t uid);

struct passwd *getpwent(void);

void setpwent(void);//定位到文件开头,反转

void endpwent(void);

h3: 组相关操作:

struct group *getgrnam(const char *name);

struct group *getgrgid(gid_t gid);

I: 启动例程:

命令行参数:字符串的处理

argv----字符串的数组;argv[argc] == NULL

J: 位运算:

bit 0/1

& |

00  0 0

01  0 1

10  0 1

11  1 1

一个bit跟0相与& 结果是0;跟1相与&,结果是他本身.

一个bit跟0相或| 结果是他本身;跟1相或|,结果是1.

K: 设置文件权限(权限的掩码)

mode_t umask(mode_t mask);

系统调用

permission & ~umask

regular file 0666 & ~0022

0b110 110 110

0b000 010 010/0b111 101 101 取反做与

& 0b110 100 100  0644

linux系统提供的umask命令跟umask()系统调用的作用是一样的

k1: int chmod(const char *path, mode_t mode);

int fchmod(int fd, mode_t mode);

改变文件的存取许可权限

linux系统提供的chmod命令跟chmod()系统调用作用是一样的

k2: int chown(const char *path, uid_t owner, gid_t group);

int fchown(int fd, uid_t owner, gid_t group);

int lchown(const char *path, uid_t owner, gid_t group);

改变文件的用户ID uid和组ID gid

chown 命令改变文件的属主owner和属组group

k3: int truncate(const char *path, off_t length);

int ftruncate(int fd, off_t length);

将文件的长度截短为length

如果当前文件的长度要是小于我们的length,其结果与系统有关.

将文件截短为0时,它属于一个特例,与open或creat调用设定O_TRUNC标志是一样的.

L: 硬链接以及硬链接的限制条件

1.堆目录不能硬链接

2.硬链接不能跨文件系统/硬链接不能跨磁盘分区

l1: link 创建硬链接

int link(const char *oldpath, const char *newpath);

symlink 创建符号链接 软链接 快捷方式

int symlink(const char *oldpath, const char *newpath);

int unlink(const char *pathname);

删除文件名,有可能会删除文件(当硬链接数/inode里的引用计数为0的时候,会删除文件)

M: rm remove cd 路径;rm 文件

int remove(const char *pathname);

m1: rename

int rename(const char *oldpath, const char *newpath);

m2: mkdir

int mkdir(const char *pathname, mode_t mode);

m3: rmdir

int rmdir(const char *pathname);

针对空目录进行删除.

N: 时间和日期

time() get time in seconds

time_t time(time_t *t);

1.出参

2.返回值

char *ctime(const time_t *timep);

eg: "Wed Jun 30 21:49:08 1993\n"

struct tm *localtime(const time_t *timep);    返回值是结构体指针

time_t mktime(struct tm *tm);

char *asctime(const struct tm *tm);

n1: 时间的字符串表达

^ ^

| |asctime

|

| struct tm-------->

| ^  |

|ctime |localtime  |mktime

| |  |

^---------time_t<---------

^

|time

|

内核kernel

O: 堆heap

malloc

free

char *ptr;

char *p;

ptr =malloc(1024*sizeof(char));

....

p=ptr+512;

o1: 元数据 metadata

void *realloc(void *ptr, size_t size);//增加空间

P: 前台/后台:

命令 & :表示后台运行

fg 后台进程调入到前台运行  eg:fg %1

bg 前台进程调入到后台运行  eg:bg %1

jobs 查看后台作业/进程

Q: linux如何运行一个程序/如何执行execvp?

1.将指定的程序/可执行文件加载/复制到调用exec的进程

2.将给定的字符串数组作为argv传给这个程序

3.运行这个程序

R:  status分为3部分:exit返回值(8b);异常退出号(7b);内核映像(core dump)(1b)

S: 目录块/目录项(inode号和名d_name)

数据块

inode节点表/inode节点数组

T: 自顶向下的程序设计方法

分文件:函数数量多的时候,会根据函数的类型分文件

头文件:宏定义;全局变量的声明;结构体类型的定义;函数的声明

分函数:一个函数中代码数量多的时候,会跟据完成的任务、功能分函数(每个函数的代码是1-15行)

分函数通常只做方法处理,数据的输入和打印输出通常在主函数中完成

t1: #include"strcpypt.h"   // “”----> 当前目录下优先查找

#include<string.h>   // <>----> 在环境变量PATH制定的目录下优先查找

t2: #ifndef   //防止头文件被重复的包含

U: 服务/客户:

bc----计算器命令(bc----客户;dc----服务)

bc是dc的预处理

bc提供界面处理,使用dc提供的服务,bc是dc的客户

bc和dc两者之间是独立的程序

双向通信

V: 普通文件

竞态文件

文件锁/记录锁

fcntl----改变已打开的文件的性质

加读数据的锁

void set_read_lock(int fd)

{

struct flock lockinfo;

lockinfo.l_type = F_RDLCK;

lockinfo.l_whence = SEEK_SET;

lockinfo.l_start = 0;

lockinfo.l_len = 0;

lockinfo.l_pid = getpid();

fcntl(fd,F_SETLKW,&lockinfo);

lockinfo.l_type = F_RDLCK;

}

加写数据的锁:

void set_read_lock(int fd)

{

struct flock lockinfo;

lockinfo.l_type = F_WRLCK;

lockinfo.l_whence = SEEK_SET;

lockinfo.l_start = 0;

lockinfo.l_len = 0;

lockinfo.l_pid = getpid();

fcntl(fd,F_SETLKW,&lockinfo);

lockinfo.l_type = F_RDLCK;

}

解锁:

void set_read_lock(int fd)

{

struct flock lockinfo;

lockinfo.l_type = F_UNLCK;

lockinfo.l_whence = SEEK_SET;

lockinfo.l_start = 0;

lockinfo.l_len = 0;

lockinfo.l_pid = getpid();

fcntl(fd,F_SETLKW,&lockinfo);

lockinfo.l_type = F_RDLCK;

}

W: 函数名---函数的地址/函数的指针

指针----1,地址  2,指针变量

X: 设备文件:

x1: 串口/终端:

处理进程和外部设备之间的数据流的内核子程序的集合----被称为终端驱动程序/tty(TeleTYpe)驱动程序

读取终端驱动程序的属性:

int tcgetattr(int fd, struct termios *termios_p);

设置终端驱动程序的属性:

int tcsetattr(int fd, int optional_actions,const struct termios *termios_p);

TCSANOW:立即更新驱动程序的设置

结构体 termios:------------------保存属性

tcflag_t c_iflag;      /* input modes */-------输入:驱动程序如何处理从终端来的字符

tcflag_t c_oflag;      /* output modes */-------输出:驱动程序如何处理流向终端的字符

tcflag_t c_cflag;      /* control modes */--------控制:字符如何被表示(位的个数,停止位等)

tcflag_t c_lflag;      /* local modes */-------本地:驱动程序如何处理来自驱动程序内部的字符

cc_t     c_cc[NCCS];   /* control chars */

=============================================================================================================

书写步骤:

struct termois attribs;   //保存属性

tcgetattr(fd,&attribs);   //获取当前属性

//修改:

测试位:if(attribs.flagset & MASK)...

置位:attribs.flagset |= MASK;...

清除位:attribs.flagset &|= ~MASK;...

tcsetattr(fd,TCSANOW,&attribs);   //写回属性

-------------------------------------------------------------------------------------------------------------

总结:

改变终端驱动程序的设置:(Read--Mddify--Write)

1.读取:从驱动程序中获取当前的属性

2.修改:修改所要修改的属性

3.写回:将修改后的属性去回写到驱动程序

-------------------------------------------------------------------------------------------------------------

===============================================================================================================

时间: 2024-08-24 11:13:38

linux高级编程补充知识的相关文章

unix环境高级编程基础知识之第一篇

陆陆续续看完了圣经第一章,熟悉了unix的整个编程流程,c语言的用处在这里得到伸张. 从unix的体系结构,原来操作系统包括内核及一些其他软件,我们常常误称为linux内核为操作系统,这俨然成为一种共识.基本熟悉了shell的介绍,主流的是bash(Bourne-again shell),unix的文件的基本操作,出错处理,用户ID,信号(感觉类似windows的消息),时间值,最后还有系统调用和库函数的区别. 自己把这篇的所有代码用vim的敲完了,主要前期是熟悉unix的基本命令编程,大致了解

[转] - Linux网络编程 -- 网络知识介绍

(一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户端        在网络程序中,如果一个程序主动和外面的程序通信,那么我们把这个程序称为客户端程序. 比如我们使用ftp程序从另外一        个地方获取文件的时候,是我们的ftp程序主动同外面进行通信(获取文件), 所以这个地方我们的ftp程序就是客户端程序. 服务端        和客户端相

unix环境高级编程基础知识之第二篇(3)

看了unix环境高级编程第三章,把代码也都自己敲了一遍,另主要讲解了一些IO函数,read/write/fseek/fcntl:这里主要是c函数,比较容易,看多了就熟悉了.对fcntl函数讲解比较到位,它可以得到和改变打开文件的属性(只读,只写等等,注意后面和stat区别),下面记录了自己在学习的时候一些命令及概念,供学习使用: ls 命令的含义是list显示当前目录中的文件名字.注意不加参数它显示除隐藏文件外的所有文件及目录的名字. 1)ls –a 显示当前目录中的所有文件,包含隐藏文件. 2

Linux——高级编程之概要

1.为什么要学习Linux下的高级编程 应用课程的学习,不知道Linux内核的强大功能 Linux下的高级编程课程学习:感知到内核的存在,内核的强大功能 文件管理 进程管理 设备管理 内存管理 网络管理 2.怎么样学习Linux下的高级编程 Linux下高级编程的特点:涉及到内核向用户空间提供的接口(函数) 3.为什么内核要提供这些接口呢 主要原因: A:内核要为应用程序服务,应用程序如果没有内核服务,则功能非常单一 B:内核是一个稳定的代码,同时也要为多个用户空间的程序服务,为了防止用户空间的

Linux Shell编程基本知识

Shell是Linux提供的一种脚本语言,可以完成部分编程操作.从根本上讲Shell仅仅是一个命令解释器,而Shell脚本也就是一个由命令和一些简单的逻辑判断的堆砌. 所以说学好Shell脚本最重要的因素就是熟悉基本命令的使用.并掌握一些Shell逻辑判断的语句. 写一个shell脚本首先要声明shebang,也就是:   #!/bin/bash 由于Shell可能涉及的东西比较多,我这里只给大家列出来一些常用的东西: 1.命令执行状态结果: #判断语句的关键  0        #执行成功  

Linux高级编程--02.gcc和动态库

在Linux环境下,我们通常用gcc将C代码编译成可执行文件,如下就是一个简单的例子: 小实验:hello.c #include <stdlib.h> #include <stdio.h> void main(void) { printf("hello world!\r\n"); } 可以通过如下指令来编译出一个可执行文件: gcc hello.c 执行完该命令后,就会得到一个a.out的可执行文件. 编译的过程 前面的例子只是简单的介绍了一下gcc的使用方法,

Linux高级编程--05.文件读写

缓冲I/O和非缓冲I/O 文件读写主要牵涉到了如下五个操作:打开.关闭.读.写.定位.在Linux系统中,提供了两套API, 一套是C标准API:fopen.fclose.fread.fwrite.fseek, 另一套则是POSIX定义的系统API:open.close.read.write.seek. 其中POSIX定义的API是系统API,而C标准API是基于系统API的封装,并且提供了额外的缓冲的功能.因此也可以把它们叫做缓冲I/O函数和非缓冲I/O函数. 除了前面介绍的这几个缓冲IO函数

Linux高级编程--01.vi命令

VI是Linux/Unix下标配的一个纯字符界面的文本编辑器.由于不支持鼠标功能,也没有图形界面,相关的操作都要通过键盘指令来完成,需要记忆大量命令.因此很多人不大喜欢它,但同时由于键盘的方式往往比鼠标来得快,一旦熟练后用起来是有种非常流畅的感觉的,也有人因此而非常喜欢它. 不管你喜欢也好,不喜欢也好,VI是Linux的标配编辑器,很多时候你也只有这一个编辑器可用,如果要做一个Linux Coder,熟悉VI还是非常有必要的. PS:由于VI的命令非常多,本文主要只介绍一些基础命令.并且就算是这

Linux高级编程--10.Socket编程

Linux下的Socket编程大体上包括Tcp Socket.Udp Socket即Raw Socket这三种,其中TCP和UDP方式的Socket编程用于编写应用层的socket程序,是我们用得比较多的,而Raw Socket则用得相对较少,不在本文介绍范围之列. TCP Socket 基于TCP协议的客户端/服务器程序的一般流程一般如下: 它基本上可以分为三个部分: 一.建立连接: 服务器调用socket().bind().listen()完成初始化后,调用accept()阻塞等待,处于监听