mktime之夏令时

最近遇到了一件奇怪的事情,单元测试里写的一段代码在本地跑没有问题,放到Jenkins上跑就出问题。因为是跟时间相关的,所以一开始怀疑与时区有关系,跑到测试机上去看,时区配置的没有问题。代码逻辑很简单,如下:

最后打印的时间与最初传入的时间可能并不一致。

追踪了半天,最后发现是tm.tm_isdst影响了结果的正确性。tm_isdst是用来描述是否是daylight saving time的属性,而strptime由于并不能确认是否是冬令时/夏令时,所以并没有置这个值,而是保留了其原有的默认值。而原有的默认值由于没有初始化,其值会影响mktime的行为,mktime会根据tm_isdst来修正tm中的各项值。

所以,在使用struct tm前,将其初始化成全0是最安全的。

11 次浏览 | 没有评论
2016年1月12日 | 归档于 C++, Linux, 工作, 技术

圣诞快乐!

我似乎已经很久没有写日志了,久得上一篇工作总结还是写的入职两年。

原来一直在使用GoDaddy的空间,去年到期的时候,就想着要换到别的空间去,顺带着供我范强用,但是拖啊拖啊,不停地每个月续租到现在。最近一段时间,试了搬瓦工,速度不错,似乎装上Nginx,MySQL和PHP也跑得挺顺畅。

于是今天终于下定决心,搞到这里来了。

18 次浏览 | 没有评论
2015年12月24日 | 归档于 回忆录, 工作
标签: ,

树莓派的内网穿透

家里的宽带没有公网IP,从外面没有办法SSH到树莓派上。如果有公网IP的话,现在一般的路由器都支持端口转发功能,在路由器的管理界面添加一条转发规则即可。

不过有一天,我突然想到了SSH的端口转发功能,其实很简单的一条命令:

简单解释一下,-N表示了不要执行任何命令,-f表示在后台执行,-R 8022:localhost:22表示remote-host.com上将会监听8022端口,并将所有的流量转发到localhost:22端口上来。就是这么简单。

当然了,前提是你要有一台有公网IP的主机,这个就自己想办法搞定吧,比如阿里云什么的。

但是,这个办法有个缺点,树莓派重启了就失效了,可以参考[这个][autosshd],在树莓派上略加修改就能用了,把autosshd脚本放到/etc/init.d下,再执行

autosshd加到自启动项里去。其实这个脚本就是利用了autossh这个工具。

不过我对上面的那个脚本做了些修改,供大家参考:

做了几点改进:

  1. 修改了一下在树莓派上可以跑,但是很多地方还有待改进
  2. 修改了ssh的启动参数,添加了-Cq,可以man ssh自己看
  3. 添加了-o ServerAliveInterval=30 -o ServerAliveCountMax=5,可以自动检测SSH连接可用性

至此

2,315 次浏览 | 1 条评论
2014年12月15日 | 归档于 Raspberry Pi

树莓派上配置无线网络

上一篇里抱怨了没有键盘,没有显示器,没有有线网络的情况下,配置无线网络很不方便。后来通过安装XBMC暂时解决了这个问题。现在已经从XBMC转投了Raspbian,周六在家里研究了一下树莓派的无线网络配置方法。

首先要确认树莓派正确识别和支持了你的无线网卡,我买的是这一款 腾达 W311MI,在shell里运行lsusb,在我的树莓派上执行结果如下:

我们可以看到,使用的是Ralink芯片,对于USB网卡不支持的情况,我觉得通过搜索,应该是能够找到相关的驱动的。或者您在购买之前先查询一下,是否被树莓派支持。至于还有文章里说lsmod用来查询内核里是否加载了网卡的驱动,这个我就没有深究了。

方法1

基本上通过以上确认以后,下面就是扫描一下家里的无线网络了,取得一些必要的参数。使用iwlist wlan0 scanning,结果输出会很长,注意其中这部分:

