190221f91SCody Peter Mello /*
290221f91SCody Peter Mello  * This file and its contents are supplied under the terms of the
390221f91SCody Peter Mello  * Common Development and Distribution License ("CDDL"), version 1.0.
490221f91SCody Peter Mello  * You may only use this file in accordance with the terms of version
590221f91SCody Peter Mello  * 1.0 of the CDDL.
690221f91SCody Peter Mello  *
790221f91SCody Peter Mello  * A full copy of the text of the CDDL should have accompanied this
890221f91SCody Peter Mello  * source.  A copy of the CDDL is also available via the Internet at
990221f91SCody Peter Mello  * http://www.illumos.org/license/CDDL.
1090221f91SCody Peter Mello  */
1190221f91SCody Peter Mello 
1290221f91SCody Peter Mello /*
13*9c7f1ae0SJerry Jelinek  * Copyright 2018 Joyent, Inc.
1490221f91SCody Peter Mello  */
1590221f91SCody Peter Mello 
1690221f91SCody Peter Mello /*
1790221f91SCody Peter Mello  * Utility functions for use in both acquire-lock and runtests.
1890221f91SCody Peter Mello  */
1990221f91SCody Peter Mello 
2090221f91SCody Peter Mello #include "util.h"
2190221f91SCody Peter Mello #include <err.h>
2290221f91SCody Peter Mello #include <errno.h>
2390221f91SCody Peter Mello #include <poll.h>
2490221f91SCody Peter Mello #include <stdarg.h>
2590221f91SCody Peter Mello #include <stdio.h>
2690221f91SCody Peter Mello #include <stdlib.h>
2790221f91SCody Peter Mello #include <strings.h>
2890221f91SCody Peter Mello #include <unistd.h>
2990221f91SCody Peter Mello 
3090221f91SCody Peter Mello 
3190221f91SCody Peter Mello boolean_t LOG = B_FALSE;
3290221f91SCody Peter Mello 
3390221f91SCody Peter Mello 
3490221f91SCody Peter Mello void
3590221f91SCody Peter Mello flock_log(const char *format, ...)
3690221f91SCody Peter Mello {
3790221f91SCody Peter Mello 	va_list ap;
3890221f91SCody Peter Mello 	if (!LOG) {
3990221f91SCody Peter Mello 		return;
4090221f91SCody Peter Mello 	}
4190221f91SCody Peter Mello 
4290221f91SCody Peter Mello 	va_start(ap, format);
4390221f91SCody Peter Mello 	(void) vfprintf(stderr, format, ap);
4490221f91SCody Peter Mello 	va_end(ap);
4590221f91SCody Peter Mello }
4690221f91SCody Peter Mello 
4790221f91SCody Peter Mello 
4890221f91SCody Peter Mello boolean_t
4990221f91SCody Peter Mello flock_nodata(int fd)
5090221f91SCody Peter Mello {
5190221f91SCody Peter Mello 	struct pollfd pfd = { fd, POLLIN, 0 };
5290221f91SCody Peter Mello 	int ret = poll(&pfd, 1, 1000);
5390221f91SCody Peter Mello 
5490221f91SCody Peter Mello 	if (ret == -1) {
5590221f91SCody Peter Mello 		err(EXIT_FAILURE, "poll failed");
5690221f91SCody Peter Mello 	}
5790221f91SCody Peter Mello 
5890221f91SCody Peter Mello 	return (ret == 0);
5990221f91SCody Peter Mello }
6090221f91SCody Peter Mello 
6190221f91SCody Peter Mello 
6290221f91SCody Peter Mello void
6390221f91SCody Peter Mello flock_block(int fd)
6490221f91SCody Peter Mello {
6590221f91SCody Peter Mello 	char buf[1];
6690221f91SCody Peter Mello 	int ret = 0;
6790221f91SCody Peter Mello 	while (ret < 1) {
6890221f91SCody Peter Mello 		ret = read(fd, buf, 1);
6990221f91SCody Peter Mello 		if (ret == -1) {
7090221f91SCody Peter Mello 			if (errno == EINTR)
7190221f91SCody Peter Mello 				continue;
7290221f91SCody Peter Mello 			err(EXIT_FAILURE, "read failed");
7390221f91SCody Peter Mello 		}
7490221f91SCody Peter Mello 	}
7590221f91SCody Peter Mello }
7690221f91SCody Peter Mello 
7790221f91SCody Peter Mello 
7890221f91SCody Peter Mello void
7990221f91SCody Peter Mello flock_alert(int fd)
8090221f91SCody Peter Mello {
8190221f91SCody Peter Mello 	int ret = 0;
8290221f91SCody Peter Mello 	while (ret < 1) {
8390221f91SCody Peter Mello 		ret = write(fd, "1", 1);
8490221f91SCody Peter Mello 		if (ret == -1) {
8590221f91SCody Peter Mello 			if (errno == EINTR)
8690221f91SCody Peter Mello 				continue;
8790221f91SCody Peter Mello 			err(EXIT_FAILURE, "write failed");
8890221f91SCody Peter Mello 		}
8990221f91SCody Peter Mello 	}
9090221f91SCody Peter Mello }
9190221f91SCody Peter Mello 
9290221f91SCody Peter Mello 
9390221f91SCody Peter Mello lock_style_t
9490221f91SCody Peter Mello flock_styleenum(char *stylestr)
9590221f91SCody Peter Mello {
9690221f91SCody Peter Mello 	if (strcmp(stylestr, "posix") == 0) {
9790221f91SCody Peter Mello 		return (LSTYLE_POSIX);
9890221f91SCody Peter Mello 	} else if (strcmp(stylestr, "ofd") == 0) {
9990221f91SCody Peter Mello 		return (LSTYLE_OFD);
10090221f91SCody Peter Mello 	} else if (strcmp(stylestr, "flock") == 0) {
10190221f91SCody Peter Mello 		return (LSTYLE_FLOCK);
10290221f91SCody Peter Mello 	} else {
10390221f91SCody Peter Mello 		errx(EXIT_FAILURE, BAD_LOCK_MESSAGE);
10490221f91SCody Peter Mello 		return (LSTYLE_LAST);
10590221f91SCody Peter Mello 	}
10690221f91SCody Peter Mello }
10790221f91SCody Peter Mello 
10890221f91SCody Peter Mello 
10990221f91SCody Peter Mello char *
11090221f91SCody Peter Mello flock_stylestr(lock_style_t style)
11190221f91SCody Peter Mello {
11290221f91SCody Peter Mello 	switch (style) {
11390221f91SCody Peter Mello 	case LSTYLE_POSIX:
11490221f91SCody Peter Mello 		return ("posix");
11590221f91SCody Peter Mello 	case LSTYLE_OFD:
11690221f91SCody Peter Mello 		return ("ofd");
11790221f91SCody Peter Mello 	case LSTYLE_FLOCK:
11890221f91SCody Peter Mello 		return ("flock");
11990221f91SCody Peter Mello 	default:
12090221f91SCody Peter Mello 		abort();
12190221f91SCody Peter Mello 		return ("<unreachable>");
12290221f91SCody Peter Mello 	}
12390221f91SCody Peter Mello }
12490221f91SCody Peter Mello 
12590221f91SCody Peter Mello 
12690221f91SCody Peter Mello char *
12790221f91SCody Peter Mello flock_stylename(lock_style_t style)
12890221f91SCody Peter Mello {
12990221f91SCody Peter Mello 	switch (style) {
13090221f91SCody Peter Mello 	case LSTYLE_POSIX:
13190221f91SCody Peter Mello 		return ("fcntl(2) POSIX");
13290221f91SCody Peter Mello 	case LSTYLE_OFD:
13390221f91SCody Peter Mello 		return ("fcntl(2) OFD");
13490221f91SCody Peter Mello 	case LSTYLE_FLOCK:
13590221f91SCody Peter Mello 		return ("flock(3C)");
13690221f91SCody Peter Mello 	default:
13790221f91SCody Peter Mello 		abort();
13890221f91SCody Peter Mello 		return ("<unreachable>");
13990221f91SCody Peter Mello 	}
14090221f91SCody Peter Mello }
14190221f91SCody Peter Mello 
14290221f91SCody Peter Mello 
14390221f91SCody Peter Mello void
14490221f91SCody Peter Mello flock_reinit(struct flock *flp, int ltype)
14590221f91SCody Peter Mello {
14690221f91SCody Peter Mello 	bzero(flp, sizeof (*flp));
14790221f91SCody Peter Mello 	flp->l_type = ltype;
14890221f91SCody Peter Mello }
14990221f91SCody Peter Mello 
15090221f91SCody Peter Mello 
15190221f91SCody Peter Mello char *
15290221f91SCody Peter Mello flock_cmdname(int cmd)
15390221f91SCody Peter Mello {
15490221f91SCody Peter Mello 	switch (cmd) {
15590221f91SCody Peter Mello 	case F_SETLK:
15690221f91SCody Peter Mello 		return ("F_SETLK");
15790221f91SCody Peter Mello 	case F_OFD_SETLK:
15890221f91SCody Peter Mello 		return ("F_OFD_SETLK");
15990221f91SCody Peter Mello 	case F_SETLKW:
16090221f91SCody Peter Mello 		return ("F_SETLKW");
16190221f91SCody Peter Mello 	case F_OFD_SETLKW:
16290221f91SCody Peter Mello 		return ("F_OFD_SETLKW");
16390221f91SCody Peter Mello 	case F_GETLK:
16490221f91SCody Peter Mello 		return ("F_GETLK");
16590221f91SCody Peter Mello 	case F_OFD_GETLK:
16690221f91SCody Peter Mello 		return ("F_OFD_GETLK");
16790221f91SCody Peter Mello 	case F_FLOCK:
16890221f91SCody Peter Mello 		return ("F_FLOCK");
16990221f91SCody Peter Mello 	case F_FLOCKW:
17090221f91SCody Peter Mello 		return ("F_FLOCKW");
171*9c7f1ae0SJerry Jelinek #if !defined(_LP64)
172*9c7f1ae0SJerry Jelinek 	case F_OFD_SETLK64:
173*9c7f1ae0SJerry Jelinek 		return ("F_OFD_SETLK64");
174*9c7f1ae0SJerry Jelinek 	case F_OFD_SETLKW64:
175*9c7f1ae0SJerry Jelinek 		return ("F_OFD_SETLKW64");
176*9c7f1ae0SJerry Jelinek 	case F_OFD_GETLK64:
177*9c7f1ae0SJerry Jelinek 		return ("F_OFD_GETLK64");
178*9c7f1ae0SJerry Jelinek #endif
17990221f91SCody Peter Mello 	default:
18090221f91SCody Peter Mello 		abort();
18190221f91SCody Peter Mello 		return ("<unreachable>");
18290221f91SCody Peter Mello 	}
18390221f91SCody Peter Mello }
184