summaryrefslogtreecommitdiff
path: root/newlib/addon/newlib/libc/sys/hurd/pipefile.c
blob: f34d1a9c2c57b10f602829b0ea02ceca8747f333 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <viengoos/misc.h>

#include "fd.h"

struct pipefile
{
  struct _fd fd;
};

static _ssize_t
pipe_pread (struct _fd *fd, void *buf, size_t size, off_t offset)
{
  struct io_buffer buffer;
  rm_read (ADDR_VOID, ADDR_VOID, size, &buffer);

  memcpy (buf, buffer.data, buffer.len);
  return buffer.len;
}

static int
pipe_ftruncate (struct _fd *fd, off_t length)
{
  errno = EPIPE;
  return -1;
}

static void
io_buffer_flush (struct io_buffer *buffer)
{
  if (buffer->len == 0)
    return;

  rm_write (ADDR_VOID, ADDR_VOID, *buffer);
  buffer->len = 0;
}

static void
io_buffer_append (struct io_buffer *buffer, int chr)
{
  if (buffer->len == sizeof (buffer->data))
    io_buffer_flush (buffer);

  buffer->data[buffer->len ++] = chr;
}

static _ssize_t
pipe_pwrite (struct _fd *fd, void *buf, size_t size, off_t offset)
{
  struct io_buffer buffer;
  buffer.len = 0;

  int i;
  for (i = 0; i < size; i ++)
    io_buffer_append (&buffer, ((char *) buf)[i]);
  io_buffer_flush (&buffer);

  return size;
}

static void
pipe_close (struct _fd *fd)
{
  struct pipefile *pipefile = (void *) fd;

  if (fd != &_stdio)
    free (pipefile);
}

static struct _fileops ops =
  {
    .pread = pipe_pread,
    .pwrite = pipe_pwrite,
    .ftruncate = pipe_ftruncate,
    .close = pipe_close,
  };

struct _fd _stdio = { 0, 0, -1, &ops };

struct _fd *
pipefile_open (const char *filename, int access)
{
  if (strcmp (filename, "/dev/stdin") != 0
      && strcmp (filename, "/dev/stdout") != 0
      && strcmp (filename, "/dev/stderr") != 0)
    return NULL;

  return &_stdio;
}