昨天在研究dropbear实现时,看到初始化脚本/etc/init.d/dropbear中有关于文件锁lock的内容,如下:
lock /tmp/.switch2jffs
mkdir -p /etc/dropbear mv /tmp/dropbear/dropbear_* /etc/dropbear/ lock -u /tmp/.switch2jffs以为lock是linux命令,百度一下,发现没有这个命令,查找lock来源:
root@hbg:/# which lock/bin/lockroot@hbg:/# ls -al /bin/locklrwxrwxrwx 1 root root 7 Jan 17 14:20 /bin/lock -> busyboxroot@hbg:/#
在busybox中查看到了源码:
代码很简单,lock有三个参数可选:
root@hbg:/# lock -hUsage: lock [-suw] <filename> -s Use shared locking 使用共享锁 -u Unlock 解锁 -w Wait for the lock to become free, don't acquire lock 阻塞等待解锁
主要代码如下:
static int do_lock(void){ int pid; char pidstr[8];
// 打开文件 if ((fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0700)) < 0) { if ((fd = open(file, O_RDWR)) < 0) { fprintf(stderr, "Can't open %s\n", file); return 1; } } // 加锁(共享锁或互斥锁) if (flock(fd, (shared ? LOCK_SH : LOCK_EX)) < 0) { fprintf(stderr, "Can't lock %s\n", file); return 1; } pid = fork(); if (pid < 0) return -1; // 子进程 if (pid == 0) { signal(SIGKILL, exit_unlock); signal(SIGTERM, exit_unlock); signal(SIGINT, exit_unlock); if (waitonly) exit_unlock(0); else while (1) sleep(1); } else { // 父进程 if (!waitonly) { lseek(fd, 0, SEEK_SET); ftruncate(fd, 0); sprintf(pidstr, "%d\n", pid); write(fd, pidstr, strlen(pidstr)); close(fd); } return 0; } return 0;通过代码可以看到调用的是flock函数。
=====================================
简单了解一下flock函数:
#include <sys/file.h>int flock(int fd, int operation);参数operation有一下四种情况:LOCK_SH:建立共享锁,多个进程可以对同一个文件作共享锁定。LOCK_EX:建立互斥锁,一个文件同时只有一个互斥锁定。LOCK_UN:解除文件锁定状态。LOCK_NB:无法建立锁定时,此操作可被阻断,马上返回进程。通常与LOCK_SH或LOCK_EX做OR(|)组合。单一文件无法同时建立共享锁定或互斥锁定,当使用dup()或fork()时文件描述词不会继承此种锁定。返回0表示成功,-1表示错误,错误代码存于errno中。
flock只能对整个文件加锁,不能对文件的一部分进行加锁。