my blog my blog

Tag: Linux
linux c编程信号处理的一些实例signal sigaction

 

 刚接触linux下的c编程,记录一下吧.对于信号,就是我们经常用的那个kill,kill可以发送很多信号,当然,我们也可以通过程序来实现,我们甚至可以来定义对于不同的信号的处理,比如ctrl+c可能并不能退出我们的程序,因为我们可以监视ctrl+c发送的SIGINT信号,并且用我们自己的功能来进行处理.PS:发现写代码也是个需要手感的事儿,意识到该多看看vim的配置鸟~~~自动不全一定要强大才行哇~~~

先把课本上的两个小实例放上来,记录下:

1.signal()的使用

捕捉ctrl+c发送的SIGINT与ctrl+\发送的SIGQUIT信号

  1. #include <stdio.h> 
  2. #include <stdlib.h> 
  3. #include <signal.h> 
  4.  
  5. void my_func(int sign_no) { 
  6.     if (sign_no == SIGINT) { 
  7.         printf("I have get SIGINT\n"); 
  8.     } else if (sign_no == SIGQUIT) { 
  9.         printf("I have get SIGQUIT\n"); 
  10.     } 
  11.  
  12. int main() { 
  13.     printf("waiting for signal SIGINT or SIGQUIT ... \n"); 
  14.     signal(SIGINT, my_func); 
  15.     signal(SIGQUIT, my_func); 
  16.     pause(); 
  17.     exit(0); 

2.sigaction()的使用<—感觉是signal的一个变种

同样是捕捉ctrl+c发送的SIGINT与ctrl+\发送的SIGQUIT信号

  1. #include <stdio.h> 
  2. #include <stdlib.h> 
  3. #include <signal.h> 
  4.  
  5. void my_func(int sign_no) { 
  6.     if (sign_no == SIGINT) { 
  7.         printf("I have get SIGINT\n"); 
  8.     } else if (sign_no == SIGQUIT) { 
  9.         printf("I have get SIGQUIT\n"); 
  10.     } 
  11.  
  12. int main() { 
  13.     struct sigaction action; 
  14.     printf("waiting for signal SIGINT or SIGQUIT ... \n"); 
  15.     action.sa_handler = my_func; 
  16.     sigemptyset(&action.sa_mask); 
  17.     action.sa_flags = 0; 
  18.     sigaction(SIGINT, &action, 0); 
  19.     sigaction(SIGQUIT, &action, 0); 
  20.     pause(); 
  21.     exit(0); 

3.信号集

默认对信号进行状态阻塞,此时输入任何信号都不执行,ctrl+c 与ctrl+\都不会被执行,但是当输入任意字符并回车后,原来的信号就会被立即执行.可以先输入任意字符解除SIG_BLOCK状态,然后执行SIG_INT与SIG_QUIT,SIG_INT调用我们自己的函数my_func,所以程序会一直不退出,但是SIG_QUIT仍旧是系统的函数,因此可以正常表达

  1. #include <stdio.h> 
  2. #include <stdlib.h> 
  3. #include <sys/types.h> 
  4. #include <unistd.h> 
  5. #include <signal.h> 
  6.  
  7. void my_func(int signum) { 
  8.     printf("If you want to quit ,please try SIGQUIT\n"); 
  9.  
  10. int main() { 
  11.     sigset_t set, pendset; 
  12.     struct sigaction action1, action2; 
  13.  
  14.     if (sigemptyset(&set) < 0) { 
  15.         perror("sigemptyset"); 
  16.         exit(1); 
  17.     } 
  18.  
  19.     if (sigaddset(&set, SIGQUIT) < 0) { 
  20.         perror("sigaddset"); 
  21.         exit(1); 
  22.     } 
  23.  
  24.     if (sigaddset(&set, SIGINT) < 0) { 
  25.         perror("sigaddset"); 
  26.         exit(1); 
  27.     } 
  28.  
  29.     if (sigismember(&set, SIGINT)) { 
  30.         sigemptyset(&action1.sa_mask); 
  31.         action1.sa_handler = my_func; 
  32.         action1.sa_flags = 0; 
  33.         sigaction(SIGINT, &action1, 0); 
  34.     } 
  35.  
  36.     if (sigismember(&set, SIGQUIT)) { 
  37.         sigemptyset(&action2.sa_mask); 
  38.         action2.sa_handler = SIG_DFL; 
  39.         action2.sa_flags = 0; 
  40.         sigaction(SIGQUIT, &action2, 0); 
  41.     } 
  42.  
  43.     if (sigprocmask(SIG_BLOCK, &set, NULL) < 0) { 
  44.         perror("sigprocmask"); 
  45.         exit(1); 
  46.     } else { 
  47.         printf("Signal set was blocked,Press any key!"); 
  48.         getchar(); 
  49.     } 
  50.     if (sigprocmask(SIG_UNBLOCK, &set, NULL) < 0) { 
  51.         perror("sigprocmask"); 
  52.         exit(1); 
  53.     } else { 
  54.         printf("Signal set is unblock state\n"); 
  55.     } 
  56.     while (1) 
  57.         ; 
  58.     exit(0); 

 

Linux C编程—fork子程序以及fifo有名管道的使用

 

写一个程序,创建一个fifo有名管道,然后利用程序与子程序完成程序间的信息传输实例.

功能:输入什么,输出什么

           输入q或者Q程序退出

调用fifo文件:/tmp/fifo

  1. #include <stdio.h> 
  2. #include <stdlib.h> 
  3. #include <unistd.h> 
  4. #include <sys/types.h> 
  5. #include <sys/stat.h> 
  6. #include <errno.h> 
  7. #include <fcntl.h> 
  8. #include <limits.h> 
  9.  
  10. #define FIFO_FILE "/tmp/fifo" 
  11. #define BUFFER_SIZE PIPE_BUF 
  12.  
  13. int main(void) { 
  14.     char buff[BUFFER_SIZE]; 
  15.  
  16.     if (access(FIFO_FILE, F_OK) == -1) { 
  17.         if ((mkfifo(FIFO_FILE, 0666) < 0) && (errno != EEXIST)) { 
  18.             printf("Filo file create error!\n"); 
  19.         } 
  20.     } 
  21.     pid_t newfork = fork(); 
  22.     if (newfork < 0) { 
  23.         printf("Fork error!\n"); 
  24.         exit(1); 
  25.     } else if (newfork == 0) { 
  26.         int fd1 = open(FIFO_FILE, O_RDONLY); 
  27.         int reader; 
  28.         if (fd1 < 0) { 
  29.             printf("child process fd error!\n"); 
  30.             exit(1); 
  31.         } 
  32.         while (1) { 
  33.             reader = read(fd1, buff, BUFFER_SIZE); 
  34.             if ((buff[0] == 'q' && buff[1] == '\0'
  35.                     || (buff[0] == 'Q' && buff[1] == '\0')) { 
  36.                 printf("Get EXIT message and quit!\n"); 
  37.                 close(fd1); 
  38.                 exit(0); 
  39.             } 
  40.             if (reader > 0) { 
  41.                 printf("Read from FIFO:%s\n", buff); 
  42.             } 
  43.         } 
  44.     } else { 
  45.         int fd2 = open(FIFO_FILE, O_WRONLY); 
  46.         int writer; 
  47.         if (fd2 < 0) { 
  48.             printf("Father process fd error!\n"); 
  49.             exit(1); 
  50.         } 
  51.         while (1) { 
  52.             if ((buff[0] == 'q' && buff[1] == '\0'
  53.                     || (buff[0] == 'Q' && buff[1] == '\0')) { 
  54.                 close(fd2); 
  55.                 exit(0); 
  56.             } 
  57.             scanf("%s", buff); 
  58.             writer = write(fd2, buff, BUFFER_SIZE); 
  59.         } 
  60.     } 

 

动态磁盘无法写入grub问题介绍

 

昨天帮小远装linux,发现正常安装后grub无法写入,而且最强大的是mbr中的windows引导还顽强的存在。当时分区的时候就感觉怪怪的,因为没有主分区跟扩展分区,刚开始也没多想,只是觉得怪怪的,后来经过很久的排错,终于知道了,原来是由于windows的动态磁盘造成的。

查了下百科,介绍如下:Windows 2000起引入了基本磁盘和动态磁盘的概念,并且把它们添加到Windows系统管理员的工具之中。无论是基本磁盘还是动态磁盘,你都可以使用任何文件系统,包括FAT和NTFS。而且你可以在动态磁盘改变卷而不需要重启系统。你可以把一个基本磁盘转换 成动态磁盘。但是你必须了解这并不是一个双向的过程。一旦你从基本磁盘变成了动态磁盘,除非你重新创建卷,否则你不能将它转变回去。

我们平时用的是基本磁盘,有主分区跟扩展分区之分,而动态磁盘默认都是简单卷,还有其它的卷模式。这里我们就不讨论了,我们只要知道这个grub无法写入的问题是由于动态磁盘造成的就ok鸟。

看了网上的一些文章,其实是有无损把动态磁盘转换为基本磁盘的程序跟方法的,但是这里只是针对简单卷的哦,有其它卷的就不好处理了。

资料我已经都整理到文件中了,朋友们有需要的可以直接下载无损转换动态分区工具包 (请先备份数据再使用,以防万一)

教程可以看下图:点击可以看大图

怎么无损数据地转换动态磁盘到基本磁盘

 

Ubuntu12.04新手入门指南

写一篇新手入门指南吧,可能总结的不够全面,再补充吧~有些点可能写的不够明确,希望朋友们可以好好借助google baidu等搜索引擎来寻找更详细的介绍.

1.系统安装

对于Ubuntu系统的安装,方法真的很多.比如在windows下就可以进行的wubi安装,正常推荐的光盘安装(哪里有光盘?自己把iso镜像文件刻录为光盘就可以了哇),U盘安装以及奶牛前篇介绍过的硬盘安装.如果采用wubi方式安装,请尽量将系统放在一个ntfs分区上,否则可能会因为文件大小限制造成一些问题.奶牛更推荐的是直装方式,但是需要你有一定的了解跟基础.

Ubuntu的安装,你首先要了解linux下的分区以及引导方式的一些知识,奶牛在这里简单的说一下:

Ubuntu等linux操作系统一般不要求你安装在主分区上,不像windows要求那样子苛刻,就算全是逻辑分区也是没有任何问题的.一般对于新手,分配一个分区给根目录(/)+一个交换分区(swap).交换分区的概念也许在windows下并没有怎么被提到,不过如果你了解比较多,一定听说过页面缓存文件,一个跟交换分区差不多的东西,都是用作交换时候用的,弥补内存不足造成的一些问题,就相当于一个速度不高的内存区域,一般设置为内存的1~1.5倍,不过内存超过4G的PC就可以不设置了.

引导呢,linux主流系统现在都是用grub来做引导,此处所说的grub是grub2,从前几个版本就开始一直在用,因为使用Ubuntu的grub引导可以轻松实现对于windows的引导,所以一般我们都选择由grub来做引导,如果安装完成后发现没有windows的开机启动选项,可以直接执行命令update-grub来寻找windows的引导的.

2.配置工具ubuntu-tweak

对于一个操作系统,配置很关键,如果你已经顺利的安装完成,那么就要用一些配置工具来帮你配置好一个你更习惯更喜欢的桌面环境了.这里奶牛首推的是ubuntu-tweak.国人编写,功能较为完善的ubuntu配置工具,涵盖了从系统桌面环境配置到源的修改,以及垃圾清理.使用ubuntu-tweak几乎可以完成对于ubuntu的常用配置,如果你还觉得不够过瘾,想对于特效有更详细的配置,可以使用ccsm,compiz的高级配置工具.

3.驱动问题

驱动问题估计是个老大难,因为奶牛只有一台Y450笔记本,没有遇到太大问题,除了此次六屏幕问题(已经解决),并没有遇到过其它问题.不过奶牛没遇到并不代表其他朋友不会遇到,这里奶牛说一下.显卡驱动一般分为开源驱动跟闭源驱动,奶牛一般直接去官方网站下载官方驱动(也就是闭源驱动,总体性能上还是不错的),对于显卡驱动的安装,一般会下载一个.run的驱动,然后关闭lightgdm服务,sh xxx.run来安装驱动.如果你用开源驱动没啥问题,就继续用也没关系的.

声音驱动一般用alsa来配置就可以搞定的.而无线网卡呢,linux下有一个可以安装windows无线驱动的工具ndiswrapper,如果无线无法搞定可以试试这个工具.

4.软件

牛X的应用程序,linux下很多都有相应的版本,如果没有,也会有很多功能类似的替代软件可以使用.比如office有open office 跟libre office,现在永中跟wps也加入到linux环境下的office工具开发当中了.

影音播放只要解码没啥问题也都可以正常使用,一般装个vlc,装个totem+gstream那个系列的解码就ok搞定99%了.

上网呢,mozilla firefox chrome opera等各种主流浏览器也都完美支持.

一些拨号的客户端可以通过wine的方法来搞定.

IM软件:QQ可以直接用webQQ,skype有linux的客户端,功能很强大,gtalk哇msn哇可以直接用自带的集成软件去实现.

更多软件尽在:ubuntu的软件中心

5.建议买本书学起

可以看奶牛的介绍文章:Ubuntu Linux 入门书籍教程推荐

6.一些思想

开放:不要局限在windows的点点鼠标,你应该更加深入了解系统

共享:把好的东西分享给需要的人

自由:让自己充满想法,要geek一些,不要被局限

友帮拓:虽然很多人说这个中文名很烂,但是奶牛觉得它的含义很明确:友好互爱,互帮互助,开拓进取

recordmydesktop录制桌面后ogv转avi脚本

 

在Linux下使用recordmydesktop录制桌面很方便,但是生成的是ogv文件,不够通用,转成avi格式会比较好传给非linux用户看.

这里有一个简单的小脚本,直接保存ogv2avi到bin目录下使用即可.

简单脚本:

#!/bin/bash
# ogv to avi
mencoder "$1" -ovc xvid -oac mp3lame -xvidencopts pass=1 -o "$2"

功能稍好的脚本:

#!/bin/bash
# ogv to avi
# Call this with multiple arguments
# for example : ls *.{ogv,OGV} | xargs ogv2avi
N=$#;
echo "Converting $N files !"
for ((i=0; i<=(N-1); i++))
do
echo "converting" $1
filename=${1%.*}
mencoder "$1" -ovc xvid -oac mp3lame -xvidencopts pass=1 -o $filename.avi
shift 1
done

保存完成后

sudo chmod +x ogv2avi

然后直接用ogv2avi 源文件  目标文件即可

脚本需要mencoder支持哦,ubuntu12.04 arch linux 都可以正常使用的.

Ubuntu12.04即将发布(10日倒计时)

 

Ubuntu12.04即将发布,还有十天,因为Ubuntu12.04是LTS发行版本,所以奶牛还是决定在新版本发布的时候进行安装,顺便适应下新的Unity。话说奶牛第一次使用Unity的时候还是在Unity刚发布beta测试的时候,那时候Unity还没有被正式在Ubuntu的版本中默认发布,只能自己找源更新测试。虽然近几次新版本发布Unity的变化很大,但是与最初的Unity在总体方向上还是有一致性的。

奶牛使用Gnome3环境已经有半年多了,总体上对于Gnome3的设计还是很习惯的,看到最近Ubuntu12.04的Unity进步很大,也决定开始 尝试下Unity了。

不要太着急,静等十日,奶牛会发布第一手的安装教程与测评。敬请期待。

希望尽早尝试的朋友可以去http://cdimage.ubuntu.com/daily-live/current/下载当前最新的live镜像进行ubuntu12.04全新安装。当然也可以选择alt+F2运行

update-manager -d

进行ubuntu12.04升级安装

Arch Linux降级安装软件包与禁止升级不想升级的包的方法

 

Arch Linux虽然采用滚动更新,但是有些包确实并没有想象的完美,甚至不如老版本.例如新版本的eclipse,如果升级安装,则提示与xulrunner冲突,但是xulrunner可是Mozilla Runtime Environment,这个可是mozilla的一个运行环境哇,木有必然会造成不稳定.所以这时候只有禁止eclipse的升级鸟.奶牛觉得很多包都不需要升级的,比如说显卡驱动,不必要每次都升级,很麻烦还很大~~~

禁止某些包自动升级的方法是

sudo vim /etc/rc.conf

添加行

IgnorePkg = eclipse nvidia nvidia-utils nvidia-cg-toolkit

这样子,我们就可以禁止上面的四个包自动升级了.如果有其它的包想禁止,直接添加就可以了,记住分隔符要用空格哦.

如果安装了新版本软件想降级可以通过downgrade程序.

sudo yaourt -S downgrade

然后

downgrade eclipse

就可以选择本地已有的缓存或者输入s来搜索可用的网络缓存进行降级.

如果可以下载到具体的包的话也可以采用

sudo pacman -Uf xxx.pkg.tar.gz

来进行降级安装哦,然后降级安装成功后添加个禁止自动升级就可以了.

Ubuntu下GCC编译流程及使用方法

 

gcc编译分四个步骤:

  • 预处理(生成预处理文件)
  • 编译(生成汇编代码)
  • 汇编(生成二进制目标代码)
  • 链接(生成可执行文件)

使用方法:

  • 预处理
gcc -E hello.c -o hello.i
  • 编译
gcc -S hello.c -o hello.s
  • 汇编
gcc -c hello.s -o hello.o
  • 链接
gcc hello.o -o hello
  • 执行
./hello

奶牛以前只知道gcc hello.c直接生成a.out就可以执行了,没有那么细化的了解过,记录下备忘.Ubuntu12.04快点儿发布吧,等好久了的说.

如何开启Ubuntu12.04的Gnome3桌面图标功能

 

如何开启ubuntu12.04 gnome3桌面的图标,这个问题可以用gnome tweak tool来搞定.

首先安装gnome-tweak-tool并运行

进入程序的desktop选项卡

开启Have file manager handle the desktop即可,如果想要computer图标跟Home图标可以选中第二跟的三项,最后三项分别是网络 回收站 跟挂载的盘图标,gnome-tweak-tool是gnome3必备的配置工具,可以配置很多东东哦,建议先安装这个再去配置gnome3.

how linux is built 视频介绍linux

 

视频短篇介绍linux系统: