
/* fcntl.q: demonstration of the fcntl function (UNIX only) */

import system;

/* set and clear the FD_CLOEXEC and O_NONBLOCK flags of a file */

set_cloexec FD:Int	= fcntl FD F_SETFD (FLAGS or FD_CLOEXEC)
			    where FLAGS = fcntl FD F_GETFD ();
clr_cloexec FD:Int	= fcntl FD F_SETFD (FLAGS and not FD_CLOEXEC)
			    where FLAGS = fcntl FD F_GETFD ();

set_nonblock FD:Int	= fcntl FD F_SETFL (FLAGS or O_NONBLOCK)
			    where FLAGS = fcntl FD F_GETFL ();
clr_nonblock FD:Int	= fcntl FD F_SETFL (FLAGS and not O_NONBLOCK)
			    where FLAGS = fcntl FD F_GETFL ();

/* retrieve the descriptor flags, status flags and access mode of a file */

flags FD:Int		= (fcntl FD F_GETFD (),
			   fcntl FD F_GETFL () and not O_ACCMODE);
mode FD:Int		= fcntl FD F_GETFL () and O_ACCMODE;

/* place an advisory read or write lock on an entire file (fail if error) */

rdlock FD:Int		= () where () = fcntl FD F_SETLK (F_RDLCK, 0, 0);
wrlock FD:Int		= () where () = fcntl FD F_SETLK (F_WRLCK, 0, 0);

/* remove the lock from the file */

unlock FD:Int		= () where () = fcntl FD F_SETLK (F_UNLCK, 0, 0);

/* predicates to check whether a read or write lock could be placed */

rdlockp FD:Int		= (LOCK!0 = F_UNLCK)
			    where LOCK:Tuple =
			      fcntl FD F_GETLK (F_RDLCK, 0, 0);
wrlockp FD:Int		= (LOCK!0 = F_UNLCK)
			    where LOCK:Tuple =
			      fcntl FD F_GETLK (F_WRLCK, 0, 0);
