Linux程序開發(fā)環(huán)境:Linux程序設(shè)計 入門、文件操作和環(huán)境_第1頁
Linux程序開發(fā)環(huán)境:Linux程序設(shè)計 入門、文件操作和環(huán)境_第2頁
Linux程序開發(fā)環(huán)境:Linux程序設(shè)計 入門、文件操作和環(huán)境_第3頁
Linux程序開發(fā)環(huán)境:Linux程序設(shè)計 入門、文件操作和環(huán)境_第4頁
Linux程序開發(fā)環(huán)境:Linux程序設(shè)計 入門、文件操作和環(huán)境_第5頁
已閱讀5頁,還剩45頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

CentralSouthUniversityLinux程序設(shè)計環(huán)境CH09Linux程序設(shè)計I入門、文件操作和環(huán)境回顧Linux內(nèi)核中進(jìn)程的基本概念進(jìn)程管理作業(yè)管理Linux內(nèi)核中的文件機(jī)制硬鏈接和符號鏈接本章目標(biāo)Linux程序設(shè)計入門文件操作Linux環(huán)境Linux程序設(shè)計入門Linux應(yīng)用程序分為兩類:可執(zhí)行程序(executables)腳本(scripts)Linux系統(tǒng)下常用文本編輯器:vi/vimemacsC語言編譯器:gccLinux程序設(shè)計入門emacs文本編輯器第一個LinuxC程序/*helloworld.c*/#include<stdio.h>#include<stdlib.h>intmain(){ printf(”HelloWorld\n”); exit(0);}$gcc-ohelloworldhelloworld.c$./helloworldHelloWorld$編譯執(zhí)行確保已安裝有g(shù)cc-o選項用于指定編譯后的文件名如不指定則默認(rèn)生成a.out./用于指定路徑常用文件路徑-1應(yīng)用程序系統(tǒng)提供的應(yīng)用程序一般在/usr/bin或/usr/local/bin中。頭文件基本頭文件在/usr/include,附加頭文件一般在/usr/include/sys或/usr/include/linux中。使用gcc的-I選項可以引入不在默認(rèn)路徑中的頭文件。如:$gcc-I/usr/openwin/includehello.c常用文件路徑-2庫文件標(biāo)準(zhǔn)庫文件一般位于/lib或/usr/lib。庫文件可以分為靜態(tài)庫(.a)和共享庫(.so)。庫文件的命名規(guī)范:以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程序設(shè)計基本概念用戶程序庫系統(tǒng)調(diào)用設(shè)備驅(qū)動程序硬件文件操作Linux只需少量函數(shù)就可以實現(xiàn)對文件和設(shè)備的訪問和控制,這些函數(shù)被稱為系統(tǒng)調(diào)用。系統(tǒng)調(diào)用由Linux系統(tǒng)直接提供,是通向操作系統(tǒng)自身的接口。Linux系統(tǒng)提供5個系統(tǒng)調(diào)用:open、write、read、close、iotcl。Linux的核心部分是內(nèi)核,內(nèi)核由一組設(shè)備驅(qū)動程序組成,完成系統(tǒng)對硬件的訪問和控制。為了向用戶提供統(tǒng)一的接口,設(shè)備驅(qū)動程序封裝了所有與硬件相關(guān)的特性。硬件的特有功能一般通過系統(tǒng)調(diào)用iotcl來完成。為了給設(shè)備和磁盤文件提供更高層的接口,Linux的各發(fā)行版一般提供一系列的標(biāo)準(zhǔn)函數(shù)庫。文件操作系統(tǒng)調(diào)用1.write系統(tǒng)調(diào)用write系統(tǒng)調(diào)用的原型為:其功能為:將緩沖區(qū)buf的前nbytes個字節(jié)寫入文件描述符fildes關(guān)聯(lián)的文件中,返回實際寫入的字節(jié)數(shù)(如果fileds有錯或者大小不夠返回將小于nbytes,返回0表示未寫入任何數(shù)據(jù),返回-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);}文件操作系統(tǒng)調(diào)用2.read系統(tǒng)調(diào)用read系統(tǒng)調(diào)用的原型為:其功能為:從文件描述符fildes關(guān)聯(lián)的文件中讀入nbytes個字節(jié),并放入緩沖區(qū)buf中,返回實際讀入的字節(jié)數(shù)(有可能小于nbytes,返回0表示未讀入數(shù)據(jù)已到文件尾,返回-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);}文件操作系統(tǒng)調(diào)用3.open系統(tǒng)調(diào)用open系統(tǒng)調(diào)用的原型為:open系統(tǒng)調(diào)用創(chuàng)建一個新的文件描述符,如果調(diào)用成功將返回一個可以被read、write和其他系統(tǒng)調(diào)用使用的文件描述符。準(zhǔn)備打開的設(shè)備或文件作為參數(shù)path傳遞給函數(shù),oflags參數(shù)用于指定打開文件所采取的動作。open調(diào)用成功時返回的文件描述符總是當(dāng)前未用的最小值的文件描述符,失敗時返回-1。oflags的取值必須為表中的某一個和其他的可選值:#include<fcntl.h>#include<sys/types.h>#include<sys/stat.h>intopen(constchar*path,intoflags);intopen(constchar*path,intoflags,mode_tmode);文件操作系統(tǒng)調(diào)用4.close系統(tǒng)調(diào)用和ioctl系統(tǒng)調(diào)用close系統(tǒng)調(diào)用的原型為:ioctl系統(tǒng)調(diào)用的原型為:范例:打開鍵盤上LED燈(如果有)#include<unistd.h>intclose(intfildes);#include<unistd.h>intioctl(intfildes,intcmd,...);ioctl(tty_fd,KDSETLED,LED_NUM|LED_CAP|LED_SCR);綜合案例-1一個文件復(fù)制程序/*預(yù)先準(zhǔn)備好文件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一個文件復(fù)制程序#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標(biāo)準(zhǔn)I/O庫標(biāo)準(zhǔn)I/O庫(stdio)及其頭文件stdio.h為底層I/O系統(tǒng)調(diào)用提供了統(tǒng)一的接口。該庫已成為ANSI標(biāo)準(zhǔn)C的一部分。使用stdio和使用底層文件描述符一樣,需要先打開一個文件以建立一個訪問路徑。這個操作的返回值將作為其他I/O庫函數(shù)的參數(shù)。在stdio中與底層文件描述符對應(yīng)的是流(stream),被實現(xiàn)為指向結(jié)構(gòu)FILE的指針。常用的I/O標(biāo)準(zhǔn)庫函數(shù)有:fopen,close,fread,write,fflush,fseek,fgetc,getc,getchar,fputc,putc,putchar,fgets,gets,printf,fprintf,andsprintf,scanf,fscanf,sscanf綜合案例-3一個文件復(fù)制程序#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向程序傳遞參數(shù)main函數(shù)參數(shù)Linux系統(tǒng)中完整的main函數(shù)(C語言)聲明為:其中argc表示參數(shù)的個數(shù),argv數(shù)組用戶保存參數(shù)的值。如有:

argc:4 argv:{“myprog”,“l(fā)eft”,“right”,“andcenter”}Linux中程序的參數(shù)一般以“-”開始,后面包含單個字母或數(shù)字,并允許合并。intmain(intargc,char*argv[])$myprogleftright‘a(chǎn)ndcenter’Linux程序設(shè)計環(huán)境Linux中程序運(yùn)行的環(huán)境,主要包括:向程序傳遞參數(shù)環(huán)境變量查看時間臨時文件獲取用戶和主機(jī)的信息生成和配置日志信息了解系統(tǒng)中各項資源的限制向程序傳遞參數(shù)main函數(shù)參數(shù)使用范例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向程序傳遞參數(shù)getopt函數(shù)的使用為了使傳遞參數(shù)更加規(guī)范,Linux標(biāo)準(zhǔn)庫提供getopt()來完成參數(shù)的傳遞。getopt()函數(shù)的原型為:getopt()將傳遞給main()的argc和argv作為參數(shù),同時接受一個選項指定符字符串optstring。optstring是一個字符列表,每個字符代表一個單字符選項,如果一個字符后跟一個”:”號,則表明該選項需要一個關(guān)聯(lián)值。如:#include<unistd.h>intgetopt(intargc,char*constargv[],constchar*optstring);externchar*optarg;externintoptind,opterr,optopt;getopt(argc,argv,“if:lr”);向程序傳遞參數(shù)getopt函數(shù)的使用范例(功能和前一范例相同)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);}環(huán)境變量Linux規(guī)范為各種應(yīng)用定義了許多標(biāo)準(zhǔn)環(huán)境變量,包括終端類型、默認(rèn)的編輯器、時區(qū)信息等。C語言程序可以通過putenv()和getenv()兩個函數(shù)來訪問環(huán)境變量。其函數(shù)原型為:#include<stdlib.h>char*getenv(constchar*name);intputenv(constchar*string);環(huán)境變量putenv()和getenv()使用范例該范例打印出所選的任意環(huán)境變量的值,如果給程序傳遞第二個參數(shù)則設(shè)置環(huán)境變量的值。

