1#!/bin/sh 2 3# 4# SPDX-License-Identifier: BSD-2-Clause-FreeBSD 5# 6# Copyright (c) 2021 Konstantin Belousov <kib@FreeBSD.org> 7# 8# Redistribution and use in source and binary forms, with or without 9# modification, are permitted provided that the following conditions 10# are met: 11# 1. Redistributions of source code must retain the above copyright 12# notice, this list of conditions and the following disclaimer. 13# 2. Redistributions in binary form must reproduce the above copyright 14# notice, this list of conditions and the following disclaimer in the 15# documentation and/or other materials provided with the distribution. 16# 17# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27# SUCH DAMAGE. 28# 29 30# Test of open(2) with the O_RESOLVE_BENEATH flag. 31 32# userret: returning with the following locks held: 33# shared lockmgr ufs (ufs) r = 0 (0xfffff804ec0d2a48) locked @ 34# kern/vfs_subr.c:2590 seen in WiP code: 35# https://people.freebsd.org/~pho/stress/log/kostik1126.txt 36 37top=/tmp/beneath.d 38mkdir -p $top 39cat > $top/beneath.c <<EOF 40/* $Id: beneath.c,v 1.1 2018/10/13 16:53:02 kostik Exp kostik $ */ 41 42#include <sys/stat.h> 43#include <errno.h> 44#include <fcntl.h> 45#include <stdio.h> 46#include <string.h> 47#include <unistd.h> 48 49int 50main(int argc, char *argv[]) 51{ 52 struct stat st; 53 char *name; 54 int error, fd, i; 55 56 for (i = 1; i < argc; i++) { 57 name = argv[i]; 58 alarm(120); 59 fd = open(name, O_RDONLY | O_RESOLVE_BENEATH); 60 if (fd == -1) { 61 fprintf(stderr, "open(\"%s\") failed, error %d %s\n", 62 name, errno, strerror(errno)); 63 } else { 64 fprintf(stderr, "open(\"%s\") succeeded\n", name); 65 close(fd); 66 } 67 error = fstatat(AT_FDCWD, name, &st, AT_RESOLVE_BENEATH); 68 if (error == -1){ 69 fprintf(stderr, "stat(\"%s\") failed, error %d %s\n", 70 name, errno, strerror(errno)); 71 } else { 72 fprintf(stderr, "stat(\"%s\") succeeded\n", name); 73 } 74 } 75} 76EOF 77cc -o $top/beneath -Wall -Wextra $top/beneath.c || exit 1 78rm $top/beneath.c 79 80# Test with two directories as arguments: 81cd $top 82mkdir -p a/b 83./beneath a/b 84./beneath $top/a/b 85touch $top/a/c 86./beneath a/c 87./beneath $top/a/c 88./beneath a/d 89./beneath $top/a/d 90 91# CWD is still $top for this test 92top2=/var/tmp/beneath.d 93mkdir -p $top2 94mkdir -p $top2/a/b 95./beneath $top2/a/b > /dev/null 2>&1 96 97touch $top2/a/c 98./beneath $top2/a/c > /dev/null 2>&1 99 100# Other CWDs 101(cd /etc; find . | head -1000 | xargs $top/beneath) > /dev/null 2>&1 102(cd /var; find . | head -1000 | xargs $top/beneath) > /dev/null 2>&1 103 104rm -rf $top $top2 105exit 0 106