cjosta@taux01.UUCP (Jonathan Sweedler) (11/30/88)
I have a program that takes a long time to finish running. From time to time (sometimes never, sometimes more frequently) I would like to find out the current status. The way I accomplish this is to send one of the user defined signals (SIGUSR1 - no. 30) to the process. The process has a signal handler that catches this signal and writes out the current state (number of loops done, how long it has been running, when it will finish, etc.). This all works fine but only I (the owner of the process) can send the signal. If my boss, for example, wants to look at the status of the process, he can't. My questions are these: 1) Is there any way for someone who is not the owner of a process to send the process a signal? 2) Or, is there another way for a random user to cause a program to asynchronously print out a status report (or perform some action) once it has started running? I know I can have the program print out a status report every x minutes/hours/loops/whatever, but I don't want this. I want the report to be printed out only when specified to do so. I could also probably (haven't done this yet) write a shell script that would send the signal and is setuid to me but then if different people run the program (other than me), there must be different shell scripts that are setuid to each person who might run the program. For example, if either user A or user B might run the program, but it is user C that wants the progress report, then there must be a shell script setuid'ed to A and one setuid'ed to B. Is there a cleaner approach? -- Jonathan Sweedler === National Semiconductor Israel UUCP: ...!{amdahl,hplabs,decwrl}!nsc!taux01!cjosta Domain: cjosta@taux01.nsc.com
hudson@vsedev.VSE.COM (C Hudson Hendren III) (12/01/88)
In article <950@taux01.UUCP> cjosta@taux01.UUCP (Jonathan Sweedler) writes: >I have a program that takes a long time to finish running. From time >to time (sometimes never, sometimes more frequently) I would like to >find out the current status. The way I accomplish this is to send one >of the user defined signals (SIGUSR1 - no. 30) to the process. The >process has a signal handler that catches this signal and writes out >the current state (number of loops done, how long it has been running, >when it will finish, etc.). This all works fine but only I (the owner >of the process) can send the signal. If my boss, for example, wants to >look at the status of the process, he can't. > >I know I can have the program print out a status report every >x minutes/hours/loops/whatever, but I don't want this. I want the >report to be printed out only when specified to do so. > >Is there a cleaner approach? If you are running under System 5, you can use the interprocess communication facility. Have the program set up a message queue when it starts. In order to talk to the program, you write another program which opens the message queue and sends a message containing the tty number. You make this inquire program setuid to the uid of the running program since it will want to send a SIGUSR1 signal to the program. The running program catches the signal and looks to see what is waiting in the message queue. Upon finding the tty number of the requestor, it writes a message upon that console. As an alternative, you can have the running program send its status back through the message queue (thismakes it easier if you are in the habit of having unwritable ttys). You will certainly want to RTFM for more information on how to do this. Once you get in the habit of using the SVID IPC facility, you will find numerous uses such as this. -- ==> ..!uunet!vsedev!hudson [hudson@vsedev.vse.com] (C Hudson Hendren III) <== ==> These are my opinions and are not necessarily those of VSE Corporation. <== ==> MS-DOS was created to keep idiots away from UNIX computers <==
logan@vsedev.VSE.COM (James Logan III) (12/01/88)
In article <950@taux01.UUCP> cjosta@taux01.UUCP (Jonathan Sweedler) writes:
# I have a program that takes a long time to finish running. From time
# to time (sometimes never, sometimes more frequently) I would like to
# find out the current status. The way I accomplish this is to send one
# of the user defined signals (SIGUSR1 - no. 30) to the process. The
^^
SIGUSR1 is 16 under System V, so you either made a typo or you're
using a BSD system. MY RESPONSE WILL NOT HELP YOU IF YOU USE
BSD UNIX, but it may give people in this newsgroup some good ideas.
# 1) Is there any way for someone who is not the owner of a process to
# send the process a signal?
Not without being root or you. Writing a setuid program would work, but
is rather clumsy.
# 2) Or, is there another way for a random user to cause a program to
# asynchronously print out a status report (or perform some action) once
# it has started running?
Yes, use shared memory. Just use shmget(2) to get a hunk of
memory as large as an integer, use shmat(2) to get a pointer to
the integer, set the integer value to 0, and test the value
somewhere that's convenient in your code. When the value is 1,
print out a report, then set the integer value back to 0.
Then write a simple program that you and your boss can run that
uses the same key for shmget(2), use shmat(2) to get a pointer to
the same integer, and set the integer value to 1.
-Jim
--
Jim Logan logan@vsedev.vse.com
(703) 892-0002 uucp: ..!uunet!vsedev!logan
inet: logan%vsedev.vse.com@uunet.uu.net
guy@auspex.UUCP (Guy Harris) (12/01/88)
>SIGUSR1 is 16 under System V, so you either made a typo or you're >using a BSD system. MY RESPONSE WILL NOT HELP YOU IF YOU USE >BSD UNIX, Not so fast: bootme% egrep SIGUSR1 /usr/include/sys/signal.h #define SIGUSR1 30 /* user defined signal 1 */ bootme% egrep shmat /usr/lib/lint/llib-lc char * shmat(i, a, f) char *a; { return (a); } There are several systems that come to mind that 1) have SIGUSR1 as 30 (by virtue of having picked up the 4.3BSD signal set) and 2) have "shmat" (by virtue of having picked up System V IPC). SunOS releases 3.2 and later have both; I think Ultrix has "shmat" and probably has SIGUSR1 as 30 as well.
maart@cs.vu.nl (Maarten Litmaath) (12/02/88)
cjosta@taux01.UUCP (Jonathan Sweedler) writes:
\... This all works fine but only I (the owner
\of the process) can send the signal. If my boss, for example, wants to
\look at the status of the process, he can't.
\My questions are these:
\1) Is there any way for someone who is not the owner of a process to
\send the process a signal?
If your boss is root, he can :-)
\2) Or, is there another way for a random user to cause a program to
\asynchronously print out a status report (or perform some action) once
\it has started running?
You could let a child of the program test if a certain file in /tmp
exists, and, if so, signal the parent; anyone can make the file, and it's
still a process of yours (the child) who's doing the signaling. The
signal handler could look at the owner of the file, to determine who to
send the status report to. By using a child process the asynchronous
signal scheme is still possible; you'd rather not let the parent constantly
check /tmp for the file.
\...
\I could also probably (haven't done this yet) write a shell script that
^^^^^^^^^^^^
\would send the signal and is setuid to me but then if different people
^^^^^^
Aaaaaaaaaaaaarrrrrrrrrrrrgh!!!!!
Haven't you followed the `setuid shell scripts' discussion?
--
fcntl(fd, F_SETFL, FNDELAY): |Maarten Litmaath @ VU Amsterdam:
let's go weepin' in the corner! |maart@cs.vu.nl, mcvax!botter!maart
logan@vsedev.VSE.COM (James Logan III) (12/02/88)
In article <555@auspex.UUCP> guy@auspex.UUCP (Guy Harris) writes:
# >SIGUSR1 is 16 under System V, so you either made a typo or you're
# >using a BSD system. MY RESPONSE WILL NOT HELP YOU IF YOU USE
# >BSD UNIX,
#
# Not so fast:
#
# There are several systems that come to mind that 1) have SIGUSR1 as 30
# (by virtue of having picked up the 4.3BSD signal set) and 2) have
# "shmat" (by virtue of having picked up System V IPC). SunOS releases
# 3.2 and later have both; I think Ultrix has "shmat" and probably has
# SIGUSR1 as 30 as well.
That may very well be, but I was simply trying to state that
if he does not have System V, chances are he won't have *shared
memory*. If he is running Ultrix and has shared memory, then my
suggestion will work for him and he will be a happy person.
By the way, I thought of this after reading Hudson Hendron's
posting:
In addition to the integer stored in the shared memory segment I
posted about, a character array can be used to pass a filename
(such as "/tmp/dumpfile" or "/dev/tty11") so that the program
will open that file and dump the report. This way the report can
be sent somewhere besides the system printer via "lp" each time
a dump is requested.
If it is possible that more than one person at a time will be
requesting a report, you should use semaphores to lock the shared
memory resource. The System V semaphores make the implementation
of the Dekker P/V algorithm very easy. (I have a generalized
locking mechanism already written if you want it.)
Testing one integer in a loop in the program will be MUCH faster
than pushing 5 arguments on the stack and calling msgrcv() in
order to periodically poll a message queue like Hudson suggested.
-Jim
--
Jim Logan logan@vsedev.vse.com
(703) 892-0002 uucp: ..!uunet!vsedev!logan
inet: logan%vsedev.vse.com@uunet.uu.net
les@chinet.chi.il.us (Leslie Mikesell) (12/02/88)
In article <950@taux01.UUCP> cjosta@taux01.UUCP (Jonathan Sweedler) writes: >2) Or, is there another way for a random user to cause a program to >asynchronously print out a status report (or perform some action) once >it has started running? If you are running SysV you can have the program fork off a process that creates a FIFO with appropriate write permissions and blocks waiting for someone to write a command to it. When it reads a command it would send a signal to its parent. You might also set up a pipe from the child to the parent so that the details of the command could be passed (such as the device or another FIFO name to send the progress report to). If response doesn't have to be instant, the main process could periodically do a non-blocking read on the FIFO instead of using a child process. I suppose that something similar is possible with sockets under BSD. Les Mikesell
mkhaw@teknowledge-vaxc.ARPA (Mike Khaw) (12/02/88)
<555@auspex.UUCP>, by guy@auspex.UUCP (Guy Harris): > There are several systems that come to mind that 1) have SIGUSR1 as 30 > (by virtue of having picked up the 4.3BSD signal set) and 2) have > "shmat" (by virtue of having picked up System V IPC). SunOS releases > 3.2 and later have both; I think Ultrix has "shmat" and probably has > SIGUSR1 as 30 as well. On Ultrix 2.2: % fgrep SIGUSR1 /usr/include/signal.h * Moved SIGUSR1 and SIGUSR2 to 30 and 31 to conform with Berkeley * #define SIGUSR1 30 /* User signal 1 (from SysV) */ % man -k shmat shmop, shmat, shmdt (2) - shared memory operations % nm /lib/libc.a | fgrep shmat shmat.o: 00000000 T _shmat Mike Khaw -- internet: mkhaw@teknowledge.arpa uucp: {uunet|sun|ucbvax|decwrl|ames|hplabs}!mkhaw%teknowledge.arpa hardcopy: Teknowledge Inc, 1850 Embarcadero Rd, POB 10119, Palo Alto, CA 94303
hudson@vsedev.VSE.COM (C Hudson Hendren III) (12/02/88)
In article <1265@vsedev.VSE.COM> logan@vsedev.VSE.COM (James Logan III) writes: >If it is possible that more than one person at a time will be >requesting a report, you should use semaphores to lock the shared >memory resource. The System V semaphores make the implementation >of the Dekker P/V algorithm very easy. (I have a generalized >locking mechanism already written if you want it.) > >Testing one integer in a loop in the program will be MUCH faster >than pushing 5 arguments on the stack and calling msgrcv() in >order to periodically poll a message queue like Hudson suggested. My original suggestion did not require periodically polling a message queue. I had suggested sending a message through the message queue then sending SIGUSR1 to the running process. It would only need to call msgrcv() in the signal handler for SIGUSR1. Checking an integer field on every loop iteration is much more overhead than just setting a trap handler to call msgrcv(). Of course, if there is going to be a heavy demand on this feature with constant requests for status dumps, then the trap handler may become less efficient. I did not get the impression that the status dump would be requested with great frequency. That would be like shaking the jello to see if it had set. Another advantage of this method is that there is no need to use semaphore locking. -- ==> ..!uunet!vsedev!hudson [hudson@vsedev.vse.com] (C Hudson Hendren III) <== ==> These are my opinions and are not necessarily those of VSE Corporation. <== ==> MS-DOS was created to keep idiots away from UNIX computers <==
logan@vsedev.VSE.COM (James Logan III) (12/02/88)
In article <1267@vsedev.VSE.COM> hudson@vsedev.VSE.COM (C Hudson Hendren III) writes:
#
# It would only need to call msgrcv() in the signal handler for SIGUSR1.
#
Shared memory could also read the char array the same way on
receipt of SIGUSR1 (it could do it *faster* even!), but I don't
see any good way of sending a signal to the daemon.
How is another user going to find the PID of the daemon? Does
the user run 'ps -ef | grep "some_name"' and give it to this
other program as an argument? Do you hack on the "ps" source
to look through the process table for some_name?
Even if the daemon wrote its PID into some file, what do you
think happens when *two* daemons are running? If the daemon
writes the PID in append mode, how are do you know which PID is
the one you're interested in?
# Another advantage of this method is that there is no need to use semaphore
# locking.
That code is trivial and is not necessary on the daemon side.
-Jim
--
Jim Logan logan@vsedev.vse.com
(703) 892-0002 uucp: ..!uunet!vsedev!logan
inet: logan%vsedev.vse.com@uunet.uu.net
dhesi@bsu-cs.UUCP (Rahul Dhesi) (12/02/88)
I have lost track of whether the original poster, who wanted to be able to send a signal to a process not owned by him, wanted to do it under under BSD or System V. If it was BSD, a possibility is to open an Internet domain socket and set up a SIGIO handler. When somebody-- anybody--tries to write to the socket a SIGIO signal will be seen by the process. -- Rahul Dhesi UUCP: <backbones>!{iuvax,pur-ee}!bsu-cs!dhesi
guy@auspex.UUCP (Guy Harris) (12/02/88)
>That may very well be, but I was simply trying to state that >if he does not have System V, chances are he won't have *shared >memory*. Again, not so fast; if you have "shmat", which is what I was "grep"ping for and found in the SunOS "lint" libraries, you presumably have "*shared memory*" - the "shmat" I'm familiar with is, from the SunOS manual page: shmat() maps the shared memory segment associated with the shared memory identifier specified by shmid into the data segment of the calling process. Upon successful completion, the address of the mapped segment is returned. These days, I would think twice before saying "if he does not have System V, chances are he won't have *shared memory*", if "System V" is to be interpreted as "something that began as the stuff from an AT&T source tape, as you seemed to have interpreted it. Looking at the value of SIGUSR1, seeing that it's not 16, and concluding that they're unlikely to have shared memory is a mistake; if they *do* have a system that started out with the stuff from a Berkeley source tape, but that had S5 IPC added, and took the claim that they were unlikely to have S5 shared memory at face value and didn't look for it on their system, they'd have lost. The world isn't neatly divided into "BSD" and "System V"; there are plenty of systems with features from both, many of which may have started from BSD but picked up stuff like S5 IPC. (Of course, in SunOS - and, I think, in at least some other systems, including S5 from AT&T - it's an optional feature, so you have to configure the S5 IPC stuff into your system.)