// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
 */

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <linux/falloc.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <sys/un.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/eventfd.h>
#include <poll.h>
#include <os.h>

static void copy_stat(struct uml_stat *dst, const struct stat64 *src)
{
	*dst = ((struct uml_stat) {
		.ust_dev     = src->st_dev,     /* device */
		.ust_ino     = src->st_ino,     /* inode */
		.ust_mode    = src->st_mode,    /* protection */
		.ust_nlink   = src->st_nlink,   /* number of hard links */
		.ust_uid     = src->st_uid,     /* user ID of owner */
		.ust_gid     = src->st_gid,     /* group ID of owner */
		.ust_size    = src->st_size,    /* total size, in bytes */
		.ust_blksize = src->st_blksize, /* blocksize for filesys I/O */
		.ust_blocks  = src->st_blocks,  /* number of blocks allocated */
		.ust_atime   = src->st_atime,   /* time of last access */
		.ust_mtime   = src->st_mtime,   /* time of last modification */
		.ust_ctime   = src->st_ctime,   /* time of last change */
	});
}

int os_stat_fd(const int fd, struct uml_stat *ubuf)
{
	struct stat64 sbuf;
	int err;

	CATCH_EINTR(err = fstat64(fd, &sbuf));
	if (err < 0)
		return -errno;

	if (ubuf != NULL)
		copy_stat(ubuf, &sbuf);
	return err;
}

int os_stat_file(const char *file_name, struct uml_stat *ubuf)
{
	struct stat64 sbuf;
	int err;

	CATCH_EINTR(err = stat64(file_name, &sbuf));
	if (err < 0)
		return -errno;

	if (ubuf != NULL)
		copy_stat(ubuf, &sbuf);
	return err;
}

int os_access(const char *file, int mode)
{
	int amode, err;

	amode = (mode & OS_ACC_R_OK ? R_OK : 0) |
		(mode & OS_ACC_W_OK ? W_OK : 0) |
		(mode & OS_ACC_X_OK ? X_OK : 0) |
		(mode & OS_ACC_F_OK ? F_OK : 0);

	err = access(file, amode);
	if (err < 0)
		return -errno;

	return 0;
}

/* FIXME? required only by hostaudio (because it passes ioctls verbatim) */
int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg)
{
	int err;

	err = ioctl(fd, cmd, arg);
	if (err < 0)
		return -errno;

	return err;
}

/* FIXME: ensure namebuf in os_get_if_name is big enough */
int os_get_ifname(int fd, char* namebuf)
{
	if (ioctl(fd, SIOCGIFNAME, namebuf) < 0)
		return -errno;

	return 0;
}

int os_set_slip(int fd)
{
	int disc, sencap;

	disc = N_SLIP;
	if (ioctl(fd, TIOCSETD, &disc) < 0)
		return -errno;

	sencap = 0;
	if (ioctl(fd, SIOCSIFENCAP, &sencap) < 0)
		return -errno;

	return 0;
}

int os_mode_fd(int fd, int mode)
{
	int err;

	CATCH_EINTR(err = fchmod(fd, mode));
	if (err < 0)
		return -errno;

	return 0;
}

int os_file_type(char *file)
{
	struct uml_stat buf;
	int err;

	err = os_stat_file(file, &buf);
	if (err < 0)
		return err;

	if (S_ISDIR(buf.ust_mode))
		return OS_TYPE_DIR;
	else if (S_ISLNK(buf.ust_mode))
		return OS_TYPE_SYMLINK;
	else if (S_ISCHR(buf.ust_mode))
		return OS_TYPE_CHARDEV;
	else if (S_ISBLK(buf.ust_mode))
		return OS_TYPE_BLOCKDEV;
	else if (S_ISFIFO(buf.ust_mode))
		return OS_TYPE_FIFO;
	else if (S_ISSOCK(buf.ust_mode))
		return OS_TYPE_SOCK;
	else return OS_TYPE_FILE;
}

int os_file_mode(const char *file, struct openflags *mode_out)
{
	int err;

	*mode_out = OPENFLAGS();

	err = access(file, W_OK);
	if (err && (errno != EACCES))
		return -errno;
	else if (!err)
		*mode_out = of_write(*mode_out);

	err = access(file, R_OK);
	if (err && (errno != EACCES))
		return -errno;
	else if (!err)
		*mode_out = of_read(*mode_out);

	return err;
}

