http://www.perlmonks.org?node_id=589305

neilwatson has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to debug some scary legacy code. This line:
system("$ENSCRIPT $fullfilename -o $TEMPDIR/$dirname.$filename.ps")== 0 or die "Cannot $ENSCRIPT $fullfilename -o $TEMPDIR/$dirname.$filename.ps: $ +!";
Returns this error is returned:
Cannot /usr/bin/enscript -B --margins=10:10:10:30 -r -fCourier9 ./dpi. +2006-12-12/iip8061211 -o /tmp/printer.15270/./dpi.2006-12-12.iip80612 +11.ps: Inappropriate ioctl for device at ./print-gui.pl line 215.
What does it mean?

Neil Watson
watson-wilson.ca

Replies are listed 'Best First'.
Re: Inappropriate ioctl for device erro on system call
by marto (Cardinal) on Dec 12, 2006 at 16:14 UTC
      Yes, I looked at those. Alas the problem persists even if I remove $! from the die string. That thread, and others, mention TTY problems. I don't understand the relationship fully. This script runs with a regular login shell. It does use a module called UI::Dialog::Backend::CDialog which I am not familiar with.

      Neil Watson
      watson-wilson.ca

Re: Inappropriate ioctl for device error on system call
by traveler (Parson) on Dec 12, 2006 at 16:45 UTC
    It is possible that your $fullfilename does not exist. You are trying to open ./dpi.2006-12-12+/iip8061211. If that does not exist, enscript will try to processess stdin which may not be a tty on your process. Also ensure that your output file can be created.
      The $fullfilename exists. There are some commands that run earlier that work fine:
      # Unzip file here system("gunzip $fullfilename") == 0 or die "Cannot gunzip $fullfilename $!"; open FH, "file $fullfilename | " or die "Cannot open fullfilename: $fullfilename $!"; my $filetype = <FH>; close FH; if ($filetype =~ /ASCII/ || $filetype =~ /ISO-8859/) { latex_template("$dirname/print.files.txt", $filename, $data[2]); system("latex banner.$$.tex") == 0 or die "Cannot latex banner.$$.tex $!"; system("dvips banner.$$.dvi -o banner.$$.ps") == 0 or die "Cannot dvips banner.$$.dvi $!"; if ( -e $fullfilename ){ print "File to be enscripted ($fullfilename) exists"; } system("$ENSCRIPT $fullfilename -o $TEMPDIR/$dirname.$filename.ps") + == 0 or die "Cannot $ENSCRIPT $fullfilename -o $TEMPDIR/$dirname.$fil +ename.ps: $!"; system("lp -d $PRINTER_NAME banner.$$.ps 2>$TEMPDIR/error.txt") == +0 or die "Cannot lp -d banner.$$.ps $!"; system("lp -d $PRINTER_NAME -n $num_copies -q $job_priority $page_l +ist $TEMPDIR/$dirname.$filename.ps 2>$TEMPDIR/error.txt") == 0 or die "Cannot lp -d $TEMPDIR/$dirname.$filename.ps $!";
      I also tried replace the output file ($TEMPDIR/$dirname.$filename.ps) with a known good location. The enscript command actually does create the postscript file. This makes the existence of the error that much more confusing.

      Neil Watson
      watson-wilson.ca

        Some more troubleshooting hints:

        Does it run from the command line? If so, perl is probably not giving expected access to some filehandle.

        Try tracing it with strace. You can do it from the command line if the command version fails, or from perl by adding it to the system call. It can generate a lot of output but may show what file descriptor is causing the problem.

Re: Inappropriate ioctl for device error on system call
by sgifford (Prior) on Dec 12, 2006 at 20:26 UTC
    It's quite possible the Inappropriate ioctl for device is a red herring. $! will only be set if a call to the OS fails. Since a program run by system returning a nonzero exit status isn't considered a failed OS call, $! may contain gibberish. You may find more useful information by looking at $?, and/or any error output from the program you're running.
Re: Inappropriate ioctl for device error on system call
by neilwatson (Priest) on Dec 12, 2006 at 20:58 UTC
    Problem solved. Enscript's return status is more than simply zero or not zero:
    RETURN VALUE Enscript returns value 1 to the shell if any errors were encountered. On successfull termination, the return code is constucted from the following flags: 0 no errors or warnings 2 some lines were truncated or wrapped 4 some characters were missing from the used fonts 8 some characters were unprintable
    Would something like
    system("/bin/somecommand") < 9 or die "Somecommand failed $!, $?";
    Work?

    Neil Watson
    watson-wilson.ca

      The basic idea is right, but $! won't be set by the command exiting with a nonzero exit status (t will be left at whatever the last error happened to be), and $? is the actual exit value times 256, for a normal exit. See system and $! variable for more details.

      Here's an example to try out to see what I mean:

      perl -e 'unlink("nosuchfile"); system("sh","-c","exit 1") == 0 or die "Err: $!,$?"' Err: No such file or directory,256 at -e line 1.