delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1998/01/12/14:47:56

From: Gertjan Klein <gklein AT xs4all DOT nl>
Newsgroups: comp.os.msdos.djgpp
Subject: Re: Help: read/write from printer port
Date: 12 Jan 1998 15:31:06 +0100
Organization: XS4ALL, networking for the masses
Lines: 95
Message-ID: <69d9fa$prn$1@xs2.xs4all.nl>
References: <01bd1cc1$d4914d00$ab51e0ce AT rhasty>
NNTP-Posting-Host: xs2.xs4all.nl
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

In article <01bd1cc1$d4914d00$ab51e0ce AT rhasty>,
"Richard Hasty" <rhasty AT io DOT com> wrote:

 > I was thinking I'd
 > be able to just use "open" and pretend I was writing to a file called LPT1
 > or PRN.

  You can.

 > The code (only a
 > few lines) is at the end of the message. It bombs on the write operation.

  That's not much of a problem description.

 > Is there a better way of doing it?

  Yes (although what you tried should work).  It is usually better to
avoid using write(); it is not portable, and it's use doesn't really buy
you anything. Use fwrite() instead.

 > I was thinking of trying to just write to the correct memory address.

  This is _definitely_ a bad idea.  Stay as high-level as you can!  That
means use (in this order):

 - Standard ANSI functions
 - Standard POSIX functions
 - Compiler-specific functions
 - Direct DOS calls
 - Direct BIOS calls
 - Direct hardware access

  This way you avoid all sorts of nasty problems you'd face if you
change OS, compiler, or even compiler version.

  I didn't actually test you code; instead I rewrote it using the ANSI
fwrite() and fopen() calls.  This works here; if you have any problems
with it, please post a more specific description of your problem.  A few
things to keep in mind:

 - Both the C library and the OS may do some form of buffering, so you
may not immediately see what you print.  To flush the C library buffers
inside your program, use fflush(prn).  (You don't need to do that here
because you immediately close the file, which also flushes the buffers).

 - The printer may do it's own buffering, especially if it's a laser;
usually it has a button to make it print what it's got so far;
alternatively you could send it a formfeed (fputc('\f', prn)).

 - The printer may require line endings to be \r\n rather than just \n.
There are several ways to deal with this.  If you work under DOS,
opening the printer in text mode will tranlate all \n into \r\n (but
makes it hard to send binary data).  Opening the printer in binary mode,
you could just write \r\n everywhere.

 - The code below #define's PRINTER to be "prn".  The code uses a C
feature called string concatenation to insert the real printer name into
the error strings.  (String concatenation basically means that "one"
"two" is concatenated to "onetwo").  After changing the define to
"/dev/lp0", the code compiles and runs under e.g. Linux too.

  Gertjan.

#include <stdio.h>
#include <string.h>

#define PRINTER "prn"

int main(void)
{
  FILE *prn;
  char *printme = "This must be printed!\r\n";
  int len = strlen(printme);

  if((prn = fopen(PRINTER, "wb")) == NULL)
  {
    printf("Error: Cannot open " PRINTER);
    return 1;
  }

  if(fwrite(printme, 1, len, prn) != len)
  {
    printf("Write error on " PRINTER);
    return 1;
  }

  fputc('\f', prn);

  fclose(prn);
  return 0;
}

-- 
Gertjan Klein <gklein AT xs4all DOT nl>
The Boot Control home page: http://www.xs4all.nl/~gklein/bcpage.html

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019