Subject: pkg/33887: pkg open2300 need O_NONBLOCK on open
To: None <pkg-manager@netbsd.org, gnats-admin@netbsd.org,>
From: None <luc@pbox.org>
List: pkgsrc-bugs
Date: 07/01/2006 15:10:01
>Number:         33887
>Category:       pkg
>Synopsis:       pkg open2300 need O_NONBLOCK on open
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    pkg-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Jul 01 15:10:00 +0000 2006
>Originator:     Luc Beurton
>Release:        NetBSD 3.99.7
>Organization:
>Environment:
System: NetBSD iz-bushka 3.0.0_STABLE NetBSD 3.0.0_STABLE (GENERIC) #0: Tue Feb
21 06:56:59 UTC 2006 riz@faith.netbsd.org:/home/builds/ab/netbsd-3-0/sparc64/200
602200000Z-obj/home/builds/ab/netbsd-3-0/src/sys/arch/sparc64/compile/GENERIC sp
arc64
Architecture: sparc64
Machine: sparc64
>Description:
open2300 doesn't work on sparc/sparc64, but it works fine on i386
On debug we could see that it's waiting when opening device.

In tip.c I read this:
        /*
         * Direct connections with no carrier require using O_NONBLOCK on
         * open, but we don't want to keep O_NONBLOCK after open because it
         * will cause busy waits.
         */

So I try this code, and now it's work :)

>How-To-Repeat:
Just try to use open2300 on sparc/sparc64

>Fix:
A simple drag&drop from tip.c, I use it with open2300-1.10 too

--- linux2300.c.orig    2004-11-13 13:02:12.000000000 +0100
+++ linux2300.c 2006-07-01 16:40:21.000000000 +0200
@@ -14,6 +14,7 @@
 #define DEBUG 0
 
 #include <errno.h>
+#include <fcntl.h>
 #include "rw2300.h"
 
 /********************************************************************
@@ -29,13 +30,20 @@
        WEATHERSTATION ws2300;
        struct termios adtio;
        int portstatus;
+       int fcarg;
 
        //Setup serial port
 
-       if ((ws2300 = open(device, O_RDWR | O_NOCTTY)) < 0)
+       if ((ws2300 = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK )) < 0)
        {
                printf("\nUnable to open serial device %s\n", device);
-               exit(0);
+               exit(EXIT_FAILURE);
+       }
+
+       if ((fcarg = fcntl(ws2300, F_GETFL, 0)) < 0 ||
+             fcntl(ws2300, F_SETFL, fcarg & ~O_NONBLOCK) < 0) {
+               printf("\nCan't clear O_NONBLOCK: %s\n", device);
+               exit(EXIT_FAILURE);
        }
 
        tcgetattr(ws2300, &adtio);