Re: [PARPORT] Using C to program printer port

From: Gora Mohanty (
Date: Tue Jan 28 2003 - 00:33:43 EST

  • Next message: Gora Mohanty: "Re: [PARPORT] Using C to program printer port"

    Simon writes:


    >You could do this as a user using libieee1284, though, which was
    >mentioned in a previous post. It is much safer and would solve the
    >problems you just pointed out. It would also make the program portable
    >to other operating systems, promote world peace, etc.

    Great idea. In the spirit of promoting world peace, and because I have been
    interested in a safe way to enable a normal user to do this, I whipped up
    the attached piece of code which will write its argument (default 1) to
    parport0. It has been tested on a Linux x86 PC. Hope this is of use to people,
    and please excuse the somewhat-grotty design of the code. I have yet to
    clean it up. Save to a file called set1284.c, and compile with, e.g.,
      gcc -O2 -ansi -pedantic -o set1284 set1284.c -lieee1284
    You will of course need libieee1284 installed in a standard location (see Run, e.g., as
      ./set1284 255
    to set all data lines to high.


    P.S. Incidentally, Tim, ieee1284.h in the version on the web has a couple
         of minor problems that I encountered: (i) include guards are missing
         which caues problems when it is included multiple times, and (ii)
         various enums have a trailing comma in the definition that triggers
         warnings with gcc -W

    #include <ieee1284.h>
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    typedef enum { ERR1284_OK = 0, ERR1284_NOMEM, ERR1284_NOTIMPL, ERR1284_INIT,
                   ERR1284_NOTAVAIL, ERR1284_INVALIDPORT, ERR1284_SYS,
                   ERR1284_REJECTED, ERR1284_NEGFAILED, ERR1284_TIMEDOUT,
    } ieee1284_err_t;

    static const char* gerr_str[ERR1284_MAX + 1] = {
      "No error (success)",
      "Not enough memory",
      "Not implemented",
      "Problem in port initialization. Port already open?",
      "Capability not available in port",
      "Invalid port. Port already open?",
      "System error",
      "Mode negotiation rejected by peripheral.",
      "Mode negotiation failed. Is peripheral IEEE 1284 compliant?",
      "Timed out waiting for peripheral to handshake",
      "Unknown error"

    static const char* s2_1284_strerror(ieee1284_err_t err_num)
      const char* error;
      switch( err_num )
        case E1284_OK:
          error = gerr_str[ERR1284_OK];

        case E1284_NOMEM:
          error = gerr_str[ERR1284_NOMEM];

        case E1284_NOTIMPL:
          error = gerr_str[ERR1284_NOTIMPL];

        case E1284_INIT:
          error = gerr_str[ERR1284_INIT];

        case E1284_NOTAVAIL:
          error = gerr_str[ERR1284_NOTAVAIL];

        case E1284_INVALIDPORT:
          error = gerr_str[ERR1284_INVALIDPORT];

        case E1284_SYS:
          error = gerr_str[ERR1284_SYS];

        case E1284_REJECTED:
          error = gerr_str[ERR1284_REJECTED];

        case E1284_NEGFAILED:
          error = gerr_str[ERR1284_NEGFAILED];

        case E1284_TIMEDOUT:
          error = gerr_str[ERR1284_TIMEDOUT];

          error = gerr_str[ERR1284_MAX];
      return error;
    static void s2_1284_err_handler(ieee1284_err_t err_num, const char* err_msg)
      if( err_msg )
        fprintf( stderr, "%s\n", err_msg );
      fprintf( stderr, "s2_1284_err_handler: %s\n", s2_1284_strerror( err_num ) );
      if( (int) err_num == E1284_SYS )
        fprintf( stderr, "\t%s\n", strerror( errno ) );
      exit( EXIT_FAILURE );
    int main(int argc, char *argv[])
      int status = EXIT_FAILURE;
      int retval;
      char buffer = 1;
      struct parport_list port_list;
      struct parport* port;
      int capability;

      if( argc > 1 )
        buffer = atoi( argv[1] ); /* What is to be written. */

      /* Find available parallel ports. */
      if( (retval = ieee1284_find_ports( &port_list, 0 )) != E1284_OK )
        s2_1284_err_handler( retval, "Failed to find ports." );
      port = port_list.portv[0]; /* Use first available port: parport 0. */

      errno = 0;
      if( (retval = ieee1284_open( port, 0, &capability )) != E1284_OK )
          fprintf( stderr, "main: unable to open port \"%s\" at base "
                   "address (0x%02x).\n", port->name,
                   (unsigned int) port->base_addr );
          s2_1284_err_handler( retval, NULL );

      /* Claim port. */
      if( (retval = ieee1284_claim( port )) != E1284_OK )
          fprintf( stderr, "main: unable to claim port \"%s\" at base "
                   "address (0x%02x).\n", port->name,
                   (unsigned int) port->base_addr );
          s2_1284_err_handler( retval, NULL );

      /* Write to port. */
      ieee1284_write_data( port, buffer );
      fprintf( stdout, "Wrote %u to port \"%s\" at base address (0x%02x).\n",
               buffer, port->name, (unsigned int) port->base_addr );

      /* Release resources. */
      ieee1284_terminate( port );
      ieee1284_release( port );
      if( (retval = ieee1284_close( port )) != E1284_OK )
          fprintf( stderr, "main: error in closing port \"%s\" at base"
                   " address (0x%02x).\n", port->name,
                   (unsigned int) port->base_addr );
          s2_1284_err_handler( retval, NULL );
      ieee1284_free_ports( &port_list );
      status = EXIT_SUCCESS;
      exit( status );
    /*@@@@@@@@@@@@@@@@@@@@@@@@@@@ END OF FILE @@@@@@@@@@@@@@@@@@@@@@@@@@*/

    -- To unsubscribe, send mail to: --
    -- with the single word "unsubscribe" in the body of the message. --

    This archive was generated by hypermail 2b29 : Tue Jan 28 2003 - 00:45:38 EST