Recent

Author Topic: Bug in synaser  (Read 5759 times)

hakelm

  • Full Member
  • ***
  • Posts: 112
Bug in synaser
« on: April 04, 2012, 10:35:59 am »
In synaser.pas  (007.002.000) line 1905 "SerialCheck(fpioctl(integer(FHandle), TCFLSH, TCIOFLUSH)); " causes a compilation error under LInux.
I haven't been able to figure out what to replace TCIOFLUSH with but I added oldlinux to my units and replaced line 1905 with
  SerialCheck(tcflush(integer(FHandle), TCIOFLUSH));
and this seems to work.
Is there anyone who knows to what structure and data the 3rd argument in fpioctl(integer(FHandle), TCFLSH, @????)); should point to?
H

ludob

  • Hero Member
  • *****
  • Posts: 1173
Re: Bug in synaser
« Reply #1 on: April 04, 2012, 11:34:55 am »
Just cast TCIOFLUSH to a pointer. The problem has been solved in the svn version of synaser:
Code: [Select]
{$IFNDEF MSWINDOWS}
procedure TBlockSerial.Purge;
begin
  {$IFNDEF FPC}
  SerialCheck(ioctl(FHandle, TCFLSH, TCIOFLUSH));
  {$ELSE}
    {$IFDEF DARWIN}
    SerialCheck(fpioctl(FHandle, TCIOflush, Pointer(PtrInt(TCIOFLUSH))));
    {$ELSE}
    SerialCheck(fpioctl(FHandle, TCFLSH, Pointer(PtrInt(TCIOFLUSH))));
    {$ENDIF}
  {$ENDIF}
  FBuffer := '';
  ExceptCheck;
end;
{$ELSE}       

hakelm

  • Full Member
  • ***
  • Posts: 112
Re: Bug in synaser
« Reply #2 on: April 04, 2012, 03:00:10 pm »
Thanks a lot,
this works even if I don't grasp the syntax.
H

hakelm

  • Full Member
  • ***
  • Posts: 112
aha
« Reply #3 on: April 04, 2012, 10:16:43 pm »
I get it, it is not what is pointed at, but the the pointer itself that is the datum.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7574
Re: Bug in synaser
« Reply #4 on: April 05, 2012, 09:26:04 am »
Just cast TCIOFLUSH to a pointer. The problem has been solved in the svn version of synaser:
Code: [Select]
{$IFNDEF MSWINDOWS}
procedure TBlockSerial.Purge;
begin
  {$IFNDEF FPC}
  SerialCheck(ioctl(FHandle, TCFLSH, TCIOFLUSH));
  {$ELSE}
    {$IFDEF DARWIN}
    SerialCheck(fpioctl(FHandle, TCIOflush, Pointer(PtrInt(TCIOFLUSH))));
    {$ELSE}
    SerialCheck(fpioctl(FHandle, TCFLSH, Pointer(PtrInt(TCIOFLUSH))));
    {$ENDIF}
  {$ENDIF}
  FBuffer := '';
  ExceptCheck;
end;
{$ELSE}       

That code is wrong. *BSD does not support TCFLSH (which is Linux only, or maybe Solaris too)

Smartest would be to simply use termio.tcflush

ludob

  • Hero Member
  • *****
  • Posts: 1173
Re: Bug in synaser
« Reply #5 on: April 05, 2012, 03:01:46 pm »
That code is wrong. *BSD does not support TCFLSH (which is Linux only, or maybe Solaris too)
Smartest would be to simply use termio.tcflush
Solaris does support TCFLSH. termio.tcflush for solaris is implemented in fpc as
Code: [Select]
Function TCFlush(fd,qsel:cint):cint; {$ifdef VER2_0}inline;{$endif}
begin
  TCFlush:=fpIOCtl(fd,TIOCFLUSH,pointer(qsel));
end;
From the doc I found that TIOCFLUSH expects a pointer to an int and not the int itself (A bug report found here: http://wesunsolve.net/bugid/id/4143249).  TCFLSH expects the int.
The other problem is that the tcflush parameters for solaris are defined for TCFlush:
Code: [Select]
     
     TCIFLUSH = 0;
     TCOFLUSH = 1;
     TCIOFLUSH = 2;
while those for bsd match the TIOCFLUSH values:
Code: [Select]
       
        TCIFLUSH        =1;
        TCOFLUSH        =2;
        TCIOFLUSH       =3;

When I look at the implementation of NetBSD (http://www.koders.com/c/fidB1DBDDE277209C66898CA4CFE116A72C4CD38D46.aspx?s=cdefs#L36) the same pointer problem exists in the FPC implementation:
Code: [Select]
tcflush(fd, which)
int fd, which;
{
int com;

switch (which) {
case TCIFLUSH:
com = FREAD;
break;
case TCOFLUSH:
com = FWRITE;
break;
case TCIOFLUSH:
com = FREAD | FWRITE;
break;
default:
errno = EINVAL;
return (-1);
}
return (ioctl(fd, TIOCFLUSH, &com));
}

Code: [Select]
Function TCFlush(fd,qsel:cint):cint;
begin
  TCFlush:=fpIOCtl(fd,TIOCFLUSH,pointer(qsel));
end;