(1)首先確保程序只帶有一個或兩個參數(shù):#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); }環(huán)境變量putenv()和getenv()使用范例

(2)然后調(diào)用getenv()取出環(huán)境變量的值: var=argv[1]; value=getenv(var); if(value) printf(“Variable%shasvalue%s\n”,var,value); else printf(“Variable%shasnovalue\n”,var);環(huán)境變量putenv()和getenv()使用范例

(3)接下來檢查程序是否有第二個參數(shù),如果有則調(diào)用putenv()設(shè)置環(huán)境變量的值:

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); }環(huán)境變量putenv()和getenv()使用范例

(4)再次調(diào)用getenv()查看新設(shè)置的環(huán)境變量的值:

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

(5)程序的運(yùn)行結(jié)果為:$./environHOMEVariableHOMEhasvalue/home/neil$./environFREDVariableFREDhasnovalue$./environFREDhelloVariableFREDhasnovalueCallingputenvwith:FRED=helloNewvalueofFREDishello$./environFREDVariableFREDhasnovalue日期和時間獲取日期和時間對Linux中的應(yīng)用程序是很重要的功能。Linux中時間通過一個預(yù)定義的time_t來處理,time_t為長整型,與處理時間的函數(shù)一起定義在頭文件time.h中。time函數(shù)用于獲取底層的時間值,其原型為:返回值單位為秒,如果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()函數(shù)用于計算兩個時間之間的差距。其原型為:gmtime()函數(shù)用于設(shè)定時間為特定格式。其原型為:結(jié)構(gòu)體tm的成員包括:#include<time.h>doubledifftime(time_ttime1,time_ttime2);#include<time.h>structtm*gmtime(consttime_ttimeval);日期和時間difftime()和gmtime()使用范例:打印當(dāng)前時間和日期。#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()使用范例:程序運(yùn)行結(jié)果。$./gmtime;dateRawtimeis1179644196gmtimegives:date:107/05/20time:06:56:36SunMay2007:56:37BST2007臨時文件臨時文件是Linux系統(tǒng)一種重要的數(shù)據(jù)保存方式,常用于保存計算的中間結(jié)果、關(guān)鍵操作前的文件備份等。在Linux的多用戶環(huán)境下,需要確保臨時文件的文件名的唯一性。函數(shù)tmpnam()用于生成一個唯一的文件名。其原型為:在需要立刻使用臨時文件時,可以使用tmpfile()函數(shù)在給其命名的同時將其打開。其原型為:#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()函數(shù)來獲取用戶的相關(guān)信息。其原型為:Linux中還提供另一種更通用和有效的獲取用戶信息的編程接口,即getpwuid()和getpwnam()函數(shù)。其原型為:#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結(jié)構(gòu)體的成員如下表所示:用戶信息獲取用戶信息范例。#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);}主機(jī)信息與獲取用戶信息類似,Linux還提供獲取主機(jī)信息的編程接口,gethostname()和uname()函數(shù)。其原型為:其中結(jié)構(gòu)體utsname的成員如下表所示:#include<unistd.h>intgethostname(char*name,size_tnamelen);#include<sys/utsname.h>intuname(structutsname*name);主機(jī)信息獲取主機(jī)信息范例#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系統(tǒng)的一個主要特征就是強(qiáng)大的日志功能。應(yīng)用程序如需向日志文件添加日志信息,可以通過syslog()函數(shù)來實現(xiàn)。其原型為:每條信息都有一個priority參數(shù),該參數(shù)指定日志的嚴(yán)重級別,預(yù)定義的級別如下表所示:#include<syslog.h>voidsyslog(intpriority,constchar*message,args...);日志信息日志信息使用范例該程序的執(zhí)行結(jié)果會在/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系統(tǒng)上運(yùn)行的程序會收到資源的限制,這種限制可能是硬件方面的物理性限制(如內(nèi)存)、也可能是系統(tǒng)策略的限制(如CPU運(yùn)行時間)或具體實現(xiàn)的限制(如整型長度和文件名長度等)。系統(tǒng)策略的限制一般定義在頭文件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()函數(shù)將一

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論