学习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…这些不同的目录下。缺省的类别如下:

可以使用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手册,有几个网站比较好

【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=&gt;2.000000
-2.200000=&gt;-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=&gt;%f\n",value[i],ceil(value[i]));
     }
   return 0;
}
[windriver@windriver-machine ltest]$