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;
}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/
This archive was generated by hypermail 2b29 : Fri Sep 15 2000 - 21:00:16 EST