<commit_before>/*-
 * Copyright (c) 1994-1995 <NAME>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer
 *    in this position and unchanged.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");

#include "opt_compat.h"
#include "opt_mac.h"

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/dirent.h>
#include <sys/fcntl.h>
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/stat.h>
#include <sys/syscallsubr.h>
#include <sys/sysproto.h>
#include <sys/tty.h>
#include <sys/unistd.h>
#include <sys/vnode.h>

#include <security/mac/mac_framework.h>

#include <ufs/ufs/extattr.h>
#include <ufs/ufs/quota.h>
#include <ufs/ufs/ufsmount.h>

#ifdef COMPAT_LINUX32
#include <machine/../linux32/linux.h>
#include <machine/../linux32/linux32_proto.h>
#else
#include <machine/../linux/linux.h>
#include <machine/../linux/linux_proto.h>
#endif
#include <compat/linux/linux_util.h>

int
linux_creat(struct thread *td, struct linux_creat_args *args)
{
    char *path;
    int error;

    LCONVPATHEXIST(td, args->path, &path);

#ifdef DEBUG
	if (ldebug(creat))
		printf(ARGS(creat, "%s, %d"), path, args->mode);
#endif
    error = kern_open(td, path, UIO_SYSSPACE, O_WRONLY | O_CREAT | O_TRUNC,
	args->mode);
    LFREEPATH(path);
    return (error);
}

int
linux_open(struct thread *td, struct linux_open_args *args)
{
    struct proc *p = td->td_proc;
    char *path;
    int bsd_flags, error;

    if (args->flags & LINUX_O_CREAT)
	LCONVPATHCREAT(td, args->path, &path);
    else
	LCONVPATHEXIST(td, args->path, &path);

#ifdef DEBUG
	if (ldebug(open))
		printf(ARGS(open, "%s, 0x%x, 0x%x"),
		    path, args->flags, args->mode);
#endif
    bsd_flags = 0;
    if (args->flags & LINUX_O_RDONLY)
	bsd_flags |= O_RDONLY;
    if (args->flags & LINUX_O_WRONLY)
	bsd_flags |= O_WRONLY;
    if (args->flags & LINUX_O_RDWR)
	bsd_flags |= O_RDWR;
    if (args->flags & LINUX_O_NDELAY)
	bsd_flags |= O_NONBLOCK;
    if (args->flags & LINUX_O_APPEND)
	bsd_flags |= O_APPEND;
    if (args->flags & LINUX_O_SYNC)
	bsd_flags |= O_FSYNC;
    if (args->flags & LINUX_O_NONBLOCK)
	bsd_flags |= O_NONBLOCK;
    if (args->flags & LINUX_FASYNC)
	bsd_flags |= O_ASYNC;
    if (args->flags & LINUX_O_CREAT)
	bsd_flags |= O_CREAT;
    if (args->flags & LINUX_O_TRUNC)
	bsd_flags |= O_TRUNC;
    if (args->flags & LINUX_O_EXCL)
	bsd_flags |= O_EXCL;
    if (args->flags & LINUX_O_NOCTTY)
	bsd_flags |= O_NOCTTY;

    error = kern_open(td, path, UIO_SYSSPACE, bsd_flags, args->mode);
    PROC_LOCK(p);
    if (!error && !(bsd_flags & O_NOCTTY) &&
	SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
	struct file *fp;

	PROC_UNLOCK(p);
	error = fget(td, td->td_retval[0], &fp);
	if (!error) {
		if (fp->f_type == DTYPE_VNODE)
			fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, td->td_ucred,
			    td);
	    fdrop(fp, td);
	}
    } else {
	PROC_UNLOCK(p);
#ifdef DEBUG
	if (ldebug(open))
		printf(LMSG("open returns error %d"), error);
#endif
    }
    LFREEPATH(path);
    return error;
}
<commit_msg>Add support for LINUX_O_DIRECT, LINUX_O_DIRECT and LINUX_O_NOFOLLOW flags to open() [1]. Improve locking for accessing session control structures [2]. Try to document (most likely harmless) races in the code [3].<commit_after>/*-
 * Copyright (c) 1994-1995 <NAME>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer
 *    in this position and unchanged.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");

#include "opt_compat.h"
#include "opt_mac.h"

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/dirent.h>
#include <sys/fcntl.h>
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/stat.h>
#include <sys/sx.h>
#include <sys/syscallsubr.h>
#include <sys/sysproto.h>
#include <sys/tty.h>
#include <sys/unistd.h>
#include <sys/vnode.h>

#include <security/mac/mac_framework.h>

#include <ufs/ufs/extattr.h>
#include <ufs/ufs/quota.h>
#include <ufs/ufs/ufsmount.h>

#ifdef COMPAT_LINUX32
#include <machine/../linux32/linux.h>
#include <machine/../linux32/linux32_proto.h>
#else
#include <machine/../linux/linux.h>
#include <machine/../linux/linux_proto.h>
#endif
#include <compat/linux/linux_util.h>

int
linux_creat(struct thread *td, struct linux_creat_args *args)
{
    char *path;
    int error;

    LCONVPATHEXIST(td, args->path, &path);

#ifdef DEBUG
	if (ldebug(creat))
		printf(ARGS(creat, "%s, %d"), path, args->mode);
#endif
    error = kern_open(td, path, UIO_SYSSPACE, O_WRONLY | O_CREAT | O_TRUNC,
	args->mode);
    LFREEPATH(path);
    return (error);
}

int
linux_open(struct thread *td, struct linux_open_args *args)
{
    struct proc *p = td->td_proc;
    struct file *fp;
    int fd;
    char *path;
    int bsd_flags, error;

    if (args->flags & LINUX_O_CREAT)
	LCONVPATHCREAT(td, args->path, &path);
    else
	LCONVPATHEXIST(td, args->path, &path);

#ifdef DEBUG
	if (ldebug(open))
		printf(ARGS(open, "%s, 0x%x, 0x%x"),
		    path, args->flags, args->mode);
#endif
    bsd_flags = 0;
    if (args->flags & LINUX_O_RDONLY)
	bsd_flags |= O_RDONLY;
    if (args->flags & LINUX_O_WRONLY)
	bsd_flags |= O_WRONLY;
    if (args->flags & LINUX_O_RDWR)
	bsd_flags |= O_RDWR;
    if (args->flags & LINUX_O_NDELAY)
	bsd_flags |= O_NONBLOCK;
    if (args->flags & LINUX_O_APPEND)
	bsd_flags |= O_APPEND;
    if (args->flags & LINUX_O_SYNC)
	bsd_flags |= O_FSYNC;
    if (args->flags & LINUX_O_NONBLOCK)
	bsd_flags |= O_NONBLOCK;
    if (args->flags & LINUX_FASYNC)
	bsd_flags |= O_ASYNC;
    if (args->flags & LINUX_O_CREAT)
	bsd_flags |= O_CREAT;
    if (args->flags & LINUX_O_TRUNC)
	bsd_flags |= O_TRUNC;
    if (args->flags & LINUX_O_EXCL)
	bsd_flags |= O_EXCL;
    if (args->flags & LINUX_O_NOCTTY)
	bsd_flags |= O_NOCTTY;
    if (args->flags & LINUX_O_DIRECT)
	bsd_flags |= O_DIRECT;
    if (args->flags & LINUX_O_NOFOLLOW)
	bsd_flags |= O_NOFOLLOW;
    /* XXX LINUX_O_NOATIME: unable to be easily implemented. */

    error = kern_open(td, path, UIO_SYSSPACE, bsd_flags, args->mode);
    if (!error) {
	    fd = td->td_retval[0];
	    /*
	     * XXX In between kern_open() and fget(), another process
	     * having the same filedesc could use that fd without
	     * checking below.
	     */
	    error = fget(td, fd, &fp);
	    if (!error) {
		    sx_slock(&proctree_lock);
		    PROC_LOCK(p);
		    if (!(bsd_flags & O_NOCTTY) &&
			SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
			    PROC_UNLOCK(p);
			    sx_unlock(&proctree_lock);
			    if (fp->f_type == DTYPE_VNODE)
				    (void) fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0,
					     td->td_ucred, td);
		    } else {
			    PROC_UNLOCK(p);
			    sx_sunlock(&proctree_lock);
		    }
		    if (args->flags & LINUX_O_DIRECTORY) {
			    if (fp->f_type != DTYPE_VNODE ||
				fp->f_vnode->v_type != VDIR) {
				    error = ENOTDIR;
			    }
		    }
		    fdrop(fp, td);
		    /*
		     * XXX as above, fdrop()/kern_close() pair is racy.
		     */
		    if (error)
			    kern_close(td, fd);
	    }
    }

#ifdef DEBUG
    if (ldebug(open))
	    printf(LMSG("open returns error %d"), error);
#endif
    LFREEPATH(path);
    return error;
}

{'fraction_non_alphanumeric': 0.1267718107406668, 'fraction_numerical': 0.005090836494310242, 'mean_word_length': 3.6949390815370196, 'pattern_counts': {'":': 0, '<': 62, '<?xml version=': 0, '>': 120, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3196082', 'n_tokens_mistral': 3911, 'n_tokens_neox': 3600, 'n_words': 1029}