Linux程序开发环境:Linux程序设计 入门、文件操作和环境_第1页
Linux程序开发环境:Linux程序设计 入门、文件操作和环境_第2页
Linux程序开发环境:Linux程序设计 入门、文件操作和环境_第3页
Linux程序开发环境:Linux程序设计 入门、文件操作和环境_第4页
Linux程序开发环境:Linux程序设计 入门、文件操作和环境_第5页
已阅读5页,还剩45页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

CentralSouthUniversityLinux程序设计环境CH09Linux程序设计I入门、文件操作和环境回顾Linux内核中进程的基本概念进程管理作业管理Linux内核中的文件机制硬链接和符号链接本章目标Linux程序设计入门文件操作Linux环境Linux程序设计入门Linux应用程序分为两类:可执行程序(executables)脚本(scripts)Linux系统下常用文本编辑器:vi/vimemacsC语言编译器:gccLinux程序设计入门emacs文本编辑器第一个LinuxC程序/*helloworld.c*/#include<stdio.h>#include<stdlib.h>intmain(){ printf(”HelloWorld\n”); exit(0);}$gcc-ohelloworldhelloworld.c$./helloworldHelloWorld$编译执行确保已安装有gcc-o选项用于指定编译后的文件名如不指定则默认生成a.out./用于指定路径常用文件路径-1应用程序系统提供的应用程序一般在/usr/bin或/usr/local/bin中。头文件基本头文件在/usr/include,附加头文件一般在/usr/include/sys或/usr/include/linux中。使用gcc的-I选项可以引入不在默认路径中的头文件。如:$gcc-I/usr/openwin/includehello.c常用文件路径-2库文件标准库文件一般位于/lib或/usr/lib。库文件可以分为静态库(.a)和共享库(.so)。库文件的命名规范:以lib开头,后面部分指明库功能,后缀名说明库类型。gcc的-l选项可以指定要搜索的库文件、-L选项指定库路径。如:gcc-ohellohello.c/usr/lib/libm.agcc-ohellohello.c-lmgcc-ohellohello.c-L/usr/lib-l/usr/temp/lib/x.aLinux程序设计基本概念用户程序库系统调用设备驱动程序硬件文件操作Linux只需少量函数就可以实现对文件和设备的访问和控制,这些函数被称为系统调用。系统调用由Linux系统直接提供,是通向操作系统自身的接口。Linux系统提供5个系统调用:open、write、read、close、iotcl。Linux的核心部分是内核,内核由一组设备驱动程序组成,完成系统对硬件的访问和控制。为了向用户提供统一的接口,设备驱动程序封装了所有与硬件相关的特性。硬件的特有功能一般通过系统调用iotcl来完成。为了给设备和磁盘文件提供更高层的接口,Linux的各发行版一般提供一系列的标准函数库。文件操作系统调用1.write系统调用write系统调用的原型为:其功能为:将缓冲区buf的前nbytes个字节写入文件描述符fildes关联的文件中,返回实际写入的字节数(如果fileds有错或者大小不够返回将小于nbytes,返回0表示未写入任何数据,返回-1表示写入过程错误)。范例:#include<unistd.h>size_twrite(intfildes,constvoid*buf,size_tnbytes);#include<unistd.h>#include<stdlib.h>intmain(){ if((write(1,“Hereissomedata\n”,18))!=18) write(2,“Awriteerrorhasoccurredonfiledescriptor1\n”,46); exit(0);}文件操作系统调用2.read系统调用read系统调用的原型为:其功能为:从文件描述符fildes关联的文件中读入nbytes个字节,并放入缓冲区buf中,返回实际读入的字节数(有可能小于nbytes,返回0表示未读入数据已到文件尾,返回-1表示读入错误)。范例#include<unistd.h>size_tread(intfildes,void*buf,size_tnbytes);#include<unistd.h>#include<stdlib.h>intmain(){ charbuffer[128]; intnread; nread=read(0,buffer,128); if(nread==-1) write(2,“Areaderrorhasoccurred\n”,26); if((write(1,buffer,nread))!=nread) write(2,“Awriteerrorhasoccurred\n”,27); exit(0);}文件操作系统调用3.open系统调用open系统调用的原型为:open系统调用创建一个新的文件描述符,如果调用成功将返回一个可以被read、write和其他系统调用使用的文件描述符。准备打开的设备或文件作为参数path传递给函数,oflags参数用于指定打开文件所采取的动作。open调用成功时返回的文件描述符总是当前未用的最小值的文件描述符,失败时返回-1。oflags的取值必须为表中的某一个和其他的可选值:#include<fcntl.h>#include<sys/types.h>#include<sys/stat.h>intopen(constchar*path,intoflags);intopen(constchar*path,intoflags,mode_tmode);文件操作系统调用4.close系统调用和ioctl系统调用close系统调用的原型为:ioctl系统调用的原型为:范例:打开键盘上LED灯(如果有)#include<unistd.h>intclose(intfildes);#include<unistd.h>intioctl(intfildes,intcmd,...);ioctl(tty_fd,KDSETLED,LED_NUM|LED_CAP|LED_SCR);综合案例-1一个文件复制程序/*预先准备好文件file.in,大小不超过1MB*/#include<unistd.h>#include<sys/stat.h>#include<fcntl.h>#include<stdlib.h>intmain(){ charc; intin,out; in=open(“file.in”,O_RDONLY); out=open(“file.out”,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR); while(read(in,&c,1)==1) write(out,&c,1); exit(0);}$TIMEFORMAT=”“time./copy_system4.67user146.90system2:32.57elapsed99%CPU...$ls-lsfile.infile.out1029-rw-r---r-1neilusers1048576Sep1710:46file.in1029-rw-------1neilusers1048576Sep1710:51file.out综合案例-2一个文件复制程序#include<unistd.h>#include<sys/stat.h>#include<fcntl.h>#include<stdlib.h>intmain(){ charblock[1024]; intin,out; intnread; in=open(“file.in”,O_RDONLY); out=open(“file.out”,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR); while((nread=read(in,block,sizeof(block)))>0) write(out,block,nread); exit(0);}$rmfile.out$TIMEFORMAT=”“time./copy_block0.00user0.02system0:00.04elapsed78%CPU标准I/O库标准I/O库(stdio)及其头文件stdio.h为底层I/O系统调用提供了统一的接口。该库已成为ANSI标准C的一部分。使用stdio和使用底层文件描述符一样,需要先打开一个文件以建立一个访问路径。这个操作的返回值将作为其他I/O库函数的参数。在stdio中与底层文件描述符对应的是流(stream),被实现为指向结构FILE的指针。常用的I/O标准库函数有:fopen,close,fread,write,fflush,fseek,fgetc,getc,getchar,fputc,putc,putchar,fgets,gets,printf,fprintf,andsprintf,scanf,fscanf,sscanf综合案例-3一个文件复制程序#include<stdio.h>#include<stdlib.h>intmain(){ intc; FILE*in,*out; in=fopen(“file.in”,”r”); out=fopen(“file.out”,”w”); while((c=fgetc(in))!=EOF) fputc(c,out); exit(0);}$TIMEFORMAT=”“time./copy_stdio0.06user0.02system0:00.11elapsed81%CPU向程序传递参数main函数参数Linux系统中完整的main函数(C语言)声明为:其中argc表示参数的个数,argv数组用户保存参数的值。如有:

