Initial revision
authorroland <roland>
Sun, 20 Oct 1991 01:48:26 +0000 (01:48 +0000)
committerroland <roland>
Sun, 20 Oct 1991 01:48:26 +0000 (01:48 +0000)
mach/devstream.c [new file with mode: 0644]

diff --git a/mach/devstream.c b/mach/devstream.c
new file mode 100644 (file)
index 0000000..7542f11
--- /dev/null
@@ -0,0 +1,151 @@
+/* stdio on a Mach device port.
+   Translates \n to \r on output.  */
+
+#include <ansidecl.h>
+#include <stdio.h>
+#include <mach.h>
+#include <mach/device.h>
+
+static int
+input (FILE *f)
+{
+  error_t err;
+  char *buffer;
+  size_t to_read;
+  char c;
+
+  if (f->__buffer == NULL)
+    {
+      buffer = &c;
+      to_read = 1;
+    }
+  else
+    {
+      buffer = f->__buffer;
+      to_read = f->__bufsize;
+    }
+
+  f->__eof = 0;
+
+  if (err = device_read_inband ((device_t) cookie, 0, f->__target, to_read,
+                               buffer, &nread))
+    {
+      errno = EIO;
+      f->__error = 1;
+      f->__bufp = f->__get_limit = f->__put_limit = f->__buffer;
+      return EOF;
+    }
+
+  if (f->__buffer == NULL)
+    return (unsigned char) c;
+
+  f->__get_limit = f->__buffer + nread;
+  f->__bufp = f->__buffer;
+  f->__put_limit = f->__buffer + (f->__mode.__write ? f->__bufsize : 0);
+  return (unsigned char *) *f->__bufp++;
+}
+
+static void
+output (FILE *f, int c)
+{
+  error_t err;
+  size_t to_write;
+  char *p;
+
+  if (f->__buffer == NULL)
+    {
+      if (c != EOF)
+       {
+         char cc = (unsigned char) c;
+         int wrote;
+         if (cc == '\n')
+           cc = '\r';
+         if ((err = device_write_inband ((device_t) f->__cookie, 0,
+                                         f->__target, &cc, 1, &wrote)) ||
+             wrote != 1)
+           {
+             errno = EIO;
+             f->__error = 1;
+           }
+       }
+      ++f->__target;
+      return;
+    }
+
+  if (f->__put_limit == f->__buffer)
+    {
+      f->__put_limit = f->__buffer + f->__bufsize;
+      f->__bufp = f->__buffer;
+      if (c != EOF)
+       {
+         *f->__bufp++ = (unsigned char) c;
+         c = EOF;
+       }
+    }
+
+  to_write = f->__bufp - f->__buffer;
+  p = f->__buffer;
+  while (1)
+    {
+      char *p2 = memchr (p, '\n', to_write);
+      if (p2 == NULL)
+       break;
+      *p2++ = '\r';
+      to_write -= p2 - p;
+      p = p2;
+    }
+
+  to_write = f->__bufp - f->__buffer;
+  p = f->__buffer;
+  while (to_write > 0)
+    {
+      int wrote;
+      if (err = device_write_inband ((device_t) f->__cookie, 0, f->__target,
+                                    p, to_write, &wrote))
+       {
+         errno = EIO;
+         f->__error = 1;
+         break;
+       }
+      p += wrote;
+      to_write -= wrote;
+      f->__target += wrote;
+    }
+
+  f->__bufp = f->__buffer;
+
+  if (c != EOF && !ferror (f))
+    {
+      if (f->__linebuf && (unsigned char) c == '\n')
+       {
+         static const char nl = '\r';
+         if ((err = device_write_inband ((device_t) f->__cookie, 0,
+                                         f->__target, &nl, 1, &wrote)) ||
+             wrote != 1)
+           {
+             errno = EIO;
+             f->__error = 1;
+           }
+         else
+           ++f->__target;
+       }
+      else
+       *f->__bufp++ = (unsigned char) c;
+    }
+}
+
+FILE *
+mach_open_devstream (device_t dev)
+{
+  FILE *stream = __newstream ();
+  if (stream == NULL)
+    return NULL;
+
+  stream->__cookie = (void *) dev;
+  stream->__room_funcs.__input = input;
+  stream->__room_funcs.__output = output;
+  stream->__io_funcs.__close = device_close;
+  stream->__seen = 1;
+
+  retrun stream;
+}