NetBSD Problem Report #12608

Received: (qmail 8422 invoked from network); 11 Apr 2001 04:01:10 -0000
Message-Id: <20010411040109.038171110F@www.netbsd.org>
Date: Tue, 10 Apr 2001 21:01:09 -0700 (PDT)
From: cagney@tpgi.com.au
Sender: nobody@netbsd.org
Reply-To: cagney@tpgi.com.au
To: gnats-bugs@gnats.netbsd.org
Subject: Need to F_SETOWN a socket before O_ASYNC works
X-Send-Pr-Version: www-1.0

>Number:         12608
>Category:       kern
>Synopsis:       Need to F_SETOWN a socket before O_ASYNC works
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Apr 11 04:02:00 +0000 2001
>Closed-Date:    
>Last-Modified:  Wed Apr 11 04:03:00 +0000 2001
>Originator:     Andrew Cagney
>Release:        1.5.1_ALPHA
>Organization:
>Environment:
NetBSD localhost 1.5.1_ALPHA NetBSD 1.5.1_ALPHA (LULUnfs) #0: Sat Mar 31 21:42:51 EST 2001     boor@localhost:/usr/src/sys/arch/i386/compile/LULUnfs i386

>Description:
It would appear that, by default a socket has fcntl(F_GETOWN)
set to zero and consequently fcntl(F_SETFL, O_ASYNC) has no
effect unless the owner is set to getpid().

The FD created by accepting a connection on that socket does appear
to work.

Per how-to-repeat, adding code to get the owner and set it if zero
works around the problem.

I believe the code works without the set-owner on Solaris 2.5.1 and
FreeBSD 3.x.

>How-To-Repeat:
I've extracted the relevant code.Yes I should turn it into a real
program...


static void
nonblocking_fd (int fd)
{
#if defined(F_SETFL) && (defined (O_ASYNC) || defined (O_NONBLOCK))
  int flags = fcntl (fd, F_GETFL, 0);
  if (gdbsocket_log)
    {
      gdblog_string (gdbsocket_log, "[");
      gdblog_long (gdbsocket_log, fd);
      gdblog_string (gdbsocket_log, ":");
    }
#if defined (O_NONBLOCK)
  flags |= O_NONBLOCK;
  if (gdbsocket_log)
    gdblog_string (gdbsocket_log, " O_NONBLOCK");
#endif
  if (gdbsocket_log)
    gdblog_string (gdbsocket_log, "]\n");
  fcntl (fd, F_SETFL, flags);
#endif
}

static void
async_fd (int fd)
{
  int flags;
  gdblog_string (gdbsocket_log, "[");
  gdblog_long (gdbsocket_log, fd);
#if defined(F_SETFL) && (defined (O_ASYNC) || defined (O_NONBLOCK))
  flags = fcntl (fd, F_GETFL, 0);
#if defined (O_ASYNC)
  flags |= O_ASYNC;
  gdblog_string (gdbsocket_log, " O_ASYNC");
#elif defined (FASYNC)
  flags |= FASYNC;
  gdblog_string (gdbsocket_log, " FASYNC");
#endif
  fcntl (fd, F_SETFL, flags);
#endif
#if defined (F_SETOWN)
  /* some systems don't set the process to deliver the SIGIO to. */
  flags = fcntl (fd, F_GETOWN, 0);
  if (flags == 0)
    {
      flags = getpid ();
      fcntl (fd, F_SETOWN, flags);
      gdblog_string (gdbsocket_log, " [OWN ");
      gdblog_long (gdbsocket_log, flags);
      gdblog_string (gdbsocket_log, "]");
    }
#endif
  gdblog_string (gdbsocket_log, "]\n");
}

void
gdbsocket_sigio_disable (void)
{
  if (gdbsocket_log)
    gdblog_string (gdbsocket_log, "[gdbsocket_sigio_disable");

  signal (SIGIO, SIG_IGN);

  if (gdbsocket_log)
    gdblog_string (gdbsocket_log, "]\n");
}


  /* Create our socket */
  server_fd = socket (PF_INET, SOCK_STREAM, 0);
  /* allow reuse */
  on = 1;
  setsockopt (server_fd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof (on));
  on = 1;
  setsockopt (server_fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&on, sizeof (on));

  /* bind it to the requested UDP port */
  sockaddr.sin_family = PF_INET;
  sockaddr.sin_addr.s_addr = htonl (INADDR_ANY);
  sockaddr.sin_port = htons (port_nr);
  if (bind (server_fd, (struct sockaddr *)&sockaddr, sizeof (sockaddr)) < 0)
    {
      int te = errno;
      close (server_fd);
      gdblog_string (gdbsocket_log, " BIND ERROR]\n");
      errno = te;
      return -1;
    }

  listen (server_fd, 1);

  /* Don't let a closed pipe kill us */
  signal (SIGPIPE, SIG_IGN);

  gdbsocket_sigio_disable ();
  nonblocking_fd (server_fd);
  async_fd (server_fd);


>Fix:

>Release-Note:
>Audit-Trail:

