Messages in this thread |  | | Date | Tue, 12 Sep 2000 02:20:02 +0200 | From | jury gerold <> | Subject | Signal handling different for root and others |
| |
I ran into a problem with 2.2.x kernels, posix signals and sockets.
I have a program that creates a serversocket, puts it into listen state, attaches the socket to a realtime signal and simply waits for the signal.
When i create a connection (telnet a.b.c.d port) the signal is delivered depending on the user that does the telnet. If root creates the socket, then only root or another machine is able to trigger the signal by connecting to the socket. Normal users are only able to create a SIGIO signal when connecting.
If a normal user runs the program, then any user, as well as root is able to trigger the realtime signal. No SIGIO is delivered.
The program is attached.
best regards
Gerold/* compile with gcc -o rtsigsock rtsigsock.c -lpthread */ /* start it and do a telnet 127.0.0.1 20000 */
#define _GNU_SOURCE
#include <stdio.h> #include <netinet/tcp.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #include <netdb.h> #include <unistd.h> #include <fcntl.h> #include <signal.h> #include <pthread.h>
#define SERVERPORT 20000
static int RT_DISPATCHSIG;
static void setAsync( int fd, int sig ) { int ret;
// printf( "setasync %d %d\n", fd, sig ); ret = fcntl( fd, F_SETOWN, getpid() ); if( ret == -1 ) perror( "SETOWN" ); ret = fcntl( fd, F_SETSIG, sig ); if( ret == -1 ) perror( "SETSIG" ); ret = fcntl( fd, F_SETFL, fcntl( fd, F_GETFL, 0) | FASYNC); if( ret == -1 ) perror("F_SETFL" ); }
int setPortReuse( int iSockFd ) { int ret; int iReuse = 1;
ret = setsockopt( iSockFd, SOL_SOCKET, SO_REUSEADDR, (char *)&iReuse, sizeof( iReuse ) ); if( ret == -1 ) perror( "SO_REUSEADDR" ); return ret; }
int main( int argc, char *argv[] ) { int iFd, ret, sig; struct sockaddr_in sa; sigset_t waitset; siginfo_t info;
RT_DISPATCHSIG = (SIGRTMIN);
sigemptyset( &waitset ); sigaddset( &waitset, RT_DISPATCHSIG ); sigaddset( &waitset, SIGIO ); #if 0 sigprocmask( SIG_SETMASK, &waitset, NULL ); #else pthread_sigmask( SIG_BLOCK, &waitset, NULL ); #endif
iFd = socket (AF_INET, SOCK_STREAM, 0); if( iFd == -1 ) { perror( "socket" ); return 0; }
sa.sin_family = AF_INET; sa.sin_port = htons( SERVERPORT ); sa.sin_addr.s_addr = htonl( INADDR_ANY ); setPortReuse( iFd ); ret = bind( iFd, (struct sockaddr*)&sa, sizeof(sa) ); // connect to host if( ret == -1 ) { perror( "bind" ); return 0; } ret = listen( iFd, 8 ); if( ret == -1 ) { perror( "listen" ); return 0; } setAsync( iFd, RT_DISPATCHSIG ); for(;;) { sig = sigwaitinfo( &waitset, &info ); if( sig == RT_DISPATCHSIG ) break; } printf( "got the signal %d\n", sig ); return 0; }
|  |