Inappropriate Ioctl for Device When Trying to Ssh

Errno::ENOTTY Inappropriate ioctl for device when connecting to a remote server through Net::SSH on SuSe (with Ruby on Rails 5.2.4)

I finally found out that the message refers to the operating mode of SSH: it requires a sort of terminal emulation - so called pty - wrapped into a SSH chanel.

So I implemented it this way:

Net::SSH.start(remote_host, remote_user, password: remote_password) do |session|
session.open_channel do |channel|
channel.request_pty do |ch, success|
raise "Error requesting pty" unless success
puts "------------ pty successfully obtained"
end

channel.exec "#{@task.statement}" do |ch, success|
abort "could not execute command" unless success

channel.on_data do |ch, data|
puts "------------ got stdout: #{data}"
@task.update_attribute(:return_value, data)
end

channel.on_extended_data do |ch, type, data|
puts "------------ got stderr: #{data}"
end

channel.on_close do |ch|
puts "------------ channel is closing!"
end

end
end

### Wait until the session closes
session.loop
end

This solved my issue.

Note:
The answer proposed above was only a part of the solution. The same error occured again with this source code when deploying to the production server.

The issue appears to be the password to the SSH target: I retyped it by hand instead of doing the usual copy/paste from MS Excel, and the SSH connection is now successful!

As the error raised is not a simple "connection refused", I suspect that the password string had a specific character encoding, or an unexpected ending character.

As the first proposed solution provides a working example, I leave it there.

Inappropriate ioctl for device

An "ioctl" is a POSIX operation to send a control command to a device ("I/O control"). The "Inappropriate ioctl" error means that the program sent an ioctl to a device that wasn't correct in some way. The question is what ioctls this spotify program may be using that are dependent on how it's run.

When you run the spotify program from the command line, it has a TTY. When your PHP code launches the program, it doesn't have a TTY. It's probably sending an ioctl to its standard output for some reason, expecting standard output to be a tty. My guess is that it's using an ioctl to get the terminal width so that it can display that progress bar graphic.

There are two ways to fix this. You could check the documentation for this spotify program to see if it has a noninteractive mode or batch mode or quiet mode that disables printing the progress bar. That might avoid performing the ioctl that's failing.

The other fix is to have PHP request a pty (pseudo-TTY) for the ssh session. I'm not a PHP coder, but this page appears to describe the Net_SSH2 API, and it lists a function to enable requesting a PTY for calls to exec().

inappropriate ioctl for device

Most likely it means that the open didn't fail.

When Perl opens a file, it checks whether or not the file is a TTY (so that it can answer the -T $fh filetest operator) by issuing the TCGETS ioctl against it. If the file is a regular file and not a tty, the ioctl fails and sets errno to ENOTTY (string value: "Inappropriate ioctl for device"). As ysth says, the most common reason for seeing an unexpected value in $! is checking it when it's not valid -- that is, anywhere other than immediately after a syscall failed, so testing the result codes of your operations is critically important.

If open actually did return false for you, and you found ENOTTY in $! then I would consider this a small bug (giving a useless value of $!) but I would also be very curious as to how it happened. Code and/or truss output would be nifty.



Related Topics



Leave a reply



Submit