fcntl.c revision 276630
1177911Sdfr/*-
2177911Sdfr * Copyright (c) 2008 Isilon Inc http://www.isilon.com/
3177911Sdfr * Authors: Doug Rabson <dfr@rabson.org>
4177911Sdfr * Developed with Red Inc: Alfred Perlstein <alfred@freebsd.org>
5177911Sdfr *
6177911Sdfr * Redistribution and use in source and binary forms, with or without
7177911Sdfr * modification, are permitted provided that the following conditions
8177911Sdfr * are met:
9177911Sdfr * 1. Redistributions of source code must retain the above copyright
10177911Sdfr *    notice, this list of conditions and the following disclaimer.
11177911Sdfr * 2. Redistributions in binary form must reproduce the above copyright
12177911Sdfr *    notice, this list of conditions and the following disclaimer in the
13177911Sdfr *    documentation and/or other materials provided with the distribution.
14177911Sdfr *
15177911Sdfr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16177911Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17177911Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18177911Sdfr * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19177911Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20177911Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21177911Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22177911Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23177911Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24177911Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25177911Sdfr * SUCH DAMAGE.
26177911Sdfr */
27177911Sdfr
28177911Sdfr#include <sys/cdefs.h>
29177911Sdfr__FBSDID("$FreeBSD: head/lib/libc/sys/fcntl.c 276630 2015-01-03 18:38:46Z kib $");
30177911Sdfr
31177911Sdfr#include <fcntl.h>
32177911Sdfr#include <stdarg.h>
33177911Sdfr#include <sys/types.h>
34177911Sdfr#include <sys/syscall.h>
35177911Sdfr#include "libc_private.h"
36177911Sdfr
37276630Skib#pragma weak fcntl
38276630Skibint
39276630Skibfcntl(int fd, int cmd, ...)
40276630Skib{
41276630Skib	va_list args;
42276630Skib	long arg;
43179358Sdfr
44276630Skib	va_start(args, cmd);
45276630Skib	arg = va_arg(args, long);
46276630Skib	va_end(args);
47276630Skib
48276630Skib	return (((int (*)(int, int, ...))
49276630Skib	    __libc_interposing[INTERPOS_fcntl])(fd, cmd, arg));
50276630Skib}
51276630Skib
52276630Skib#ifdef SYSCALL_COMPAT
53276630Skib__weak_reference(__fcntl_compat, __fcntl);
54276630Skib
55177911Sdfrint
56179434Sdfr__fcntl_compat(int fd, int cmd, ...)
57177911Sdfr{
58177911Sdfr	va_list args;
59177911Sdfr	long arg;
60238667Skib	struct __oflock ofl;
61177911Sdfr	struct flock *flp;
62177911Sdfr	int res;
63177911Sdfr
64177911Sdfr	va_start(args, cmd);
65177911Sdfr	arg = va_arg(args, long);
66177911Sdfr	va_end(args);
67177911Sdfr
68177911Sdfr	if (__getosreldate() >= 800028) {
69177911Sdfr		return (__sys_fcntl(fd, cmd, arg));
70177911Sdfr	} else {
71177911Sdfr		if (cmd == F_GETLK || cmd == F_SETLK || cmd == F_SETLKW) {
72177911Sdfr			/*
73177911Sdfr			 * Convert new-style struct flock (which
74177911Sdfr			 * includes l_sysid) to old-style.
75177911Sdfr			 */
76177911Sdfr			flp = (struct flock *) (uintptr_t) arg;
77177911Sdfr			ofl.l_start = flp->l_start;
78177911Sdfr			ofl.l_len = flp->l_len;
79177911Sdfr			ofl.l_pid = flp->l_pid;
80177911Sdfr			ofl.l_type = flp->l_type;
81177911Sdfr			ofl.l_whence = flp->l_whence;
82177911Sdfr
83177911Sdfr			switch (cmd) {
84177911Sdfr			case F_GETLK:
85177911Sdfr				res = __sys_fcntl(fd, F_OGETLK, &ofl);
86177911Sdfr				if (res >= 0) {
87177911Sdfr					flp->l_start = ofl.l_start;
88177911Sdfr					flp->l_len = ofl.l_len;
89177911Sdfr					flp->l_pid = ofl.l_pid;
90177911Sdfr					flp->l_type = ofl.l_type;
91177911Sdfr					flp->l_whence = ofl.l_whence;
92177911Sdfr					flp->l_sysid = 0;
93177911Sdfr				}
94177911Sdfr				return (res);
95177911Sdfr
96177911Sdfr			case F_SETLK:
97177911Sdfr				return (__sys_fcntl(fd, F_OSETLK, &ofl));
98177911Sdfr
99177911Sdfr			case F_SETLKW:
100177911Sdfr				return (__sys_fcntl(fd, F_OSETLKW, &ofl));
101177911Sdfr			}
102177911Sdfr		}
103177911Sdfr		return (__sys_fcntl(fd, cmd, arg));
104177911Sdfr	}
105177911Sdfr}
106276630Skib#else
107276630Skib__weak_reference(__sys_fcntl, __fcntl_compat);
108276630Skib__weak_reference(__sys_fcntl, __fcntl);
109276630Skib#endif
110