diff options
Diffstat (limited to 'lib/libc/sys/fcntl.c')
-rw-r--r-- | lib/libc/sys/fcntl.c | 53 |
1 files changed, 43 insertions, 10 deletions
diff --git a/lib/libc/sys/fcntl.c b/lib/libc/sys/fcntl.c index e85574a..480cc40 100644 --- a/lib/libc/sys/fcntl.c +++ b/lib/libc/sys/fcntl.c @@ -3,12 +3,6 @@ * Authors: Doug Rabson <dfr@rabson.org> * Developed with Red Inc: Alfred Perlstein <alfred@freebsd.org> * - * Copyright (c) 2014-2015 The FreeBSD Foundation. - * All rights reserved. - * - * Portions of this software were developed by Konstantin Belousov - * under sponsorship from the FreeBSD Foundation. - * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -40,17 +34,56 @@ __FBSDID("$FreeBSD$"); #include <sys/syscall.h> #include "libc_private.h" -#pragma weak fcntl +__weak_reference(__fcntl_compat, fcntl); + int -fcntl(int fd, int cmd, ...) +__fcntl_compat(int fd, int cmd, ...) { va_list args; long arg; + struct __oflock ofl; + struct flock *flp; + int res; va_start(args, cmd); arg = va_arg(args, long); va_end(args); - return (((int (*)(int, int, ...)) - __libc_interposing[INTERPOS_fcntl])(fd, cmd, arg)); + if (__getosreldate() >= 800028) { + return (__sys_fcntl(fd, cmd, arg)); + } else { + if (cmd == F_GETLK || cmd == F_SETLK || cmd == F_SETLKW) { + /* + * Convert new-style struct flock (which + * includes l_sysid) to old-style. + */ + flp = (struct flock *) (uintptr_t) arg; + ofl.l_start = flp->l_start; + ofl.l_len = flp->l_len; + ofl.l_pid = flp->l_pid; + ofl.l_type = flp->l_type; + ofl.l_whence = flp->l_whence; + + switch (cmd) { + case F_GETLK: + res = __sys_fcntl(fd, F_OGETLK, &ofl); + if (res >= 0) { + flp->l_start = ofl.l_start; + flp->l_len = ofl.l_len; + flp->l_pid = ofl.l_pid; + flp->l_type = ofl.l_type; + flp->l_whence = ofl.l_whence; + flp->l_sysid = 0; + } + return (res); + + case F_SETLK: + return (__sys_fcntl(fd, F_OSETLK, &ofl)); + + case F_SETLKW: + return (__sys_fcntl(fd, F_OSETLKW, &ofl)); + } + } + return (__sys_fcntl(fd, cmd, arg)); + } } |