argc:4 argv:{“myprog”,“left”,“right”,“andcenter”}Linux中程序的参数一般以“-”开始,后面包含单个字母或数字,并允许合并。intmain(intargc,char*argv[])$myprogleftright‘andcenter’Linux程序设计环境Linux中程序运行的环境,主要包括:向程序传递参数环境变量查看时间临时文件获取用户和主机的信息生成和配置日志信息了解系统中各项资源的限制向程序传递参数main函数参数使用范例intmain(intargc,char*argv[])#include<stdio.h>#include<stdlib.h>intmain(intargc,char*argv[]){ intarg; for(arg=0;arg<argc;arg++){ if(argv[arg][0]==‘-‘) printf(“option:%s\n”,argv[arg]+1); else printf(“argument%d:%s\n”,arg,argv[arg]); } exit(0);}$./args-i-lr‘hithere’-ffred.cargument0:./argsoption:ioption:lrargument3:hithereoption:fargument5:fred.c向程序传递参数getopt函数的使用为了使传递参数更加规范,Linux标准库提供getopt()来完成参数的传递。getopt()函数的原型为:getopt()将传递给main()的argc和argv作为参数,同时接受一个选项指定符字符串optstring。optstring是一个字符列表,每个字符代表一个单字符选项,如果一个字符后跟一个”:”号,则表明该选项需要一个关联值。如:#include<unistd.h>intgetopt(intargc,char*constargv[],constchar*optstring);externchar*optarg;externintoptind,opterr,optopt;getopt(argc,argv,“if:lr”);向程序传递参数getopt函数的使用范例(功能和前一范例相同)intmain(intargc,char*argv[]){ intopt; while((opt=getopt(argc,argv,“:if:lr”))!=-1){ switch(opt){ case‘i’:case‘l’:case‘r’: printf(“option:%c\n”,opt);break; case‘f’: printf(“filename:%s\n”,optarg);break; case‘:’: printf(“optionneedsavalue\n”);break; case‘?’: printf(“unknownoption:%c\n”,optopt);break; } } for(;optind<argc;optind++) printf(“argument:%s\n”,argv[optind]); exit(0);}环境变量Linux规范为各种应用定义了许多标准环境变量,包括终端类型、默认的编辑器、时区信息等。C语言程序可以通过putenv()和getenv()两个函数来访问环境变量。其函数原型为:#include<stdlib.h>char*getenv(constchar*name);intputenv(constchar*string);环境变量putenv()和getenv()使用范例该范例打印出所选的任意环境变量的值,如果给程序传递第二个参数则设置环境变量的值。

