, , , , POSIX fcntl . , ( ). , 4 .
#define F_SETLK 8
#define F_SETLKW 9
#define F_RDLCK 1
#define F_WRLCK 2
#define F_UNLCK 3
struct flock {
short l_type;
short l_whence;
long l_start;
long l_len;
short l_pid;
short l_xxx;
};
__inline int fcntl(int fd, int cmd, ...)
{
va_list a;
va_start(a, cmd);
switch(cmd)
{
case F_SETLK:
{
struct flock *l = va_arg(a, struct flock*);
switch(l->l_type)
{
case F_RDLCK:
{
OVERLAPPED o = { 0 };
HANDLE h = (HANDLE)_get_osfhandle(fd);
if (l->l_whence != SEEK_SET || l->l_start != 0 || l->l_len != 0)
{
_set_errno(ENOTSUP);
return -1;
}
if (!LockFileEx(h, LOCKFILE_FAIL_IMMEDIATELY, 0, 0, 1, &o))
{
unsigned long x = GetLastError();
_set_errno(GetLastError() == ERROR_LOCK_VIOLATION ? EAGAIN : EBADF);
return -1;
}
UnlockFile(h, 0, 0, 1, 1);
}
break;
case F_WRLCK:
{
OVERLAPPED o = { 0 };
HANDLE h = (HANDLE)_get_osfhandle(fd);
if (l->l_whence != SEEK_SET || l->l_start != 0 || l->l_len != 0)
{
_set_errno(ENOTSUP);
return -1;
}
if (!LockFileEx(h, LOCKFILE_FAIL_IMMEDIATELY|LOCKFILE_EXCLUSIVE_LOCK, 0, 1, 1, &o))
{
unsigned long x = GetLastError();
_set_errno(GetLastError() == ERROR_LOCK_VIOLATION ? EAGAIN : EBADF);
return -1;
}
UnlockFile(h, 0, 0, 0, 1);
}
break;
case F_UNLCK:
{
HANDLE h = (HANDLE)_get_osfhandle(fd);
if (l->l_whence != SEEK_SET || l->l_start != 0 || l->l_len != 0)
{
_set_errno(ENOTSUP);
return -1;
}
UnlockFile(h, 0, 0, 0, 1);
UnlockFile(h, 0, 0, 1, 1);
}
break;
default:
_set_errno(ENOTSUP);
return -1;
}
}
break;
case F_SETLKW:
{
struct flock *l = va_arg(a, struct flock*);
switch(l->l_type)
{
case F_RDLCK:
{
OVERLAPPED o = { 0 };
HANDLE h = (HANDLE)_get_osfhandle(fd);
if (l->l_whence != SEEK_SET || l->l_start != 0 || l->l_len != 0)
{
_set_errno(ENOTSUP);
return -1;
}
if(!LockFileEx(h, 0, 0, 0, 1, &o))
{
unsigned long x = GetLastError();
return -1;
}
UnlockFile(h, 0, 0, 1, 1);
}
break;
case F_WRLCK:
{
OVERLAPPED o = { 0 };
HANDLE h = (HANDLE)_get_osfhandle(fd);
if (l->l_whence != SEEK_SET || l->l_start != 0 || l->l_len != 0)
{
_set_errno(ENOTSUP);
return -1;
}
if (!LockFileEx(h, LOCKFILE_EXCLUSIVE_LOCK, 0, 1, 1, &o))
{
unsigned long x = GetLastError();
return -1;
}
UnlockFile(h, 0, 0, 0, 1);
}
break;
case F_UNLCK:
{
flock *l = va_arg(a, flock*);
HANDLE h = (HANDLE)_get_osfhandle(fd);
if (l->l_whence != SEEK_SET || l->l_start != 0 || l->l_len != 0)
{
_set_errno(ENOTSUP);
return -1;
}
UnlockFile(h, 0, 0, 0, 1);
UnlockFile(h, 0, 0, 1, 1);
}
break;
default:
_set_errno(ENOTSUP);
return -1;
}
}
break;
default:
_set_errno(ENOTSUP);
return -1;
}
return 0;
}
fcntl FileLock - , , , ( ):
, ; , .
, , . , , , i_have_both_locks_but_only_really_want_the_exclusive_lock, . ( fcntl). , , fcntl - , . std:: map fcntl, fcntl FileLock.