From: cagney@tpgi.com.au
To: gnats-bugs@gnats.netbsd.org
Cc:  
Subject: kern/12608: Need to F_SETOWN a socket before O_ASYNC works
Date: Tue, 10 Apr 2001 21:01:09 -0700 (PDT)

 >Number:         12608
 >Category:       kern
 >Synopsis:       Need to F_SETOWN a socket before O_ASYNC works
 >Confidential:   no
 >Severity:       serious
 >Priority:       medium
 >Responsible:    kern-bug-people
 >State:          open
 >Class:          sw-bug
 >Submitter-Id:   net
 >Arrival-Date:   Tue Apr 10 21:02:00 PDT 2001
 >Closed-Date:
 >Last-Modified:
 >Originator:     Andrew Cagney
 >Release:        1.5.1_ALPHA
 >Organization:
 >Environment:
 NetBSD localhost 1.5.1_ALPHA NetBSD 1.5.1_ALPHA (LULUnfs) #0: Sat Mar 31 21:42:51 EST 2001     boor@localhost:/usr/src/sys/arch/i386/compile/LULUnfs i386

 >Description:
 It would appear that, by default a socket has fcntl(F_GETOWN)
 set to zero and consequently fcntl(F_SETFL, O_ASYNC) has no
 effect unless the owner is set to getpid().

 The FD created by accepting a connection on that socket does appear
 to work.

 Per how-to-repeat, adding code to get the owner and set it if zero
 works around the problem.

 I believe the code works without the set-owner on Solaris 2.5.1 and
 FreeBSD 3.x.

 >How-To-Repeat:
 I've extracted the relevant code.Yes I should turn it into a real
 program...


 static void
 nonblocking_fd (int fd)
 {
 #if defined(F_SETFL) && (defined (O_ASYNC) || defined (O_NONBLOCK))
   int flags = fcntl (fd, F_GETFL, 0);
   if (gdbsocket_log)
     {
       gdblog_string (gdbsocket_log, "[");
       gdblog_long (gdbsocket_log, fd);
       gdblog_string (gdbsocket_log, ":");
     }
 #if defined (O_NONBLOCK)
   flags |= O_NONBLOCK;
   if (gdbsocket_log)
     gdblog_string (gdbsocket_log, " O_NONBLOCK");
 #endif
   if (gdbsocket_log)
     gdblog_string (gdbsocket_log, "]\n");
   fcntl (fd, F_SETFL, flags);
 #endif
 }

 static void
 async_fd (int fd)
 {
   int flags;
   gdblog_string (gdbsocket_log, "[");
   gdblog_long (gdbsocket_log, fd);
 #if defined(F_SETFL) && (defined (O_ASYNC) || defined (O_NONBLOCK))
   flags = fcntl (fd, F_GETFL, 0);
 #if defined (O_ASYNC)
   flags |= O_ASYNC;
   gdblog_string (gdbsocket_log, " O_ASYNC");
 #elif defined (FASYNC)
   flags |= FASYNC;
   gdblog_string (gdbsocket_log, " FASYNC");
 #endif
   fcntl (fd, F_SETFL, flags);
 #endif
 #if defined (F_SETOWN)
   /* some systems don't set the process to deliver the SIGIO to. */
   flags = fcntl (fd, F_GETOWN, 0);
   if (flags == 0)
     {
       flags = getpid ();
       fcntl (fd, F_SETOWN, flags);
       gdblog_string (gdbsocket_log, " [OWN ");
       gdblog_long (gdbsocket_log, flags);
       gdblog_string (gdbsocket_log, "]");
     }
 #endif
   gdblog_string (gdbsocket_log, "]\n");
 }

 void
 gdbsocket_sigio_disable (void)
 {
   if (gdbsocket_log)
     gdblog_string (gdbsocket_log, "[gdbsocket_sigio_disable");

   signal (SIGIO, SIG_IGN);

   if (gdbsocket_log)
     gdblog_string (gdbsocket_log, "]\n");
 }


   /* Create our socket */
   server_fd = socket (PF_INET, SOCK_STREAM, 0);
   /* allow reuse */
   on = 1;
   setsockopt (server_fd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof (on));
   on = 1;
   setsockopt (server_fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&on, sizeof (on));

   /* bind it to the requested UDP port */
   sockaddr.sin_family = PF_INET;
   sockaddr.sin_addr.s_addr = htonl (INADDR_ANY);
   sockaddr.sin_port = htons (port_nr);
   if (bind (server_fd, (struct sockaddr *)&sockaddr, sizeof (sockaddr)) < 0)
     {
       int te = errno;
       close (server_fd);
       gdblog_string (gdbsocket_log, " BIND ERROR]\n");
       errno = te;
       return -1;
     }

   listen (server_fd, 1);

   /* Don't let a closed pipe kill us */
   signal (SIGPIPE, SIG_IGN);

   gdbsocket_sigio_disable ();
   nonblocking_fd (server_fd);
   async_fd (server_fd);


 >Fix:

 >Release-Note:
 >Audit-Trail:
 >Unformatted:

>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.