确保/etc/network/interfaces的内容如下:
auto lo

这是树莓派安装完成后原版的文件内容,不要iface wlan0 inet manual改为iface wlan0 inet dhcp,我就是被这个坑了很久。

然后修改/etc/wpa_supplicant/wpa_supplicant.conf,修改后:

除了ssid和psk外,{}内的其它内容似乎都可以不配置。当然了,也可以用wpa_supplicant命令来配置,具体的可以参考这里

这种方法的好处是:1、可以实现有线网络与无线网络共存;2、可以配置多个接入点。其中奥妙之后就在于/etc/network/interfaces里的wpa-roam,前面也指出来了,这里IP获取的方式是mannual,那如果我在wpa_supplicant里配置了多个不同的网络,每个网络获取IP地址的方式不同,应该怎么处理呢,其实我们可以为每个网络指定一个名称,如上面在/etc/wpa_supplicant/wpa_supplicant.conf中指定的id_str,然后在/etc/network/interfaces中添加iface $id_str inet dhcp即可。

方法2
auto lo

这种方法是,配置比较简单,但是不支持在多个网络间漫游。

1,738 次浏览 | 没有评论
2014年12月7日 | 归档于 Raspberry Pi

我的树莓派

在北京的时候就买了个 树莓派 ,还是千辛万苦从大不列颠海淘过来了,交了50块钱的关税。搞来之后其实挺郁闷的,因为啥?因为没法玩。在公司连不上网(有认证),在家里没有显示器(其实不用显示器也能用),反正各种不折腾就不能玩。后来也就没管。再后来,到了魔都,每周回苏城,终于有机会开撸树莓派了。家里的电视有HDMI输入,直接拿了小米盒子的HDMI线接到树莓派上,开机,点亮,一切正常。但是因为没有网线,无法SSH上去,就没有办法配置无线网卡(家里没有USB键盘)。没办法配置无线网卡基本上就等于废了。后来我就装了个XBMC,这货有虚拟键盘,有可视化界面,可以直接配置无线网卡,于是我就很Happy的RUN起来了。

然后就挺入移动硬盘,装上aria2,用迅雷离线下载电影,XBMC中连的盘直接可以在小米盒子上看。

这样一直用得挺爽,直到有一天,XBMC傻逼的更新,把SSH远程登录给搞坏了,我怀疑是启动的时候SSHD没有启起来,anyway,不能远程登录啊!那作为一个Linux不就废了么!老婆实在是看不惯我周末老在家折腾这破玩意儿,批准我买个家用NAS。但是在京东上看来看去,觉得花个几千块钱买个东西就下下电影、录录家里的视频监控,还是略贵。于是转念一想,我可以买个小米路由啊,于是我就买了个小米路由,这货先不表,可玩性远不如树莓派。

买完小米路由,我才脑洞大开,尼玛啊,小米盒子之所以能支持直接访问XBMC里的文件,无非就是XBMC提供了DLNA和SAMBA的访问方式,DLNA没搞过,SAMBA搞过无数次啊!尼煤!小米路由那废柴现在已经被我降成二级路由了。(我还是得吐糟几句货,作为一个路由器,它的功能真的是太弱了,连几十块钱的路由器都支持的桥接、静态路由表啥的功能,它都不支持)

后来,我又折腾了一个上午,现在基本上都搞定了。把我装的东西,和我实现的功能,在这里罗列一下。具体的每一项,有可能的话,我再分篇展开。

aria2