int os_open_file(const char *file, struct openflags flags, int mode)
{
	int fd, err, f = 0;

	if (flags.r && flags.w)
		f = O_RDWR;
	else if (flags.r)
		f = O_RDONLY;
	else if (flags.w)
		f = O_WRONLY;
	else f = 0;

	if (flags.s)
		f |= O_SYNC;
	if (flags.c)
		f |= O_CREAT;
	if (flags.t)
		f |= O_TRUNC;
	if (flags.e)
		f |= O_EXCL;
	if (flags.a)
		f |= O_APPEND;

	fd = open64(file, f, mode);
	if (fd < 0)
		return -errno;

	if (flags.cl && fcntl(fd, F_SETFD, 1)) {
		err = -errno;
		close(fd);
		return err;
	}

	return fd;
}

int os_connect_socket(const char *name)
{
	struct sockaddr_un sock;
	int fd, err;

	sock.sun_family = AF_UNIX;
	snprintf(sock.sun_path, sizeof(sock.sun_path), "%s", name);

	fd = socket(AF_UNIX, SOCK_STREAM, 0);
	if (fd < 0) {
		err = -errno;
		goto out;
	}

	err = connect(fd, (struct sockaddr *) &sock, sizeof(sock));
	if (err) {
		err = -errno;
		goto out_close;
	}

	return fd;

out_close:
	close(fd);
out:
	return err;
}

int os_dup_file(int fd)
{
	int new_fd = dup(fd);

	if (new_fd < 0)
		return -errno;

	return new_fd;
}

void os_close_file(int fd)
{
	close(fd);
}
int os_fsync_file(int fd)
{
	if (fsync(fd) < 0)
	    return -errno;
	return 0;
}

int os_seek_file(int fd, unsigned long long offset)
{
	unsigned long long actual;

	actual = lseek64(fd, offset, SEEK_SET);
	if (actual != offset)
		return -errno;
	return 0;
}

int os_read_file(int fd, void *buf, int len)
{
	int n = read(fd, buf, len);

	if (n < 0)
		return -errno;
	return n;
}

int os_pread_file(int fd, void *buf, int len, unsigned long long offset)
{
	int n = pread(fd, buf, len, offset);

	if (n < 0)
		return -errno;
	return n;
}

int os_write_file(int fd, const void *buf, int len)
{
	int n = write(fd, (void *) buf, len);

	if (n < 0)
		return -errno;
	return n;
}

int os_sync_file(int fd)
{
	int n = fdatasync(fd);

	if (n < 0)
		return -errno;
	return n;
}

int os_pwrite_file(int fd, const void *buf, int len, unsigned long long offset)
{
	int n = pwrite(fd, (void *) buf, len, offset);

	if (n < 0)
		return -errno;
	return n;
}


int os_file_size(const char *file, unsigned long long *size_out)
{
	struct uml_stat buf;
	int err;

	err = os_stat_file(file, &buf);
	if (err < 0) {
		printk(UM_KERN_ERR "Couldn't stat \"%s\" : err = %d\n", file,
		       -err);
		return err;
	}

	if (S_ISBLK(buf.ust_mode)) {
		int fd;
		long blocks;

		fd = open(file, O_RDONLY, 0);
		if (fd < 0) {
			err = -errno;
			printk(UM_KERN_ERR "Couldn't open \"%s\", "
			       "errno = %d\n", file, errno);
			return err;
		}
		if (ioctl(fd, BLKGETSIZE, &blocks) < 0) {
			err = -errno;
			printk(UM_KERN_ERR "Couldn't get the block size of "
			       "\"%s\", errno = %d\n", file, errno);
			close(fd);
			return err;
		}
		*size_out = ((long long) blocks) * 512;
		close(fd);
	}
	else *size_out = buf.ust_size;

	return 0;
}

int os_file_modtime(const char *file, long long *modtime)
{
	struct uml_stat buf;
	int err;

	err = os_stat_file(file, &buf);
	if (err < 0) {
		printk(UM_KERN_ERR "Couldn't stat \"%s\" : err = %d\n", file,
		       -err);
		return err;
	}

	*modtime = buf.ust_mtime;
	return 0;
}

int os_set_exec_close(int fd)
{
	int err;

	CATCH_EINTR(err = fcntl(fd, F_SETFD, FD_CLOEXEC));

	if (err < 0)
		return -errno;
	return err;
}

