I suspect that the following existing code is supposed to strip a path from the serial port device filename:
2321 repeat
2322 if (sr.Attr and $FFFFFFFF) = Sr.Attr then
2323 begin
2324 data := sr.Name;
2325 index := length(data);
2326 while (index > 1) and (data[index] <> '/') do
2327 index := index - 1;
2328 TmpPorts := TmpPorts + ' ' + copy(data, 1, index + 1);
2329 end;
In FPC the TSearchRec doesn't contain a path (http://www.freepascal.org/docs-html/rtl/sysutils/tsearchrec.html). The resulting code results in a list of serial ports as follows: "tt tt tt" tested on Debian.
It seems as if the name of the serial port should simply be the value returned in sr.Name.
Also it would be more convenient (for me) if the list of serial ports are passed via a TStringList parameter. This would make it very easy to display the available serial ports in e.g. a dropdown list.
Below please find a Linux version of GetSerialPortNames that works on Debian (3.2 kernel). There are several different potential names for serial ports, so I borrowed an idea from the PascalSCADA project which uses a list of predefined serial port prefixes. I haven't tested the code on any other system so there may still be unforseen problems on other platforms.
{$IFNDEF MSWINDOWS}
// Idea copied from PascalSCADA project's serialport.pas file:
// http://pascalscada.svn.sourceforge.net/viewvc/pascalscada/trunk/serialport.pas?revision=702&view=markup
// More prefixes exist see e.g. :
// http://comments.gmane.org/gmane.comp.ide.lazarus.general/46750
{$IFDEF UNIX}
var
{$IFDEF LINUX}
PortPrefix: array[0..2] of string = ('ttyS', 'ttyUSB', 'ttyACM'); // Possibly several other names too
{$ENDIF}
{$IFDEF FREEBSD}
PortPrefix:array[0..2] of string = ('cuad', 'cuau', 'ttyu'); // http://www.freebsd.org/doc/handbook/serial.html
{$ENDIF}
{$IFDEF NETBSD}
PortPrefix:array[0..0] of string = ('cuad'); // Don't have better info at the moment
{$ENDIF}
{$IFDEF OPENBSD}
PortPrefix:array[0..0] of string = ('cuad'); // Don't have better info at the moment
{$ENDIF}
{$ENDIF}
function GetSerialPortNames: string;
var
i: Integer;
sl: TStringList;
sr : TSearchRec;
begin
Result := '';
sl := TStringList.Create;
try
for i := 0 to high(PortPrefix) do
if FindFirst('/dev/' + PortPrefix[i] + '*', LongInt($FFFFFFFF), sr) = 0 then // from patch
begin
repeat
if (sr.Attr and $FFFFFFFF) = Sr.Attr then
sl.Add(sr.Name);
until FindNext(sr) <> 0;
end;
finally
FindClose(sr);
Result := sl.CommaText;
sl.Free;
end;
end;
{$ENDIF}
Thank you, fixed in SVN#157
Code was adapted from synalist forum, and have this bugs. Additionally, it returns data in another form then Windows variant! Windows variant return data as comma-delimited list, what can be assigned easily to stringlist. Buggy code returns data as space-delimited.
Now it is repaired and data is returned as comma-delimited list.