学习LINUX下C编程前提是要懂得LINUX。当然除了懂LINUX之外,还要了解一个程序是怎么样在操作系统之上进行运行的。这就需要了解LINUX向上提供了什么。所有这些就是我们通常意义上的SHELL,系统调用API等等,因此基于LINUX的开发程序需要了解这些系统CALL和SHELL。当然这些预定义的SHELL和CALL都非常多,怎么查看呢?两个地方,一个网站,一个手册。这个手册就类似于WINDOWSHELP一样,可以实时查看。使用命令man
【1】 man 是用来格式化显示在线手册的命令。大部分LINUX缺省的软件都带有MAN文档,GNU的工具安装后也会带有MAN文档,这些文档安装在/usr/share/man下
[root@windriver-machine shtest]# ls /usr/share/man/
bg da el eo fi fr.ISO8859-1 hr id it.ISO8859-1 ja man0p man1p man2 man3 man3x man4x man5x man6x man7x man8x man9x nl pl.ISO8859-2 pt ro ru.KOI8-R sk sv zh_CN
cs de en es fr fr.UTF-8 hu it it.UTF-8 ko man1 man1x man2x man3p man4 man5 man6 man7 man8 man9 mann pl pl.UTF-8 pt_BR ru ru.UTF-8 sl tr zh_TW
[root@windriver-machine shtest]#
man是区分章节的,这个章节的内容就是查看的对象它可能是一个SHELL命令,也可能是一个系统函数,还有可能一些其它的东西。LINUX MAN将之分成8类,每个章节打成一个gz 包,分别存放在man1,man2…这些不同的目录下。缺省的类别如下:
1. General Commands
2. System Calls
3. Subroutines
4. Special Files
5. File Formats
6. Games
7. Macros and Conventions
8. Maintenence Commands
可以使用man 1 fork 或者man 2 kill之类方式查看。自己也可以制作相应的文档文件,打包压缩成section.gz放到指定的目录如/usr/share/man/man1下,也可以使用-M指定特定目录。
[root@windriver-machine shtest]# ls /usr/share/man/man1/ |more
:.1.gz
[.1.gz
411toppm.1.gz
a2p.1.gz
a2ps.1.gz
ab.1.gz
ac.1.gz
[root@windriver-machine shtest]# man -a fork
[root@windriver-machine shtest]# man -aw fork
/usr/share/man/man2/fork.2.gz
/usr/share/man/man3p/fork.3p.gz
[root@windriver-machine shtest]# man 3 fork
No entry for fork in section 3 of the manual
[root@windriver-machine shtest]# man 2 fork
[root@windriver-machine shtest]# man -w fork
/usr/share/man/man2/fork.2.gz
[root@windriver-machine shtest]# LANG=zh
[root@windriver-machine shtest]# man -w fork
/usr/share/man/man2/fork.2.gz
[root@windriver-machine shtest]# LANG=de
[root@windriver-machine shtest]# man -w fork
/usr/share/man/man2/fork.2.gz
[root@windriver-machine shtest]# LANG=zh_CN
[root@windriver-machine shtest]# man -w kill
/usr/share/man/man1/kill.1.gz
[root@windriver-machine shtest]# ls -latr /usr/share/man/zh_CN/man
man1/ man8/
[root@windriver-machine shtest]# ls -latr /usr/share/man/zh_CN/man1/
dcraw.1.gz newgrp.1.gz
[root@windriver-machine shtest]# ls -latr /usr/share/man/zh_CN/man1/
\ufffd\u073c\ufffd 32
-rw-r--r-- 1 root root 3304 2007-02-05 dcraw.1.gz
-rw-r--r-- 1 root root 772 2007-04-10 newgrp.1.gz
drwxr-xr-x 4 root root 4096 05-18 00:13 ..
drwxr-xr-x 2 root root 4096 05-18 00:13 .
[root@windriver-machine shtest]# man dcraw
[root@windriver-machine shtest]# man -w dcraw
/usr/share/man/zh_CN/man1/dcraw.1.gz
[root@windriver-machine shtest]# man -w newgrp
/usr/share/man/zh_CN/man1/newgrp.1.gz
[root@windriver-machine shtest]# man -f time
Time::HiRes (3pm) - High resolution alarm, sleep, gettimeofday, interval timers
Time::Local (3pm) - efficiently compute time from local and GMT time
Time::gmtime (3pm) - by-name interface to Perl's built-in gmtime() function
Time::localtime (3pm) - by-name interface to Perl's built-in localtime() function
Time::tm (3pm) - internal object used by Time::gmtime and Time::localtime
time (1) - time a simple command or give resource usage
time (1p) - time a simple command
time (2) - get time in seconds
time (3p) - get time
time (7) - overview of time
time (rpm) - A GNU utility for monitoring a program's use of system resources
time.conf [time] (5) - configuration file for the pam_time module
time.h [time] (0p) - time types
[root@windriver-machine shtest]#
【2】在线man手册,有几个网站比较好 http://linuxmanpages.com/ http://linux.die.net/man/
【3】libc库,在不同的LINUNX发布版本中通常有两种包,一种是以libc6-dev打头的,另一种是glibc-2打头的包,这两种其实都是一样的,只是在不同版本的LINUX/UNIX中叫法不一样,前者主要是Debian/ubuntu,后者redhat。但他们都是GNU发布的libc库。安装后显示如下:
[root@windriver-machine shtest]# rpm -qa|grep libc
glibc-2.6-3
libcdio-0.77-3.fc6
libcroco-devel-0.6.1-2.1
libchewing-0.3.0-6.fc7
glibc-devel-2.6-3
libcroco-0.6.1-2.1
glibc-headers-2.6-3
glibc-common-2.6-3
libcap-1.10-29
libcap-devel-1.10-29
[root@windriver-machine shtest]# ls -latr /usr/include/glib-2.0/glib/g
galloca.h gbase64.h gdataset.h ghash.h gkeyfile.h gmarkup.h gpattern.h gqueue.h gslice.h gstring.h gtypes.h
garray.h gbookmarkfile.h gdate.h ghook.h glist.h gmem.h gprimes.h grand.h gslist.h gthread.h gunicode.h
gasyncqueue.h gcache.h gdir.h gi18n.h gmacros.h gmessages.h gprintf.h grel.h gspawn.h gthreadpool.h gutils.h
gatomic.h gcompletion.h gerror.h gi18n-lib.h gmain.h gnode.h gqsort.h gscanner.h gstdio.h gtimer.h gwin32.h
gbacktrace.h gconvert.h gfileutils.h giochannel.h gmappedfile.h goption.h gquark.h gshell.h gstrfuncs.h gtree.h
[root@windriver-machine shtest]# ls -latr /usr/include/glib-2.0/glib/g
galloca.h gbase64.h gdataset.h ghash.h gkeyfile.h gmarkup.h gpattern.h gqueue.h gslice.h gstring.h gtypes.h
garray.h gbookmarkfile.h gdate.h ghook.h glist.h gmem.h gprimes.h grand.h gslist.h gthread.h gunicode.h
gasyncqueue.h gcache.h gdir.h gi18n.h gmacros.h gmessages.h gprintf.h grel.h gspawn.h gthreadpool.h gutils.h
gatomic.h gcompletion.h gerror.h gi18n-lib.h gmain.h gnode.h gqsort.h gscanner.h gstdio.h gtimer.h gwin32.h
gbacktrace.h gconvert.h gfileutils.h giochannel.h gmappedfile.h goption.h gquark.h gshell.h gstrfuncs.h gtree.h
[root@windriver-machine shtest]# ls -latr /usr/include/glib-2.0/glib/g
【4】ulimit 是一种LINUX内部参数集,用于为由它生成的SHELL进程及其子进程的资源使用设置限制。这些限制包括所创建的内核文件的大小、进程数据块的大小、进程创建文件的大小、内存锁住的大小、常驻内存集的大小、文件描述符的数量、分配堆栈的最大大小、CPU时间、单个用户的最大线程数、使用的最大虚拟内存等。
[windriver@windriver-machine ~]$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 32742
max locked memory (kbytes, -l) 32
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 10240
cpu time (seconds, -t) unlimited
max user processes (-u) 32742
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
[windriver@windriver-machine ~]$
ulimit 是资源使用限制的一种,它主要是限制当前SHELL进程及其派生的子进程,也就是说,对同一个用户来说,如果同时运行了两个SHELL,在其中一个SHELL中使用ULIMIT命令是不会影响另一个SHELL的。如果针对用户进行限制,可以修改配置文件/etc/security/limit.conf
[windriver@windriver-machine ~]$ cat /etc/security/limits.conf
# /etc/security/limits.conf
#
#Each line describes a limit for a user in the form:
#
#<domain> <type> <item> <value>
#
#Where:
#<domain> can be:
# - an user name
# - a group name, with @group syntax
# - the wildcard *, for default entry
# - the wildcard %, can be also used with %group syntax,
# for maxlogin limit
#
#<type> can have the two values:
# - "soft" for enforcing the soft limits
# - "hard" for enforcing hard limits
#
#<item> can be one of the following:
# - core - limits the core file size (KB)
# - data - max data size (KB)
# - fsize - maximum filesize (KB)
# - memlock - max locked-in-memory address space (KB)
# - nofile - max number of open files
# - rss - max resident set size (KB)
# - stack - max stack size (KB)
# - cpu - max CPU time (MIN)
# - nproc - max number of processes
# - as - address space limit
# - maxlogins - max number of logins for this user
# - maxsyslogins - max number of logins on the system
# - priority - the priority to run user process with
# - locks - max number of file locks the user can hold
# - sigpending - max number of pending signals
# - msgqueue - max memory used by POSIX message queues (bytes)
# - nice - max nice priority allowed to raise to
# - rtprio - max realtime priority
#
#<domain> <type> <item> <value>
#
#* soft core 0
#* hard rss 10000
#@student hard nproc 20
#@faculty soft nproc 20
#@faculty hard nproc 50
#ftp hard nproc 0
#@student - maxlogins 4
# End of file
[windriver@windriver-machine ~]$
如使用* hard nofile 100 限制任意用户最大创建文件数量是100。针对进程和针对用户只是在不同级别的资源限制,如果要求全局限制,这时就需要修改/proc下的配置参数如/proc/sys/net/ipv4/ip_local_port_range修改IP端口范围。
ulimit 一个特性就是你第一次设了一个值之后重设的值只能比这个值小。除非你使用超级权限。这句话其实也不对,如果你使用了其它权限,其实设置是不同用户。因此,ulimit设置之后只能小。不能大。除非新建SHELL
[windriver@windriver-machine ~]$ ulimit -m 5000
[windriver@windriver-machine ~]$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 32742
max locked memory (kbytes, -l) 32
max memory size (kbytes, -m) 5000
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 10240
cpu time (seconds, -t) unlimited
max user processes (-u) 32742
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
[windriver@windriver-machine ~]$ ulimit -m 4900
[windriver@windriver-machine ~]$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 32742
max locked memory (kbytes, -l) 32
max memory size (kbytes, -m) 4900
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 10240
cpu time (seconds, -t) unlimited
max user processes (-u) 32742
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
[windriver@windriver-machine ~]$ ulimit -m 4950
bash: ulimit: max memory size: cannot modify limit: Operation not permitted
[windriver@windriver-machine ~]$ man ulimit
[windriver@windriver-machine ~]$ su - root
Password:
[root@windriver-machine ~]# ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 32742
max locked memory (kbytes, -l) 32
max memory size (kbytes, -m) 4900
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 10240
cpu time (seconds, -t) unlimited
max user processes (-u) 32742
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
[root@windriver-machine ~]# ulimit -m unlimited
[root@windriver-machine ~]#
ulimit可以使用程序函数进行设置,两个函数setrlimit(), getrlimit()在glibc中。
【5】gcov工具 这个工具主要用来进行代码执行的覆盖测试,类似于JAVA中的emma,通过分析GCOV的结果来判断代码的健壮性。使用gcov 配合lcov生成HTML。gcov先用带参数-fprofile-arcs –ftest-coverage的gcc编译,当执行程序后会生成.c.gcov文件,使用gcov命令可以查看这些覆盖结果。
[windriver@windriver-machine ltest]$ gcc -fprofile-arcs -ftest-coverage gcov_exp.c -o gcov_exp
[windriver@windriver-machine ltest]$ ll gcov_exp*
-rwxrwxr-x 1 windriver windriver 15274 2011-08-30 22:06 gcov_exp
-rw-rw-r-- 1 windriver windriver 198 2011-08-30 22:05 gcov_exp.c
-rw-rw-r-- 1 windriver windriver 572 2011-08-30 22:06 gcov_exp.gcno
[windriver@windriver-machine ltest]$ ./gcov_exp
Success
[windriver@windriver-machine ltest]$ ll gcov_exp*
-rwxrwxr-x 1 windriver windriver 15274 2011-08-30 22:06 gcov_exp
-rw-rw-r-- 1 windriver windriver 198 2011-08-30 22:05 gcov_exp.c
-rw-rw-r-- 1 windriver windriver 168 2011-08-30 22:08 gcov_exp.gcda
-rw-rw-r-- 1 windriver windriver 572 2011-08-30 22:06 gcov_exp.gcno
[windriver@windriver-machine ltest]$ gcov gcov_exp.c
File 'gcov_exp.c'
Lines executed:87.50% of 8
gcov_exp.c:creating 'gcov_exp.c.gcov'
[windriver@windriver-machine ltest]$ gcov -a gcov_exp.c
File 'gcov_exp.c'
Lines executed:87.50% of 8
gcov_exp.c:creating 'gcov_exp.c.gcov'
[windriver@windriver-machine ltest]$ ll gcov_exp*
-rwxrwxr-x 1 windriver windriver 15274 2011-08-30 22:06 gcov_exp
-rw-rw-r-- 1 windriver windriver 198 2011-08-30 22:05 gcov_exp.c
-rw-rw-r-- 1 windriver windriver 832 2011-08-30 22:08 gcov_exp.c.gcov
-rw-rw-r-- 1 windriver windriver 168 2011-08-30 22:08 gcov_exp.gcda
-rw-rw-r-- 1 windriver windriver 572 2011-08-30 22:06 gcov_exp.gcno
[windriver@windriver-machine ltest]$ cat gcov_exp.c
#include<stdio.h>
int main(void)
{
int i,total;
total = 0;
for(i=0;i<10;i++)
{
total+=i;
}
if(total!=45)
printf("Failure\n");
else
printf("Success\n");
return 0;
}
[windriver@windriver-machine ltest]$
【6】环境变量读写,使用getenv/setenv/unset
【7】基本数学函数 abs(计算×××数的绝对值|a|),cos(取余玄函数值),ceil(取不小于参数的最小×××数) exp(计算指数),sqrt(计算平方根值) pow(计算次方值) log10计算对数值,注意其中abs在stdlib中,而其它是在math.h库中,因此,编译时需要链接库选项-lm。
[windriver@windriver-machine ltest]$ vi com_fun.c
[windriver@windriver-machine ltest]$ gcc com_fun.c -lm
[windriver@windriver-machine ltest]$ ./a.out
|-12| = 12
cos(0.5) = 0.877583
sqrt(200) = 14.142136
2^10 = 1024.000000
log10(100) = 2.000000
4.800000=>5.000000
1.120000=>2.000000
-2.200000=>-2.000000
[windriver@windriver-machine ltest]$ cat com_fun.c
#include <math.h>
#include <stdio.h>
int main(void)
{
double answer,root,powvalue,logv;
double value[] = {4.8,1.12,-2.2,0};
int i,absvalue;
absvalue = abs(-12);
answer = cos(0.5);
root = sqrt(200);
powvalue = pow(2,10);
logv = log10(100);
printf("|-12| = %d\n",absvalue);
printf("cos(0.5) = %f\n", answer);
printf("sqrt(200) = %f\n",root);
printf("2^10 = %f \n", powvalue);
printf("log10(100) = %f\n",logv);
for(i=0;value[i]!=0;i++)
{
printf("%f=>%f\n",value[i],ceil(value[i]));
}
return 0;
}
[windriver@windriver-machine ltest]$