int os_pipe(int *fds, int stream, int close_on_exec)
{
	int err, type = stream ? SOCK_STREAM : SOCK_DGRAM;

	err = socketpair(AF_UNIX, type, 0, fds);
	if (err < 0)
		return -errno;

	if (!close_on_exec)
		return 0;

	err = os_set_exec_close(fds[0]);
	if (err < 0)
		goto error;

	err = os_set_exec_close(fds[1]);
	if (err < 0)
		goto error;

	return 0;

 error:
	printk(UM_KERN_ERR "os_pipe : Setting FD_CLOEXEC failed, err = %d\n",
	       -err);
	close(fds[1]);
	close(fds[0]);
	return err;
}

int os_set_fd_async(int fd)
{
	int err, flags;

	flags = fcntl(fd, F_GETFL);
	if (flags < 0)
		return -errno;

	flags |= O_ASYNC | O_NONBLOCK;
	if (fcntl(fd, F_SETFL, flags) < 0) {
		err = -errno;
		printk(UM_KERN_ERR "os_set_fd_async : failed to set O_ASYNC "
		       "and O_NONBLOCK on fd # %d, errno = %d\n", fd, errno);
		return err;
	}

	if ((fcntl(fd, F_SETSIG, SIGIO) < 0) ||
	    (fcntl(fd, F_SETOWN, os_getpid()) < 0)) {
		err = -errno;
		printk(UM_KERN_ERR "os_set_fd_async : Failed to fcntl F_SETOWN "
		       "(or F_SETSIG) fd %d, errno = %d\n", fd, errno);
		return err;
	}

	return 0;
}

int os_clear_fd_async(int fd)
{
	int flags;

	flags = fcntl(fd, F_GETFL);
	if (flags < 0)
		return -errno;

	flags &= ~(O_ASYNC | O_NONBLOCK);
	if (fcntl(fd, F_SETFL, flags) < 0)
		return -errno;
	return 0;
}

int os_set_fd_block(int fd, int blocking)
{
	int flags;

	flags = fcntl(fd, F_GETFL);
	if (flags < 0)
		return -errno;

	if (blocking)
		flags &= ~O_NONBLOCK;
	else
		flags |= O_NONBLOCK;

	if (fcntl(fd, F_SETFL, flags) < 0)
		return -errno;

	return 0;
}

int os_accept_connection(int fd)
{
	int new;

	new = accept(fd, NULL, 0);
	if (new < 0)
		return -errno;
	return new;
}

#ifndef SHUT_RD
#define SHUT_RD 0
#endif

#ifndef SHUT_WR
#define SHUT_WR 1
#endif

#ifndef SHUT_RDWR
#define SHUT_RDWR 2
#endif

int os_shutdown_socket(int fd, int r, int w)
{
	int what, err;

	if (r && w)
		what = SHUT_RDWR;
	else if (r)
		what = SHUT_RD;
	else if (w)
		what = SHUT_WR;
	else
		return -EINVAL;

	err = shutdown(fd, what);
	if (err < 0)
		return -errno;
	return 0;
}

/**
 * os_rcv_fd_msg - receive message with (optional) FDs
 * @fd: the FD to receive from
 * @fds: the array for FDs to write to
 * @n_fds: number of FDs to receive (@fds array size)
 * @data: the message buffer
 * @data_len: the size of the message to receive
 *
 * Receive a message with FDs.
 *
 * Returns: the size of the received message, or an error code
 */
ssize_t os_rcv_fd_msg(int fd, int *fds, unsigned int n_fds,
		      void *data, size_t data_len)
{
#define MAX_RCV_FDS	2
	char buf[CMSG_SPACE(sizeof(*fds) * MAX_RCV_FDS)];
	struct cmsghdr *cmsg;
	struct iovec iov = {
		.iov_base = data,
		.iov_len = data_len,
	};
	struct msghdr msg = {
		.msg_iov = &iov,
		.msg_iovlen = 1,
		.msg_control = buf,
		.msg_controllen = CMSG_SPACE(sizeof(*fds) * n_fds),
	};
	int n;

	if (n_fds > MAX_RCV_FDS)
		return -EINVAL;

	n = recvmsg(fd, &msg, 0);
	if (n < 0)
		return -errno;

	cmsg = CMSG_FIRSTHDR(&msg);
	if (!cmsg ||
	    cmsg->cmsg_level != SOL_SOCKET ||
	    cmsg->cmsg_type != SCM_RIGHTS)
		return n;

	memcpy(fds, CMSG_DATA(cmsg), cmsg->cmsg_len);
	return n;
}

int os_create_unix_socket(const char *file, int len, int close_on_exec)
{
	struct sockaddr_un addr;
	int sock, err;

	sock = socket(PF_UNIX, SOCK_DGRAM, 0);
	if (sock < 0)
		return -errno;

	if (close_on_exec) {
		err = os_set_exec_close(sock);
		if (err < 0)
			printk(UM_KERN_ERR "create_unix_socket : "
			       "close_on_exec failed, err = %d", -err);
	}

	addr.sun_family = AF_UNIX;

	snprintf(addr.sun_path, len, "%s", file);

	err = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
	if (err < 0)
		return -errno;

	return sock;
}

void os_flush_stdout(void)
{
	fflush(stdout);
}

int os_lock_file(int fd, int excl)
{
	int type = excl ? F_WRLCK : F_RDLCK;
	struct flock lock = ((struct flock) { .l_type	= type,
					      .l_whence	= SEEK_SET,
					      .l_start	= 0,
					      .l_len	= 0 } );
	int err, save;

	err = fcntl(fd, F_SETLK, &lock);
	if (!err)
		goto out;

	save = -errno;
	err = fcntl(fd, F_GETLK, &lock);
	if (err) {
		err = -errno;
		goto out;
	}

	printk(UM_KERN_ERR "F_SETLK failed, file already locked by pid %d\n",
	       lock.l_pid);
	err = save;
 out:
	return err;
}

unsigned os_major(unsigned long long dev)
{
	return major(dev);
}

unsigned os_minor(unsigned long long dev)
{
	return minor(dev);
}

unsigned long long os_makedev(unsigned major, unsigned minor)
{
	return makedev(major, minor);
}

int os_falloc_punch(int fd, unsigned long long offset, int len)
{
	int n = fallocate(fd, FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE, offset, len);

	if (n < 0)
		return -errno;
	return n;
}

int os_falloc_zeroes(int fd, unsigned long long offset, int len)
{
	int n = fallocate(fd, FALLOC_FL_ZERO_RANGE|FALLOC_FL_KEEP_SIZE, offset, len);

	if (n < 0)
		return -errno;
	return n;
}

int os_eventfd(unsigned int initval, int flags)
{
	int fd = eventfd(initval, flags);

	if (fd < 0)
		return -errno;
	return fd;
}

int os_sendmsg_fds(int fd, const void *buf, unsigned int len, const int *fds,
		   unsigned int fds_num)
{
	struct iovec iov = {
		.iov_base = (void *) buf,
		.iov_len = len,
	};
	union {
		char control[CMSG_SPACE(sizeof(*fds) * OS_SENDMSG_MAX_FDS)];
		struct cmsghdr align;
	} u;
	unsigned int fds_size = sizeof(*fds) * fds_num;
	struct msghdr msg = {
		.msg_iov = &iov,
		.msg_iovlen = 1,
		.msg_control = u.control,
		.msg_controllen = CMSG_SPACE(fds_size),
	};
	struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
	int err;

	if (fds_num > OS_SENDMSG_MAX_FDS)
		return -EINVAL;
	memset(u.control, 0, sizeof(u.control));
	cmsg->cmsg_level = SOL_SOCKET;
	cmsg->cmsg_type = SCM_RIGHTS;
	cmsg->cmsg_len = CMSG_LEN(fds_size);
	memcpy(CMSG_DATA(cmsg), fds, fds_size);
	err = sendmsg(fd, &msg, 0);

	if (err < 0)
		return -errno;
	return err;
}

int os_poll(unsigned int n, const int *fds)
{
	/* currently need 2 FDs at most so avoid dynamic allocation */
	struct pollfd pollfds[2] = {};
	unsigned int i;
	int ret;

	if (n > ARRAY_SIZE(pollfds))
		return -EINVAL;

	for (i = 0; i < n; i++) {
		pollfds[i].fd = fds[i];
		pollfds[i].events = POLLIN;
	}

	ret = poll(pollfds, n, -1);
	if (ret < 0)
		return -errno;

	/* Return the index of the available FD */
	for (i = 0; i < n; i++) {
		if (pollfds[i].revents)
			return i;
	}

	return -EIO;
}

void *os_mmap_rw_shared(int fd, size_t size)
{
	void *res = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

	if (res == MAP_FAILED)
		return NULL;

	return res;
}

void *os_mremap_rw_shared(void *old_addr, size_t old_size, size_t new_size)
{
	void *res;

	res = mremap(old_addr, old_size, new_size, MREMAP_MAYMOVE, NULL);

	if (res == MAP_FAILED)
		return NULL;

	return res;
}