Linux里的下载利器,它并不是一个简单的下载工具,你可以认为它是一个下载服务器,外部工具可以通过RPC的方式向它请求开始某个下载任务,查看下载任务的状态等等,在RPI上安装很简单sudo apt-get install aria2 -y,基本也不用什么配置吧,以Deamon的形式启动,打开远程访问即可。(TODO:补充配置文件和启动脚本

我在/etc/init.d下放了个脚本,加入到了自启动项,即可机器重启了,也能正常服务。

nginx && aria2-webui

装这货并不是为了Run一个WebServer,只是想用它来跑 aria2-webui,装上git(sudo apt-get install git -y),然后把aria2-webui的代码克隆到本地,在nginx的文件里配一个alias,指像这个文件夹即可。(TODO:补充配置文件)。然后在Chrome里装一个ThunderLixianAssistant,配置好aria2的远程RPC的URL,选择下载到本地『YAWW』,就能通过aria2来下载,然后下载的进度可以在网页上访问aria2-webui来查看。很方便。aria2下载的速度不比小米路由器下载的速度慢。

BitTorrent Sync

这货绝对是个好东西啊,可以无中心节点的在节点之同步数据。于是我在我自己外网的服务器上装了一个,在Raspberry Pi上也装了一个。即可以同步大文件,又可以同步小文件。这样我在外面的时候,如果有一些事情想让树莓派做,就把脚本写好传到公网的服务器上,通过btsync同步到家里,家里树莓派上定期扫描固定的目录下有无新的脚本,有则执行,并把结果输出到目录下。我通过公网的服务器同步下来的文件,就知道执行的结果了。

samba

安装sudo apt-get install samba samba-common-bin -y,装好以后记得用smbpasswd pi来设置一下密码。在小米盒子的高清播放器里就能连接了。当然,在任何的PC和MAC上也能连。

motion

此乃居家利器啊,安装同样很简单sudo apt-get install motion,启动也很简单sudo motion -c ./motion.conf,具体的conf文件可以在官网上看文档。这个东西有什么用呢,它可以监控USB摄像头(你随便几十块钱买的报像头基本上都能用)的画面变化,当有比较大幅度的变化的时候,会拍下一张照片或者保存一段录像。懂了吧,是不是跟某些智能摄像机宣传的功能有些像? 你如果仅仅是想通过USB摄像头拍照的话,可以装一个fswebcam,这货一个命令就能拍一张照片,也挺方便。然后用脚本把照片上传到Dropbox或者百度云之类的网盘上,在远程就能查看了。

Xware

这是迅雷出的远程下载的应用,哭晕在厕所,在这里下载,据说要选 Xware1.0.31_armel_v5te_glibc.zip

2,278 次浏览 | 没有评论
2014年12月2日 | 归档于 Raspberry Pi

tmux支持gbk编码

其实背景是这样的,我用Mac,字符编码是UTF-8,我们的开发环境是Linux,字符编码是GBK,当然我可以把终端的编码改成GBK,就能轻松使用了。但是谁叫咱总觉得把本地终端的编码改得跟Host环境不一致别扭的呢,于是只能想其他办法。我在screen里是找到了完美的解决方案的。但是tmux之前实在是玩不转。后来Google到一个工具,luit,给你举个例子,聪明的你可能就明白这东西怎么用了:

是的,就是这么简单,就可以把任何命令的输出按照你指定的格式转换为UTF-8,于是在我的.zshrc里加上一条

当我用ssh-gbk登录开发机的时候,luit会自动将输出从gbk转换到utf-8。

当然,也可以在开发机上装上luit后,加个如下的命令:

世界变得美好了,就是这样。

话说我已经从bash+screen的拥趸渐渐转移到zsh+tmux了,这个世界有多种选择,也是件美好的事情。

1,858 次浏览 | 没有评论
2014年7月22日 | 归档于 Linux
标签: , ,

如何hook一个系统调用

背景 是这样的:某高人写的library里判断了新sock出来的socket的文件句柄要>0,且不谈这个assertion是否,我们的系统在运行到某个时间后,会不满足这个断言,说明有人把stdin给关了。

仔细想了一下,没有什么地方是需要把stdin关闭掉的,只能说明程序里有bug,比如某个fd被错误的赋予了0这个初始值,在没有初始化的情况下被关闭了。这是个bug。首先想到的办法是在所有调用close的地方都加上日志,这个工作量巨大,而且很容易出现遗露。其实在Linux里可以通过插入so的方式,hook某些动态连接库里的函数。只要用户没有选择静态编译,就会调用我们替换的版本。经过一翻Google,主要参考了 这篇 文章。最后成品的代码如下:

my_close.c

使用这个方法编译:

然后在运行程序前定义LD_PRELOAD,方法为

或者

如上代码在调用close时,如果fd等于0,会coredump。

1,607 次浏览 | 3 条评论
2014年7月21日 | 归档于 Linux, 工作
标签: , , , ,

把git repository导入到svn

我这个需求确实比较奇葩。一般人都是先有了svn了,然后用git svn在本地管理一下,或者与某个git remote绑定一下。但是我的需求是先有了gitlab上的某个git repository,然后第一版写完之后,才申请了svn repository,我想把git中的内容全部导入到svn里,并且以后还是基于git svn来管理。( 因为狼厂现在统一的SCM还是SVN

然后大体思路是这样的

之后再怎么搞就比较灵活了,比如直接绑定到gitlab/master上,或者在本地开发,再merge到gitlab/master上,或者在gitlab上再建一个svn的分支。

哎,git这种先进的生产工具怎么就被一帮人调研过之后给否定了呢。

1,506 次浏览 | 没有评论
2014年7月21日 | 归档于 Linux, 技术

gdb中dump一段内存

我们会有这种需求,在 gdb 中将某段内存 dump 保存到文件中,比如一段无法在 gdb 中直接访问的二进制数据(一段私有格式的网络包什么的)。其实在 gdb 里这个命令就叫dump,这里仅给出一种简单的用法,其他的可以在gdbhelp

前面就写dump binary memory,后面接文件名,接着是起始地址,然后是尾地址。dump出来的数据怎么用就随君了。

话说都一年没写博客了,再过两天入职就三年了。

1,376 次浏览 | 没有评论
2014年7月3日 | 归档于 C++, Linux, Unix, 工作
标签: , ,

入职两年了

上个月7月13日是我入职百度满两周年的日子。一直以为我曾经在入职一周年的时候写过一篇日志,可以翻来翻去,只找到一篇入职半月小记。本还想比较一下现在与一年前的心态,此已无从考据。唯有一篇27岁了的日志,还能回想起当时所说的那些烦心事情。好在也像当时所写,现在能嘴角一扬,没有想像中的那么坏,咬咬牙,没有过不去的坎。

前段时间,跟一位老程序员聊天,说到工作,我问他你觉得怎么衡量一个工作的好坏。他告诉我,看两点,一是成长;二是收获。回想自己在百度这两年,成长,学到了、巩固了许多知识;收获,职称和薪水都有不错的涨幅。我曾经在找工作回顾(7+1):微软中写过:

去百度是做基础相关的东西,我更偏向于这个方向,而且可以继续接触Linux相关的技术,对于一个对开源有着极大热情的我来说,更偏向于选择去这里,而且百度整个就是一个互联网企业,也是符合我的初衷。

这段话大体是没有错的,但其中有一点不正确,如果对于开源有着狂热的热情的话,还是不要来百度。在百度,很多东西都是自己做的。开源的东西也用,但绝对不是主流;核心的技术一般也不会开源出去。不过好在,不用开源一般也是因为开源产品在性能、稳定性、功能等方面满足不了我们的需求,而不是非得搞个新的出来。你如果非得问我,为啥不去修改开源的实现,我只能说,有些系统在提需求的时候,业界还没有相应的开源实现。

两年了,人越来越老,老了就不想过生日;老了就更加知道有些话,只能憋肚子里,不能说出来。我想每个事物都有他好的一面与坏的一面。曾经觉得应该在五年后评价自己当初找工作的选择,那就等再过段时间,等到自己离开了这家公司,亦或是干满了五年再说。

2,827 次浏览 | 1 条评论
2013年8月12日 | 归档于 未分类
标签: