Question

I've been Googling up and down, searching on the Free Pascal Wiki and even on some (obscure) mailing lists and have come completely empty on how to use ioctl() or fpioctl() on Free Pascal.

I have this bug report from Free Pascal's Bugtrack with code that enumerates the network interfaces.

The code does not compile since the libc unit has been deprecated.
A lot of similar questions about libc point to this wiki entry that talks about it's demise.
It does not give you any indication on where the SIOC*IF* stuff has gone.

Does that mean that most of ioctl functionality has gone?

Using find and grep, under /usr/share/fpcsrc/<fpc-version>/, I've been able to track some usage of fpioctl() in relation to terminals with the termios unit. Other stuff uses it but it looks like it's under other OSs.

Apart from that I'm unable to find anything of any use if you want to do something like:

if ioctl(sock, SIOCGIFCONF, @ifc)= 0 then begin
{...}
end;

So, can anyone from the Free Pascal Community give me a pointer to what's the current situation if one wants to do ioctl calls under Linux?

Was it helpful?

Solution

Does BaseUnix.FpIOCtl meet your use case? Have a look at the BaseUnix documentation. I found an example of using it here (reposted below).

program testrpi;

{$mode objfpc}{$H+}

uses
    baseUnix,
    classes,
    {$IFDEF UNIX}{$IFDEF UseCThreads}
    cthreads,
    {$ENDIF}{$ENDIF}
    sysutils;

const
    I2C_SLAVE            = 1795;

var
    buf                  : packed array [0..1] of char;
    c                    : char;
    devPath              : string = '/dev/i2c-1';
    handle               : Cint;
    iDevAddr             : Cint = $04;

begin

try
    handle := fpopen(devPath,O_RDWR);
    fpIOCtl(handle, I2C_SLAVE, pointer(iDevAddr));
except
    writeln('Error initalizing i2c');
    halt;
    end;

while true do begin

    write('Enter digit 1-9:');
    readln(c);
    if (not(c in ['1'..'9'])) then begin
        writeln('oops - try again');
        continue;
        end;
    buf[0] := chr(ord(c) - ord('0'));

    try
        fpwrite(handle, buf, 1); 
    except
        writeln('Error writing');
        halt;
    end; //try

    buf[0] := #99;
    sleep(10);

    try
        fpread(handle, buf, 1);
    except
        writeln('Error reading');
        halt;
    end; //try

    writeln('buf=', ord(buf[0]));
    end; //while

fpclose(handle);

end.

OTHER TIPS

The fpioctl bit has been answer by Mick and the FAQs. As for the constants, as the libc unit faq explains there is no clear cut solution, and thus for the more specialized constants there are no replacements.

OS specific constants should go in OS specific units (linux), and (somewhat) portable ones are usually grouped with the calls of the functionality they are for.

The old libc header was an rough header translation that was cleaned up somewhat, which was manageable for 32-bit Linux only, but unusable for a nix abstraction or even "just" multiplatform Linux. It was therefore abandoned.

In short it is best to either make a simple unit that abstracts the relevant parts or to just define the constants locally.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top