# difference for sysctlbyname() on i386/amd64



## Ole (Dec 23, 2008)

Hello,

Somebody can explain strange behaviour of this code on i386 and amd64 platform FreeBSD? 

test.c

```
#include <stdio.h>
#include <sys/types.h>
#include <sys/sysctl.h>

int main()
{
unsigned int physmem=0;
size_t len;

len = sizeof(physmem);
if (sysctlbyname("hw.physmem", &physmem, &len, NULL, 0) == -1)
    printf("sysctlbyname ;(",0);
else printf("%d",physmem);
}
```

on the first host:


> % sysctl hw.machine_arch kern.osrelease
> hw.machine_arch: i386
> kern.osrelease: 7.1-PRERELEASE
> % cc test.c -o test
> % ./test


Result (it correct numbers byte for my RAM):

```
1592954880
```

at the second host:


> % sysctl hw.machine_arch kern.osrelease
> hw.machine_arch: amd64
> kern.osrelease: 7.1-PRERELEASE
> % cc test.c -o test
> ...


Result:

```
sysctlbyname ;(
```

What the difference ( Without taking in the follow sample for "-W" Warning level in cc ) between i386/amd64 ?

Thanks!


----------



## anemos (Dec 23, 2008)

Hi Ole, 

Can you try to put

```
short len;
```

instead of

```
size_t len;
```

when running the program on the AMD64 and see what happens?


----------



## Ole (Dec 24, 2008)

anemos said:
			
		

> Can you try to put
> 
> ```
> short len;
> ...



Hello! With no effect ;(


----------



## anemos (Dec 24, 2008)

Interesting!

On my i386 system, your program works fine. Also, 

```
printf("%d", sizeof(size_t));
```

gives 4.

If I declare len as of another type i.e.

```
short len;
```
or

```
long len;
```

I get the very same message


> test.c: In function 'main':
> test.c:11: warning: passing argument 3 of 'sysctlbyname' from incompatible pointer type


though it is just a warning and the program runs correctly.

Oddly enough, the result taken in the first case is correct, though the number produced by a 2GByte system cannot be showed by an unsigned short (max. (2^16) - 1).

Unfortunately, I can't help you because I don't have a AMD64 system to test "things".
However, if you find out anything I'd appreciate if you let me know.

EDIT: The only thing I can see is that in amd64/include/_types.h:

```
typedef __uint64_t __size_t;
```
whereas in i386/include/_types.h is:

```
typedef __uint32_t __size_t;
```

which are both:

```
typedef __size_t size_t;
```


----------



## Ole (Dec 24, 2008)

anemos said:
			
		

> EDIT: The only thing I can see is that in amd64/include/_types.h:
> 
> ```
> typedef __uint64_t __size_t;
> ...



Yea, i find it too 

now list of code 

```
#include <stdio.h>
#include <sys/types.h>
#include <sys/sysctl.h>

int main()
{
int mb=0;
uint64_t physmem;
size_t len = sizeof(physmem);

printf("size %d\n",len);

if (sysctlbyname("hw.physmem", &physmem, &len, NULL, 0) == -1)
    printf("sysctlbyname ;(");
//mb=(physmem >>= 20);
else printf("%e",physmem);   //%e (or %u ) instead %d because size is "double int", 8bytes
}
```

Compile&Execute on amd64 platform is fine!:

```
./a.out
size 8
1060519936
```


Thanks for response!


----------



## crsd (Jan 1, 2009)

code from first post works for me.

> sysctl hw.machine_arch kern.osrelease kern.osreldate
hw.machine_arch: amd64
kern.osrelease: 8.0-CURRENT
kern.osreldate: 800060
> gcc -o test test.c
> ./test
2131050496


----------



## dap (Jan 2, 2009)

Ole said:
			
		

> What the difference ( Without taking in the follow sample for "-W" Warning level in cc ) between i386/amd64 ?



I think that physmem must be 64-bit wide on AMD64:


> If the amount of data available is greater than the size of the buffer supplied, the call supplies as much data as fits in the buffer provided and returns with the error code ENOMEM.


sysctlbyname()


----------



## uslanmaz (Nov 25, 2009)

Hi everyone,

I tried to rund the code in the first post, but I got warning saying "implicit declaration of sysctlbyname". I include the header file. What could be the reason for this?


----------



## expl (Nov 25, 2009)

Upload your /usr/include/sys/sysctl.h


----------



## uslanmaz (Nov 25, 2009)

I have this following in my sysctl.h:

...

```
#include<sys/cdefs.h>

--BEGIN_DECLS
int sysctl(int *, u_int , void *, size_t *, void *, size_t);
int sysctlbyname(const char *, void *, size_t *, void *, size_t);
int sysctlnametomib(const char *, int *, size_t *);
--END_DECLS
```
...

and I get "implicit declaration of function sysctlbyname"


----------

