[comp.lang.perl] ioctl

worley@compass.com (Dale Worley) (03/03/90)

I just installed patch 9-12 and the following fragment of code has
stopped working:

    # set CBREAK, so we can read the responses from the shelltool to $queryiconified
    do '/compass/c/worley/perl-3.0/ioctl.pl';
    $sgttyb_t = "ccccs";          # 4 chars and a short
    if (ioctl(STDIN,$TIOCGETP,$sgttyb)) {
	 @ary = unpack($sgttyb_t,$sgttyb);
	 $ary[4] |= $CBREAK;
	 $sgttyb = pack($sgttyb_t,@ary);
	 ioctl(STDIN,$TIOCSETP,$sgttyb)
	      || die "Can't ioctl: $!";
    }

The message I get is:

    Can't ioctl: Inappropriate ioctl for device at /compass/c/worley/bin/lpq.pl line 41.

The purpose of the code is to set CBREAK on STDIN.  I'm running SunOS
4.0.3 (BSD 4.2) on a Sun 3/50.

Since I don't know much about I/O programming on Unix or the internals
of Perl, might someone out there know what the problem is?

Thanks,

Dale Worley		Compass, Inc.			worley@compass.com
--
Do you believe in therapy? -- Sex, Lies, and Videotape

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (03/03/90)

In article <2969@uvaarpa.virginia.edu> worley@compass.com writes:
: I just installed patch 9-12 and the following fragment of code has
: stopped working:
: 
:     # set CBREAK, so we can read the responses from the shelltool to $queryiconified
:     do '/compass/c/worley/perl-3.0/ioctl.pl';
:     $sgttyb_t = "ccccs";          # 4 chars and a short
:     if (ioctl(STDIN,$TIOCGETP,$sgttyb)) {
: 	 @ary = unpack($sgttyb_t,$sgttyb);
: 	 $ary[4] |= $CBREAK;
: 	 $sgttyb = pack($sgttyb_t,@ary);
: 	 ioctl(STDIN,$TIOCSETP,$sgttyb)
: 	      || die "Can't ioctl: $!";
:     }
: 
: The message I get is:
: 
:     Can't ioctl: Inappropriate ioctl for device at /compass/c/worley/bin/lpq.pl line 41.

The problem has to do with the fact that Sun won't cast a negative float
to an unsigned long.  It used to just cast to a long, but that gave
other machines heartburn.  I'll see what I can do about it.

In the meantime, try saying

	$TIOCSETP += 2**32 if $TIOCSETP < 0;

It should only be necessary on ioctl()s that copy data into the kernel.

Larry

jra@equinox.unr.edu (John Anderson) (05/16/91)

i'm a perl rookie... i've been reading the nutshell book, etc. and am
attempting some ioctl() stuff and am getting a generic error msg.
perhaps someone could give me a pointer to more info.

here's the chunk in question:
--
#
# $r_tty is set to "+</dev/tty1"
#
open(TTY_IN, $r_tty) || die "Can't open $r_tty ($!)";

require 'sys/termio.ph';   # h2ph'ed
require 'sys/ioctl.ph';
$termio_t = "SSSSccccccccc"; # template of struct termio <sys/termio.h>

$foo = ioctl(TTY_IN, &TCGETA, $termio) || die "Can't get termio values: $!";
--
error msg:
Return value overflowed string at hang line 31.

i'm wondering if $foo is getting overflowed or $termio?!
line 31 is the ioctl line... i've tried tweaking here and there
(hard-coding the device in open(), etc.) to no avail, am reading the
passages that ioctl() is system dependent etc. the system that i'm
running this on is an IBM rs6000 (aix3.1 - no updates), perl4.003. 
any help would be appreciated.

thanks.
jra@equinox.unr.edu
John Anderson
University of Nevada-Reno

lwall@jpl-devvax.jpl.nasa.gov (Larry Wall) (05/18/91)

In article <6279@tahoe.unr.edu> jra@equinox.unr.edu (John Anderson) writes:
: i'm a perl rookie... i've been reading the nutshell book, etc. and am
: attempting some ioctl() stuff and am getting a generic error msg.
: perhaps someone could give me a pointer to more info.
: 
: here's the chunk in question:
: --
: #
: # $r_tty is set to "+</dev/tty1"
: #
: open(TTY_IN, $r_tty) || die "Can't open $r_tty ($!)";
: 
: require 'sys/termio.ph';   # h2ph'ed
: require 'sys/ioctl.ph';
: $termio_t = "SSSSccccccccc"; # template of struct termio <sys/termio.h>
: 
: $foo = ioctl(TTY_IN, &TCGETA, $termio) || die "Can't get termio values: $!";
: --
: error msg:
: Return value overflowed string at hang line 31.
: 
: i'm wondering if $foo is getting overflowed or $termio?!
: line 31 is the ioctl line... i've tried tweaking here and there
: (hard-coding the device in open(), etc.) to no avail, am reading the
: passages that ioctl() is system dependent etc. the system that i'm
: running this on is an IBM rs6000 (aix3.1 - no updates), perl4.003. 
: any help would be appreciated.

You probably need to set $sizeof{'struct termio'}, and make sure the
length of the structure is correctly being encoded in the value
of &TCGETA.  $termio is what is getting overwritten.  Look at do_ctl()
in doio.c for more clues.

Larry