/* COPYING ******************************************************************
For copyright and licensing terms, see the file named COPYING.
// **************************************************************************
*/

#include <sys/types.h>
#include <sys/file.h>
#include <unistd.h>
#include <fcntl.h>
#include "lockfile.h"
#include "FileDescriptorOwner.h"

extern
int
open_lockfile_exclusive_or_wait_at (
	int dir_fd,
	const char * name
) {
#if defined O_EXLOCK
	return openat(dir_fd, name, O_NOCTTY|O_CLOEXEC|O_WRONLY|O_CREAT|O_APPEND|O_EXLOCK, 0600);
#else
	FileDescriptorOwner lock_fd(openat(dir_fd, name, O_NOCTTY|O_CLOEXEC|O_WRONLY|O_CREAT|O_APPEND, 0600));
	if (0 <= lock_fd.get()) {
		if (0 >	flock(lock_fd.get(), LOCK_EX))
			return -1;
	}
	return lock_fd.release();
#endif
}

extern
int
open_lockfile_shared_or_wait_at (
	int dir_fd,
	const char * name
) {
#if defined O_EXLOCK
	return openat(dir_fd, name, O_NOCTTY|O_CLOEXEC|O_WRONLY|O_CREAT|O_APPEND|O_SHLOCK, 0600);
#else
	FileDescriptorOwner lock_fd(openat(dir_fd, name, O_NOCTTY|O_CLOEXEC|O_WRONLY|O_CREAT|O_APPEND, 0600));
	if (0 <= lock_fd.get()) {
		if (0 >	flock(lock_fd.get(), LOCK_SH))
			return -1;
	}
	return lock_fd.release();
#endif
}
