tags:

views:

176

answers:

7

Is it possible to i/o to a running process? I have multiple game servers running like this:

cd /path/to/game/server/binary
./binary arg1 arg2 ... argn &

Is it possible to write a message to a server if i know the process id?

Something like this would be handy:

echo "quit" > process1234

Where process1234 is the process (with sid 1234).

The game server is not a binary written by me, but it is a Call of Duty binary. So i can't change anything to the code.

+1  A: 

Only if the process is listening for some message somewhere. For instance, your game server can be waiting for input on a file, over a network connection, or from standard input.

If your process is not actively listening for something, the only things you can really do is halt or kill it.

Now if your process is waiting on standard input, and you ran it like so:

$ myprocess &

Then (in linux) you should be able to try the following:

$ jobs
[1]+  Running                 myprocess &
$ fg 1

And at this point you are typing standard input into your process.

Fragsworth
The server has a input console for commands. The command quit quits the server. I can kill <sid> but then i get messed up log files. So i want to quit the server as it should be. So the server listen to stdin.
VDVLeon
the job doesn't exists (anymore). May be because server is started by a cronjob script and then no job is stored?
VDVLeon
+1  A: 

You can only do that if the process is explicitly designed for that.

But since you example is requesting the process quit, I'd recommend trying signals. First try to send the TERM (i.e. terminate) signal which is the default:

kill _pid_

If that doesn't work, you can try other signals such as QUIT:

kill -QUIT _pid_

If all else fails, you can use the KILL signal. This is guaranteed (*) to stop the process but the process will have no change to clean up:

kill -KILL _pid_

* - in the past, kill -KILL would not work if the process was hung when on a flaky network file server. Don't know if they ever fixed this.

R Samuel Klatchko
There are many causes for "D" state (http://en.wikipedia.org/wiki/Uninterruptible_sleep), waiting for NFS I/O being one of the more frequent cases. Linux has been progressing towards eliminating some of these in favor of interruptible sleeps, but many system calls are impossible to restart if interrupted.
ephemient
+1  A: 

I'm pretty sure this would work, since the server has a console on stdin:

echo "quit" > /proc/<server pid>/fd/0

You mention in a comment below that your process does not appear to read from the console on fd 0. But it must on some fd. ls -l /proc/<server pid/>/fd/ and look for one that's pointing at /dev/pts/ if the process is running in a gnome-terminal or xterm or something.

Omnifarious
if i run: ln -al /proc/<server pid>/fd/0 i get:lr-x------ 1 root root 64 jan 1 23:00 0 -> /dev/nullSo there is no input stream.I remembered me something. The server has a console input line, always at the bottom of your linux console. So maybe it used ncurses (or something) to read input. Maybe then there is an other fd for that console input line?
VDVLeon
A: 

If you want to do a few simple operations on your server, use signals as mentioned elsewhere. Set up signal handlers in the server and have each signal perform a different action e.g.:

  • SIGINT: Reread config file
  • SIGHUP: quit

...

Richard Pennington
A: 

Highly hackish, don't do this if you have a saner alternative, but you can redirect a process's file descriptors on the fly if you have ptrace permissions.

$ echo quit > /tmp/quitfile
$ gdb binary 1234
(gdb) call dup2(open("/tmp/quitfile", 0), 0)
(gdb) continue

open("/tmp/quitfile", O_RDONLY) returns a file descriptor to /tmp/quitfile. dup2(..., STDIN_FILENO) replaces the existing standard input by the new file descriptor.

We inject this code into the application using gdb (but with numeric constants, as #define constants may not be available), and taadaah.

ephemient
+1  A: 

Yes, you can start up the process with a pipe as its stdin and then write to the pipe. You can used a named or anonymous pipe.

Normally a parent process would be needed to do this, which would create an anonmyous pipe and supply that to the child process as its stdin - popen() does this, many libraries also implement it (see Perl's IPC::Open2 for example)

Another way would be to run it under a pseudo tty, which is what "screen" does. Screen itself may also have a mechanism for doing this.

MarkR
I think i go use screen. First i have to learn how to use this :P
VDVLeon
There are alternatives to GNU screen, for example http://www.cliki.net/detachtty and http://caca.zoy.org/wiki/neercs - in fact, the former may be simpler to interact with, programatically.
ephemient
A: 

Simply run it under screen and don't background it. Then you can either connect to it with screen interactively and tell it to quit, or (with a bit of expect hackery) write a script that will connect to screen, send the quit message, and disconnect.

Andrew McGregor