zoukankan      html  css  js  c++  java
  • linux之操作磁盘文件与tty设备文件

       stty用于改变和显示终端的设置信息,准确的说是改变终端驱动程序的设置信息.tty的驱动程序位于内核,内核用于连接外部世界(磁盘文件、设备文件)与进程间的数据交换.而tty也属于设备文件中的一种,

       现在介绍两种操作磁盘文件的方式,分别采用系统的函数调用和C语言的库函数调用.

         第一种:系统库函数

      

    #include <stdio.h>
    #include <fcntl.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    
    #define LENGTH 100
    
    int main()
    {
    
    	int fd,len;
    	char str[LENGTH];
    	char *content="undergrowth";
    	fd=open("un.txt",O_CREAT | O_RDWR,S_IRUSR|S_IWUSR);
     	if(fd)
    	{
    		write(fd,content,strlen(content));
    		close(fd);
    	}else
    	{
    		exit(0);
    	}
    	fd=open("un.txt",O_RDONLY);
    	len=read(fd,str,LENGTH);
    	printf("%s
    ",str);
    	close(fd);
    	return 0;
    }
    
     使用 gcc -Wall hello.c -o un 编译即可 运行 ./un

      上面使用open以所有者可读可写的权限来操作un.txt文件  使用write写完数据后 关闭文件描述符


    第二种方式:C语言的库函数

      

    #include <stdio.h>
    
    #define  LENGTH 100
    
    
    int main()
    {
    	FILE *fd;
    	char str[LENGTH];
    	char *content="undergrowth";
    	fd=fopen("un.txt","w+");
    	if(fd)
    	{
    		fputs(content,fd);
    		fclose(fd);
    	}
    
    	fd=fopen("un.txt","r");
    	fgets(str,LENGTH,fd);
    	printf("%s
    ",str);
    	fclose(fd);
    	return 0;
    }
    

       使用 gcc -Wall hello.c -o un 编译即可 运行 ./un

    上面使用fopen以读写的方式打开un.txt,如果不存在,则进行创建,然后使用fputs向磁盘文件中写入数据,之后在使用fgets从磁盘文件中获取LENGTH长度的字符放入str字符数组中


      接下来介绍tty设备文件

       磁盘文件与设备文件有很多相似的地方,比如都有文件的属性、文件的大小、文件的修改时间、文件的节点等等之类的,都可用系统的库函数与C语言的库函数来进行open、read、write、close、ioctl来进行操作。

      那么内核如何区分文件时磁盘文件还是设备文件呢?

        这里就要看磁盘文件和设备文件共有的一个属性即文件节点,当内核要准备为文件读数据时,首先会看文件的文件节点属性,如果文件节点对应的是磁盘文件的话,则直接根据文件系统的映射表读取数据,如果是设备文件的话,则会调用设备文件的驱动程序的read方法进行读取.

      磁盘文件在进行读写的时候是有缓冲区的,而设备文件是没有缓冲区的.

      而对于tty设备文件,我们可以通过tcgetattr、tcsetattr来对其驱动程序的属性进行读取和重新设置,从而影响其正常的工作.

    下面是一个显示tty驱动设备的属性的小程序,只显示了几个比较重要的属性,更多的可以使用man tcgetattr来进行查看

    #include <stdio.h>
    #include <termios.h>
    #include <stdlib.h>
    
    
    #define eops(s,x) {perror(s); exit(x);}
    
    int main()
    {
    	struct termios ttyinfo;
    	void showbaud(int);
    	void show_someflag(struct termios *);
    	if((tcgetattr(0,&ttyinfo))==-1) eops("tcgetattr",1); //获取到当前终端的设置信息保存在ttyinfo结构体中
    	showbaud(cfgetospeed(&ttyinfo)); //显示输出波特率
    	printf("the erase charcter is ascii %d,Ctrl-%c
    ",ttyinfo.c_cc[VERASE],ttyinfo.c_cc[VERASE]);
    	show_someflag(&ttyinfo); //显示当前终端的一些设置信息
    	return 0;
    }
    
    
    void showbaud(int speed)
    {
    	printf("the baud rate is %d .
    ",speed);
    }
    
    struct flaginfo { //用于保存属性名及其描述
    	int fl_value;
    	char *fl_desc;
    };
    
    struct flaginfo input_flag[]={  //构建输入属性
    	{IGNBRK,"ignore break condition"},
    	{INLCR,"map nl to cr on input"},
    	{IXOFF,"enable start/stop input control"},
    	{0,NULL}
    };
    
    
    struct flaginfo output_flag[]={ //构建输出属性
    	{OLCUC,"map lowercase character to uppercase character on output"},
    	{0,NULL}
    };
    
    struct flaginfo local_flag[]={//构建本地属性
    	{ECHO,"echo input character"},
    	{ISIG,"when any on character intr,quit,susp or dsusp are received,generate the corresponing the signal"},	
    	{0,NULL}
    };
    
    struct flaginfo control_flag[]={//构建控制属性
    	{CREAD,"enalbe receiver"},
    	{CRTSCTS,"enable rts/cts flow control"},
    	{0,NULL}
    };
    
    
    
    void show_flagset(int thevalue,struct flaginfo fi[]) 
    {
    	int i;
    	for(i=0;fi[i].fl_value;i++)
    		{
    			printf(" %s is ",fi[i].fl_desc);
    			if(fi[i].fl_value&thevalue) printf("on.
    ");  //判断该属性是否已经打开
    			else printf("off.
    ");
    		}
    }
    
    void show_someflag(struct termios *termios_p) 
    {
    	printf("display some flag as follow:
    ");
    	show_flagset(termios_p->c_iflag,input_flag);
    	show_flagset(termios_p->c_oflag,output_flag);
    	show_flagset(termios_p->c_lflag,local_flag);
    	show_flagset(termios_p->c_cflag,control_flag);
    }
    


      还有一个是两个终端进行相互通信

    #include <stdio.h>
    #include <fcntl.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    
    
    //#define BUFSIZ 30
    
    int main(int argc,char *argv[])
    {
    	int fd;
    	char buf[BUFSIZ];
    	if(argc!=2)
    	{
    		perror("usage:write ttyname.
    ");
    		exit(1);
    	}
    	fd=open(argv[1],O_WRONLY); //获取另外一个终端的名字
    	if(fd==-1)
    		{
    		 perror(argv[1]);
    		exit(1);
    		}
    	while(fgets(buf,BUFSIZ,stdin)!=NULL)//从当前终端获取信息
    	{
    	if(write(fd,buf,strlen(buf))==-1) break; //将信息写入到另外一个终端
    	}
    	close(fd);
    	return 0;
    }
    


  • 相关阅读:
    JavaScript cookie详解
    Javascript数组的排序:sort()方法和reverse()方法
    javascript中write( ) 和 writeln( )的区别
    div做表格
    JS 盒模型 scrollLeft, scrollWidth, clientWidth, offsetWidth 详解
    Job for phpfpm.service failed because the control process exited with error code. See "systemctl status phpfpm.service" and "journalctl xe" for details.
    orm查询存在价格为空问题
    利用救援模式破解系统密码
    SSH服务拒绝了密码
    C# 调用 C++ DLL 中的委托,引发“对XXX::Invoke类型的已垃圾回收委托进行了回调”错误的解决办法
  • 原文地址:https://www.cnblogs.com/liangxinzhi/p/4275605.html
Copyright © 2011-2022 走看看