#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
static int fl_setblock(int fd);
static int fl_clrblock(int fd);
static int lock_reg(int fd, int cmd, int type, off_t off, int whence, off_t len);
int fl_setblock(int fd)
{
long flags = fcntl(fd, F_GETFL, 0);
return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}
int fl_clrblock(int fd)
{
long flags = fcntl(fd, F_GETFL, 0);
return fcntl(fd, F_SETFL, flags & (~O_NONBLOCK));
}
/* read/write block */
/* fcntl lock */
int lock_reg(int fd, int cmd, int type, off_t off, int whence, off_t len)
{
struct flock lk = {type, whence, off, len};
// struct flock lk;
// lk.l_type = type;
// lk.l_whence = whence;
// lk.l_start = off;
// lk.l_len = len;
return fcntl(fd, cmd, &lk);
}
#define READ_LOCK(fd, off, whence, len)\
lock_reg(fd, F_SETLK, F_RDLCK, off, whence, len)
#define READW_LOCK(fd, off, whence, len)\
lock_reg(fd, F_SETLKW, F_RDLCK, off, whence, len)
#define WRITE_LOCK(fd, off, whence, len)\
lock_reg(fd, F_SETLK, F_WRLCK, off, whence, len)
#define WRITEW_LOCK(fd, off, whence, len)\
lock_reg(fd, F_SETLKW, F_WRLCK, off, whence, len)
#define UN_LOCK(fd, off, whence, len)\
lock_reg(fd, F_SETLK, F_UNLCK, off, whence, len)
static void lockbyte(const char* name, int fd, off_t off);
int main(int argc, char** argv)
{
int fd;
pid_t pid;
if ((fd = open("tmp_XXXXX", O_WRONLY|O_CREAT, 00644)) == -1)
{
perror("open(path, flags, mode)");
return -1;
}
if (write(fd, "cd", 2) != 2)
{
perror("write(fd, data, len)");
return -1;
}
// lockbyte("parent", fd, 0);
// lockbyte("parent", fd, 1);
switch (fork()){
case -1:
perror("fork(void)");
break;
case 0:
lockbyte("child", fd, 0);
sleep(3);
lockbyte("child", fd, 1);
close(fd);
// exit(0);
break;
default:
lockbyte("parent", fd, 1);
lockbyte("parent", fd, 0);
}
close(fd);
printf("hello world\n");
}
static void lockbyte(const char* name, int fd, off_t off)
{
if (WRITE_LOCK(fd, off, SEEK_SET, 1) == -1)
{
perror("write(fd, off, whence, len)");
return ;
}
printf("%s: got the lock, byte %lu\n", name, off);
}
|