static int tuntap_open()

in os-Linux/drivers/tuntap_user.c [128:194]


static int tuntap_open(void *data)
{
	struct ifreq ifr;
	struct tuntap_data *pri = data;
	char *output, *buffer;
	int err, fds[2], len, used;

	err = tap_open_common(pri->dev, pri->gate_addr);
	if (err < 0)
		return err;

	if (pri->fixed_config) {
		pri->fd = os_open_file("/dev/net/tun",
				       of_cloexec(of_rdwr(OPENFLAGS())), 0);
		if (pri->fd < 0) {
			printk(UM_KERN_ERR "Failed to open /dev/net/tun, "
			       "err = %d\n", -pri->fd);
			return pri->fd;
		}
		memset(&ifr, 0, sizeof(ifr));
		ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
		strlcpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name));
		if (ioctl(pri->fd, TUNSETIFF, &ifr) < 0) {
			err = -errno;
			printk(UM_KERN_ERR "TUNSETIFF failed, errno = %d\n",
			       errno);
			close(pri->fd);
			return err;
		}
	}
	else {
		err = socketpair(AF_UNIX, SOCK_DGRAM, 0, fds);
		if (err) {
			err = -errno;
			printk(UM_KERN_ERR "tuntap_open : socketpair failed - "
			       "errno = %d\n", errno);
			return err;
		}

		buffer = get_output_buffer(&len);
		if (buffer != NULL)
			len--;
		used = 0;

		err = tuntap_open_tramp(pri->gate_addr, &pri->fd, fds[0],
					fds[1], buffer, len, &used);

		output = buffer;
		if (err < 0) {
			printk("%s", output);
			free_output_buffer(buffer);
			printk(UM_KERN_ERR "tuntap_open_tramp failed - "
			       "err = %d\n", -err);
			return err;
		}

		pri->dev_name = uml_strdup(buffer);
		output += IFNAMSIZ;
		printk("%s", output);
		free_output_buffer(buffer);

		close(fds[0]);
		iter_addresses(pri->dev, open_addr, pri->dev_name);
	}

	return pri->fd;
}