(1)首先确保程序只带有一个或两个参数:#include<stdlib.h>#include<stdio.h>#include<string.h>intmain(intargc,char*argv[]){ char*var,*value; if(argc==1||argc>3){ fprintf(stderr,”usage:environvar[value]\n”); exit(1); }环境变量putenv()和getenv()使用范例

(2)然后调用getenv()取出环境变量的值: var=argv[1]; value=getenv(var); if(value) printf(“Variable%shasvalue%s\n”,var,value); else printf(“Variable%shasnovalue\n”,var);环境变量putenv()和getenv()使用范例

(3)接下来检查程序是否有第二个参数,如果有则调用putenv()设置环境变量的值:

if(argc==3){ char*string; value=argv[2]; string=malloc(strlen(var)+strlen(value)+2); if(!string){ fprintf(stderr,”outofmemory\n”); exit(1); } strcpy(string,var); strcat(string,”=”); strcat(string,value); printf(“Callingputenvwith:%s\n”,string); if(putenv(string)!=0){ fprintf(stderr,”putenvfailed\n”); free(string); exit(1); }环境变量putenv()和getenv()使用范例

(4)再次调用getenv()查看新设置的环境变量的值:

value=getenv(var); if(value) printf(“Newvalueof%sis%s\n”,var,value); else printf(“Newvalueof%sisnull??\n”,var); } exit(0);}环境变量putenv()和getenv()使用范例

