![](https://img-blog.csdnimg.cn/20201014180756928.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Linux环境编程
文章平均质量分 61
vonzhou
这个作者很懒,什么都没留下…
展开
-
斐波那契数列
《编程之美》#include #include #include //1.按照斐波那契的定义容易用递归实现int fibonacci( int n){ if(n //看具体数学说负数也有对应的 Fibonacci值 return 0; } else if (n == 1){ return 1;原创 2014-06-30 16:57:02 · 882 阅读 · 0 评论 -
Implementing Software Timers - Don Libes
在看APUE习题10.5的时候提示了这篇文章,讲的很清晰,设计也很巧妙,所以把原文放在这里,值得自己去实现。Title: Implementing Software TimersBy: Don LibesOriginally appeared in the Nov. 1990 "C User's Journal" and is also reprinted as C原创 2014-10-02 09:33:29 · 1528 阅读 · 0 评论 -
APUE 线程 - 程序清单
APUE 线程 - 程序清单程序清单11-1 打印线程ID程序清单11-2 获得线程退出状态程序清单11-3 pthread_exit 的参数不正确使用程序清单11-4 线程清理处理程序程序清单11-5 使用互斥量保护数据结构程序清单11-6 使用两个互斥量程序清单11-7 简化的加,解锁程原创 2014-10-04 23:10:52 · 1292 阅读 · 0 评论 -
C语言不支持引用传递和函数重载
C语言不支持引用传递和函数重载(1)ANSI C不支持引用(pass by reference),通过对指针的传值可以到达需求,C++才支持引用。(2)C语言不支持函数重载。测试如下:原创 2015-03-25 21:48:04 · 1507 阅读 · 0 评论 -
创建并使用静态库(ar 命令)
创建并使用静态库(ar 命令) archive命令的功能是:创建或修改归档文件或者从归档文件中析取信息。可以简单的理解为一个打包工具,将成员文件按照一定的规则构建到.a文件中,通常这种类型的归档文件用来将常用的例程组织为一个静态库,方便应用程序的链接。重要参数:d - 从archive中删除模块,若指定v选项的话还会在删除的过程中打印信息;r - 以替换的方式原创 2015-03-19 20:20:49 · 2860 阅读 · 1 评论 -
结构体内存对齐规则
结构体的内存布局记住两个规则即可,这是编译器的优化措施。规则1:结构体中第一个成员的偏移量是0,以后每个成员的位置是x的倍数; x = min(#pragma pack(), 该成员自身的长度)规则2:成员对齐后,结构体自身也要对齐,按照y的倍数进行; y = min(#pragma pack(), 最大成员尺寸)。其中#pragma pa原创 2014-06-18 15:42:44 · 3902 阅读 · 1 评论 -
多维数组作为函数参数的形式
多维数组作为函数参数的形式 今天在看CSAPP的时候,直接敲入了书中的代码片段(P582),没有多加思考,却出现了段错误coredump,然后再纠结:被调用函数是否可以访问到主函数中的数据,函数中的自动变量存在栈中?最后才知道是函数声明的问题。所以通过这篇文章理清了数组作为参数时如何实践,同时不要忽略编译器给我们的警告。问题: $vi 2.c $ gcc原创 2015-03-24 14:26:14 · 3792 阅读 · 0 评论 -
源码阅读tinyhttpd
tinyhttpd 是一个用C语言实现的简单的HTTP服务器程序,500行代码,值得阅读。看完这个代码之后有几点需要进一步的思考:1.get_line()函数要处理跨平台的换行('\n' or '\r\n')MSG_PEEK 标志可以窥探缓冲区中的数据,从而决定是否读取;2.stat ,st.st_mode & S_IFMT) == S_IFDIR 判断对应的路径是否是目录;3.原创 2015-04-03 20:58:29 · 1099 阅读 · 0 评论 -
探寻ELF文件内容,理清符号所在section
受《CSAPP》P453启发,想实际的看看ELF文件的内容,所以做了简单的尝试,希望不虚此行。采用的程序demo是:swap.cextern int buf[];int *bufp0 = &buf[0];int *bufp1;void swap(){ int temp; bufp1 = &buf[1]; temp = *bufp0;原创 2015-04-07 20:43:23 · 3803 阅读 · 0 评论 -
Data Structure Alignment 2
Data Structure Alignment 2在前面的一篇文章中,似乎明白了结构体对齐的基本规则,但是有些地方还是含糊不清。比如看下面的这个程序。根据前面的规则很容易算出,sizeof(A)=16, sizeof(B)=24.但是在GCC下运行的结果却不是这样,所以一时有点不知问题所起,内存对齐都是编译器做的工作所以各个平台下面的实现没有得到统一规范,虽然可以#pragma原创 2015-04-08 14:41:23 · 1078 阅读 · 1 评论 -
反汇编一个简单的C程序
反汇编一个简单的C程序看了下网易云课堂的《Linux内核分析》,第一节要求有一个简单C程序得到汇编代码,然后分析。只要明确每个汇编指令代表的含义,就可以容易的走下去,关键是要体会里面的思想。int g(int x){ return x+3;}int f(int x){ return g(x);}int main(){ return f(8原创 2015-04-13 20:34:13 · 1608 阅读 · 0 评论 -
C语言0长度数组(柔性数组)
C语言0长度数组(柔性数组) 0长度数组,又称为柔性数组(flexible array),通常用来实现变长数组,常见于TLV(type-length-value)的数据结构中。在标准 C 和 C++ 中,不允许用 0 长度数组,但在原创 2014-06-18 15:13:23 · 3049 阅读 · 0 评论 -
重定位PC相对引用(PC-relative reference relocation)
重定位PC相对引用(PC-relative reference relocation) 示例代码(main.c, swap.c )见之前的一篇文章,分析目标文件。可以看到main中调用swap的call指令位于section offset 0x1d处,操作码是e8,操作数是32bit的引用0xfffffffc,即-4(little endian存储的),下一行显示的是swa原创 2015-04-14 10:36:21 · 3809 阅读 · 1 评论 -
重定位绝对引用(absolute reference relocation)
重定位决定引用(absolute reference relocation) 还是承接前面的程序,在swap.c中 “int *bufp0 = &buf[0];”bufp0被初始化为一个全局的数组地址,所以需要重定位,详细信息如图和, r.offset=0xc, r.symbol=buf, r.type=R_386_32 ,重定位条目告诉编译器,这是一个32位的绝对引用,必须重定位才能指原创 2015-04-14 11:20:41 · 2199 阅读 · 0 评论 -
Linux setuid 实践
Linux setuid 实践之前接触过setuid,但是没有深入思考,今天读《Unix编程艺术》,觉得瞬间为这种设计所折服,所以总结一下。一般在设计系统时,为了安全,总是试图使用最小权限模型,除非迫不得已需要特权来访问系统,否则不该信任用户代码。Unix中访问控制是基于用户和组的,所以setuid/setgid正是为了给当前进程设置用户/组ID,从而赋予相应的权限。 Under Unix, p原创 2015-06-05 14:55:13 · 1568 阅读 · 0 评论 -
程序间协作方式-shell out
程序间协作方式-shell outshell out这个名词虽然没怎么听说,但是说不定在默默的使用,说白了就是通过一个程序通过命令的形式调用另一个程序,即system(2)系统调用。其中存在的交互(或者称为协议)很简单,一个执行完了,接着另一个再执行,不会有通信过程,最多有调用程序向被调用程序传递参数。 这种模式的变形,就是C库函数popen()和pclose(),我们可以把popen这种机制看做原创 2015-06-05 15:58:23 · 2000 阅读 · 0 评论 -
利用pipe实现兄弟进程之间的通信
利用pipe实现兄弟进程之间的通信进程A创建2个子进程B,C。然后B C执行的程序利用pipe来通信:ls的输出通过管道到达另一个进程用wc统计单词数,字节数,行数。execve系统调用用于执行指定的程序,其他的exec系列函数都是基于它。APUE-188 int execve(const char *filename, char *const argv[],char *const envp[原创 2015-08-22 19:54:32 · 5025 阅读 · 0 评论 -
APUE信号-程序汇总
APUE信号-程序汇总 最近重看APUE,发现对于很多程序的要领还是没有完全理解,所以梳理下便于查看,而且有很多值得思考的问题。程序清单10- 1 捕获 SIGUSR1 和 SIGUSR2的简单程序#include "util.h"static void sig_usr(int);int main(void){ if(signal(SIGUSR1,原创 2014-10-02 12:20:17 · 1371 阅读 · 0 评论 -
execl error: Permission denied 错误解决
execl error: Permission denied 错误解决 在调用execl函数执行一个文件的话要确保:全路径名是正确的,第二个参数必须对应为第一个参数的文件名;最后一个参数是 (char *)NULL ;可以直接把第一个参数放在命令行运行来检验。否则会出现 Permission denied 错误。值得注意的是,即使执行的是一个解释器文件,也需要其有可执行权限。(原创 2014-09-27 11:24:58 · 9694 阅读 · 0 评论 -
哈希表的简单实现
下面这个散列表的实现来自K&R,很经典。在其他场景中遇到的实现更复杂,基本原理不变,只是在hash算法,或者在快速查询上做了优化。#include #include //具有相同hash值构成的链表struct nlist{ struct nlist * next; char * name; //key-定义的名字 char原创 2014-06-30 10:59:56 · 1179 阅读 · 0 评论 -
Autotools学习
我们通常用诸如 "./configure", "make","make install" 等命令就可以把源码包安装到系统中,但是背后的原理是什么呢?当我们需要修改源码,加入自己的代码后如何修改呢?所以需要学习如何利用 GNU Autoconf 及 Automake 这两套工具来自动产生 Makefile文件。下面的内容综合了一些网上找到的资源。先来一个例子1.系统中原创 2014-07-02 20:33:56 · 1241 阅读 · 0 评论 -
C语言char s[] 和 char *s的区别
C语言char s[] 和 char *s的区别,下面这个回答讲解的很清晰。The difference here is thatchar *s = "Hello world";will place Hello world in the read-only parts of the memory and making s a pointer to that,原创 2014-07-09 09:13:50 · 5166 阅读 · 0 评论 -
C语言实现JSON-RPC
最近对json-rpc比较感兴趣,思想很简单,而且看到了很多不同语言的实现。在github上 hmngomes 的 json-rpc-c (实现的是server端,基于TCP流),短小精悍,提供了很好的框架,代码十分清晰,易于扩展,而且代码容易看懂,很经典。该实现依赖于其它两个库 libev 和 cJSON,值得认真学习。 测试的时候先启动server,而后通过 nc 命令发送相应的j原创 2014-07-08 08:57:15 · 10720 阅读 · 0 评论 -
”Java 方法可以返回数组类型“ 所想到的
在C和C++中不能返回一个局部变量,因为函数中的局部变量分配的存储空间在栈上,当函数执行完后会被重新利用,所以想要返回数组类型,有两种方式:1)静态变量(static in a function可以在函数调用之间保持值有效),2)利用malloc动态分配,但是最终要记得释放。下面是几个简单测试程序:1.错误的示例:#include int *func(int n){原创 2014-07-28 14:23:24 · 5103 阅读 · 0 评论 -
C语言中一些很酷的技巧(cool tricks)
C语言中一些很酷的技巧(cool tricks)来自Quora,觉得不错,就实践了一下。1. #if 0 ...... #endif 块中的内容不会被编译,因为注释不允许嵌套,我们可以把暂时不用的代码块放在这里面。2. 数组初始化的时候可以指定索引,而且可以给特定范围的数组赋值。比如 int array[] = { [0 ... 9] = 1, [10 ...原创 2014-07-12 11:32:26 · 4320 阅读 · 1 评论 -
链表操作时巧用指针的指针
比如在插入有序链表的过程中,一般情况下要使用俩指针来遍历,而后还要判断是否在第一个位置插入;利用指针的指针后不需要另外考虑这种特殊情况。代码:#include #include struct node{ int data; struct node *next;} *head;//sorted link-listvoid insert(struct no原创 2014-07-12 14:47:34 · 1850 阅读 · 0 评论 -
"错误: void 值未如预期地被忽略"解决
在C陷阱与缺陷中,实现assert的时候,作者处理的很巧妙,利用逻辑或运算符的特性将这个过程转化为一个表达式,在当条件为假时就会调用_assert_error报错并终止程序。刚开始_assert_error 的返回值类型是 void 所以在((void)((e) || _assert_error(__FILE__, __LINE__))) 中出现了错误:void 值未如预期地被忽略,虽然e原创 2014-08-18 11:24:06 · 4148 阅读 · 0 评论 -
关于错误errno EFAULT:Bad address
UDP socket : read error Bad address在写UDP server,在调用套接字读取的时候发生了这个错误, 通过看errno.h 可以看到对应的错误号 EFAULT:Bad address (POSIX.1),在stackoverflow上看到的这个解释不错:It happen if the memory address of some argum原创 2014-09-04 10:33:25 · 23184 阅读 · 0 评论 -
为线程绑定CPU
// learn gcc atomic variable#define _GNU_SOURCE#include #include #include #include #include #include #include #include #define INC_TO 1000000 // every thread adds 1 million timesint glob原创 2014-08-24 12:13:02 · 1412 阅读 · 0 评论 -
错误: 您选择的 CPU 不支持 x86-64 指令集
在运行Makefile的时候出现这个错误表示指定的类型无法满足当前的CPU,需要修改编译选项比如 gcc -g -Wall -march=x86-64 -o ......gcc编译器选项 -march表示为特定的cpu类型编译二进制代码(不能在更低级别的cpu上运行)原创 2014-08-27 19:54:52 · 9152 阅读 · 0 评论 -
守护进程重读配置文件示例
守护进程重读配置文件示例 重读APUE,对守护进程有了更加深刻的理解,特别是相应的编程规则和应用场景。对于为什么要fork两次,日志设施的用法,信号的处理方法都有了更加清晰的认识。通常的应用场景是,守护进程在收到一个SIGHUP信号的时候重新读取配置文件,而不需要停止。下面是运行APUE书中这个实例的过程。 首先主要代码为(reread.c):#incl原创 2014-09-24 19:44:20 · 2794 阅读 · 0 评论 -
把枚举转化为相应的字符串
把枚举转化为相应的字符串 今天无意间就需要这样的一个功能,从枚举值得到对应的字符串表示,一个容易想到的方法就是再造个字符串数组,和ENUM对应起来,显然这个方法没有可扩展性;第二种方法在stackoverflow上看到的就是巧妙的利用 宏 来生成对应的字符串数组,感觉非常巧妙,易于扩展。下面是这两种方法的代码。#include#includeenum原创 2014-09-26 15:55:21 · 14189 阅读 · 4 评论 -
源码安装 openssl
源码安装 openssl 因为sha1计算的需要,要求有openssl/sha.h头文件,所以要安装 openssl 和 libssl-dev 否则会报错: fatal error: openssl/sha.h: No such file or directory。由于这台机器不能直接上网,就需要下载源码进行安装。不装 libssl-dev 的话,程序仍然找不到相应的头文件原创 2014-09-26 15:53:32 · 2839 阅读 · 0 评论 -
进行命令处理的典型程序框架
进行命令处理的典型程序框架 今天翻看APUE中非局部goto的时候,看到了这个处理命令行的代码框架,所以就想简单的实现一个功能进行调试,花了大概2个小时,才完全看的过去,记录下,虽然看起来还是不够层次清晰。里面牵扯到的知识点注意有:业务要学会分层;枚举值和对应字符串的转换;字符串的解析(分词)。#include "util.h"void do_line(ch原创 2014-09-26 15:57:03 · 1286 阅读 · 0 评论 -
命令行参数选项处理:getopt()及getopt_long()函数使用
在运行某个程序的时候,我们通常使用命令行参数来进行配置其行为。命令行选项和参数控制 UNIX 程序,告知它们如何动作。当 gcc的程序启动代码调用我们的入口函数 main(int argc,char *argv[]) 时,已经对命令行进行了处理。argc 参数包含程序参数的个数,而 argv 包含指向这些参数的指针数组。程序的参数可以分为三种:选项,选项的关联值,非选项参数。例如:原创 2014-07-04 15:36:43 · 4814 阅读 · 0 评论 -
一个奇怪BUG的记录(未根本解决)
一个奇怪BUG的记录(未根本解决).md基本逻辑:将文件夹下面的所有文件路径名,提取到一个configfile文件中,然后按行读取处理。代码: 问题:对于bash数据集没有问题,但是对于redis数据集(文件比bash少)出现segmentfault,使用gdb定位到是内存释放时候的错误(损坏了内存管理结构?)。 使用valgrind没有错误。 后来想到是否和权限有关?但是检查了打开文件时候的原创 2016-02-26 11:24:58 · 985 阅读 · 0 评论