LCOV - code coverage report
Current view: top level - arch/um/drivers - fd.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 19 31 61.3 %
Date: 2023-04-06 08:38:28 Functions: 3 3 100.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
       4             :  */
       5             : 
       6             : #include <stdio.h>
       7             : #include <stdlib.h>
       8             : #include <unistd.h>
       9             : #include <errno.h>
      10             : #include <termios.h>
      11             : #include "chan_user.h"
      12             : #include <os.h>
      13             : #include <um_malloc.h>
      14             : 
      15             : struct fd_chan {
      16             :         int fd;
      17             :         int raw;
      18             :         struct termios tt;
      19             :         char str[sizeof("1234567890\0")];
      20             : };
      21             : 
      22           2 : static void *fd_init(char *str, int device, const struct chan_opts *opts)
      23             : {
      24             :         struct fd_chan *data;
      25             :         char *end;
      26             :         int n;
      27             : 
      28           2 :         if (*str != ':') {
      29           0 :                 printk(UM_KERN_ERR "fd_init : channel type 'fd' must specify a "
      30             :                        "file descriptor\n");
      31           0 :                 return NULL;
      32             :         }
      33           2 :         str++;
      34           2 :         n = strtoul(str, &end, 0);
      35           2 :         if ((*end != '\0') || (end == str)) {
      36           0 :                 printk(UM_KERN_ERR "fd_init : couldn't parse file descriptor "
      37             :                        "'%s'\n", str);
      38           0 :                 return NULL;
      39             :         }
      40             : 
      41           2 :         data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
      42           2 :         if (data == NULL)
      43             :                 return NULL;
      44             : 
      45           2 :         *data = ((struct fd_chan) { .fd         = n,
      46           2 :                                     .raw        = opts->raw });
      47           2 :         return data;
      48             : }
      49             : 
      50           2 : static int fd_open(int input, int output, int primary, void *d, char **dev_out)
      51             : {
      52           2 :         struct fd_chan *data = d;
      53             :         int err;
      54             : 
      55           2 :         if (data->raw && isatty(data->fd)) {
      56           0 :                 CATCH_EINTR(err = tcgetattr(data->fd, &data->tt));
      57           0 :                 if (err)
      58             :                         return err;
      59             : 
      60           0 :                 err = raw(data->fd);
      61           0 :                 if (err)
      62             :                         return err;
      63             :         }
      64           2 :         sprintf(data->str, "%d", data->fd);
      65           2 :         *dev_out = data->str;
      66           2 :         return data->fd;
      67             : }
      68             : 
      69           2 : static void fd_close(int fd, void *d)
      70             : {
      71           2 :         struct fd_chan *data = d;
      72             :         int err;
      73             : 
      74           2 :         if (!data->raw || !isatty(fd))
      75             :                 return;
      76             : 
      77           0 :         CATCH_EINTR(err = tcsetattr(fd, TCSAFLUSH, &data->tt));
      78           0 :         if (err)
      79           0 :                 printk(UM_KERN_ERR "Failed to restore terminal state - "
      80             :                        "errno = %d\n", -err);
      81           0 :         data->raw = 0;
      82             : }
      83             : 
      84             : const struct chan_ops fd_ops = {
      85             :         .type           = "fd",
      86             :         .init           = fd_init,
      87             :         .open           = fd_open,
      88             :         .close          = fd_close,
      89             :         .read           = generic_read,
      90             :         .write          = generic_write,
      91             :         .console_write  = generic_console_write,
      92             :         .window_size    = generic_window_size,
      93             :         .free           = generic_free,
      94             :         .winch          = 1,
      95             : };

Generated by: LCOV version 1.14