lkml.org 
[lkml]   [2000]   [Sep]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectSignal 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;
}

\
 
 \ /
  Last update: 2005-03-22 12:41    [W:0.779 / U:0.628 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site