Error in definition of "ifconf"
Original Reporter info from Mantis: bryanajwells
-
Reporter name: Bryan Wells
Original Reporter info from Mantis: bryanajwells
- Reporter name: Bryan Wells
Description:
According to the Unix man pages, ifconf is defined as:
struct ifconf {
int ifc_len; /* size of buffer */
union {
char * ifc_buf; /* buffer address */
struct ifreq * ifc_req; /* array of structures */
};
};
In nifh.inc it is defined as:
ifconf = record
ifc_len : longint;
ifc_ifcu : record
case longint of
0 : ( ifcu_buf : __caddr_t );
1 : ( ifcu_req : Pifreq );
end;
end;
where __caddr_t is defined in typesh.inc as (line 40):
__caddr_t = char;
Clearly char * is not a char.
The correct definition should be
__caddr_t = pChar;
This was found on the mailing list:
http://lists.freepascal.org/pipermail/fpc-devel/2010-October/022238.html
For what it is worth - Kylix's libc defines it as a pchar.
Steps to reproduce:
embed this code, and call it from your app. It should NOT compile. It doesn't compile because it complains "Incompatible type: got Pchar expected char" on line - ifConfig.ifc_ifcu.ifcu_buf:= PChar(data);
Note - this struct expects to take a char * - according to the C API.
procedure GetLocalIPs(IPs: TStringList);
const
BUFFER_SIZE = 1024;
var
ifConfig: ifconf;
InterfaceRequest: PIFreq;
theSocket: integer;
nInterfaces: integer;
IP: string;
data: array [0..BUFFER_SIZE] of char;
idx: integer;
begin
theSocket := socket(AF_INET, SOCK_DGRAM, 0);
if theSocket >= 0 then
begin
ifConfig.ifc_len:= SizeOf(data);
ifConfig.ifc_ifcu.ifcu_buf:= PChar(data);
if ioctl(theSocket, SIOCGIFCONF, @ifConfig)>= 0 then
begin
nInterfaces := ifConfig.ifc_len div SizeOf(ifreq);
for idx := 0 to Pred(nInterfaces) do begin
InterfaceRequest := PIFreq(integer(pointer(ifConfig.ifc_ifcu.ifcu_req)) + (idx * SizeOf(ifreq)));
IP := inet_ntoa(sockaddr(InterfaceRequest.ifr_ifru.ifru_addr).sin_addr);
IPs.Add(IP);
end;
end;
libc.__close(theSocket);
end;
end;
Using 2.6.4 it will not compile.
Change the definition of __caddr_t to be a pchar
(or in my instance put the following at the top of the unit)
Pifconf = ^ifconf;
ifconf = record
ifc_len : longint;
ifc_ifcu : record
case longint of
0 : ( ifcu_buf : pchar );
1 : ( ifcu_req : Pifreq );
end;
end;
It now compiles, and when run outputs the correct IP addresses from the machine.
Additional information:
I am cross-compiling from Windows -> Centos.
Mantis conversion info:
- Mantis ID: 27479
- OS: Centos
- OS Build: 6.6
- Platform: Linux
- Version: 2.6.4
- Fixed in version: 3.0.0
- Fixed in revision: 29723 (#b42f7bea)