(5)程序的运行结果为:$./environHOMEVariableHOMEhasvalue/home/neil$./environFREDVariableFREDhasnovalue$./environFREDhelloVariableFREDhasnovalueCallingputenvwith:FRED=helloNewvalueofFREDishello$./environFREDVariableFREDhasnovalue日期和时间获取日期和时间对Linux中的应用程序是很重要的功能。Linux中时间通过一个预定义的time_t来处理,time_t为长整型,与处理时间的函数一起定义在头文件time.h中。time函数用于获取底层的时间值,其原型为:返回值单位为秒,如果tloc不是空指针,time()还会将这个值写入到*tloc。#include<time.h>time_ttime(time_t*tloc);日期和时间time()使用范例#include<time.h>#include<stdio.h>#include<unistd.h>#include<stdlib.h>intmain(){ inti; time_tthe_time; for(i=1;i<=10;i++){ the_time=time((time_t*)0); printf(“Thetimeis%ld\n”,the_time); sleep(2); } exit(0);}$./envtimeThetimeis1179643852Thetimeis1179643854Thetimeis1179643856Thetimeis1179643858Thetimeis1179643860Thetimeis1179643862Thetimeis1179643864Thetimeis1179643866Thetimeis1179643868Thetimeis1179643870日期和时间difftime()函数用于计算两个时间之间的差距。其原型为:gmtime()函数用于设定时间为特定格式。其原型为:结构体tm的成员包括:#include<time.h>doubledifftime(time_ttime1,time_ttime2);#include<time.h>structtm*gmtime(consttime_ttimeval);日期和时间difftime()和gmtime()使用范例:打印当前时间和日期。#include<time.h>#include<stdio.h>#include<stdlib.h>intmain(){ structtm*tm_ptr; time_tthe_time; (void)time(&the_time); tm_ptr=gmtime(&the_time); printf(“Rawtimeis%ld\n”,the_time); printf(“gmtimegives:\n”); printf(“date:%02d/%02d/%02d\n”, tm_ptr->tm_year,tm_ptr->tm_mon+1,tm_ptr->tm_mday); printf(“time:%02d:%02d:%02d\n”, tm_ptr->tm_hour,tm_ptr->tm_min,tm_ptr->tm_sec); exit(0);}日期和时间difftime()和gmtime()使用范例:程序运行结果。$./gmtime;dateRawtimeis1179644196gmtimegives:date:107/05/20time:06:56:36SunMay2007:56:37BST2007临时文件临时文件是Linux系统一种重要的数据保存方式,常用于保存计算的中间结果、关键操作前的文件备份等。在Linux的多用户环境下,需要确保临时文件的文件名的唯一性。函数tmpnam()用于生成一个唯一的文件名。其原型为:在需要立刻使用临时文件时,可以使用tmpfile()函数在给其命名的同时将其打开。其原型为:#include<stdio.h>char*tmpnam(char*s);#include<stdio.h>FILE*tmpfile(void);临时文件tmpnam()和tmpfile()使用范例。#include<stdio.h>#include<stdlib.h>intmain(){ chartmpname[L_tmpnam]; char*filename; FILE*tmpfp; filename=tmpnam(tmpname); printf(“Temporaryfilenameis:%s\n”,filename); tmpfp=tmpfile(); if(tmpfp) printf(“OpenedatemporaryfileOK\n”); else perror(“tmpfile”); exit(0);}$./tmpnamTemporaryfilenameis:/tmp/file2S64zcOpenedatemporaryfileOK用户信息Linux中程序可以通过getuid()和getlogin()函数来获取用户的相关信息。其原型为:Linux中还提供另一种更通用和有效的获取用户信息的编程接口,即getpwuid()和getpwnam()函数。其原型为:#include<sys/types.h>#include<unistd.h>uid_tgetuid(void);char*getlogin(void);#include<sys/types.h>#include<pwd.h>structpasswd*getpwuid(uid_tuid);structpasswd*getpwnam(constchar*name);用户信息其中passwd结构体的成员如下表所示:用户信息获取用户信息范例。#include<sys/types.h>#include<pwd.h>#include<stdio.h>#include<unistd.h>#include<stdlib.h>intmain(){ uid_tuid; gid_tgid; structpasswd*pw; uid=getuid(); gid=getgid(); printf(“Useris%s\n”,getlogin()); printf(“UserIDs:uid=%d,gid=%d\n”,uid,gid); pw=getpwuid(uid); printf(“UIDpasswdentry:\nname=%s,uid=%d,gid=%d,home=%s,shell=%s\n”, pw->pw_name,pw->pw_uid,pw->pw_gid,pw->pw_dir,pw->pw_shell); pw=getpwnam(“root”); printf(“rootpasswdentry:\n”); printf(“name=%s,uid=%d,gid=%d,home=%s,shell=%s\n”, pw->pw_name,pw->pw_uid,pw->pw_gid,pw->pw_dir,pw->pw_shell); exit(0);}主机信息与获取用户信息类似,Linux还提供获取主机信息的编程接口,gethostname()和uname()函数。其原型为:其中结构体utsname的成员如下表所示:#include<unistd.h>intgethostname(char*name,size_tnamelen);#include<sys/utsname.h>intuname(structutsname*name);主机信息获取主机信息范例#include<sys/utsname.h>#include<unistd.h>#include<stdio.h>#include<stdlib.h>intmain(){ charcomputer[256]; structutsnameuts; if(gethostname(computer,255)!=0||uname(&uts)<0){ fprintf(stderr,“Couldnotgethostinformation\n”); exit(1); } printf(“Computerhostnameis%s\n”,computer); printf(“Systemis%son%shardware\n”,uts.sysname,uts.machine); printf(“Nodenameis%s\n”,uts.nodename); printf(“Versionis%s,%s\n”,uts.release,uts.version); exit(0);}日志信息Linux系统的一个主要特征就是强大的日志功能。应用程序如需向日志文件添加日志信息,可以通过syslog()函数来实现。其原型为:每条信息都有一个priority参数,该参数指定日志的严重级别,预定义的级别如下表所示:#include<syslog.h>voidsyslog(intpriority,constchar*message,args...);日志信息日志信息使用范例该程序的执行结果会在/var/log/messages日志文件的最后添加一行。#include<syslog.h>#include<stdio.h>#include<stdlib.h>intmain(){ FILE*f; f=fopen(“not_here”,”r”); if(!f) syslog(LOG_ERR|LOG_USER,”oops-%m\n”); exit(0);}Jun909:24:50suse103syslog:oops-Nosuchfileordirectory资源和限制Linux系统上运行的程序会收到资源的限制,这种限制可能是硬件方面的物理性限制(如内存)、也可能是系统策略的限制(如CPU运行时间)或具体实现的限制(如整型长度和文件名长度等)。系统策略的限制一般定义在头文件limits.h中。如:资源和限制资源操作方面的限制一般定义在头文件resource.h中。resource.h中还定义了一系列操作这些限制值的编程接口。#include<sys/resource.h>intgetpriority(intwhich,id_twho);intsetpriority(intwhich,id_twho,intpriority);intgetrlimit(intresource,structrlimit*r_limit);intsetrlimit(intresource,conststructrlimit*r_limit);intgetrusage(intwho,structrusage*r_usage);资源和限制资源限制使用范例

(1)包含要用到的头文件:#include<sys/resource.h>#include<sys/types.h>#include<sys/time.h>#include<unistd.h>#include<stdio.h>#include<stdlib.h>#include<math.h>资源和限制资源限制使用范例

(2)work()函数将一

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论