Difference between #include <limits.h> and #inlcude <linux/limits.h> - c

In my code i am using the variable PATH_MAX for a buffer size. I had a problem when i was including the library who is supposed to define it #include <limits.h>. When i use this library my IDE doesn't recognize the variable as being define but when I include the library like #include <linux/limits.h> there is no problem and the variable is define. My question is what is the difference between both of them and will it cause problem when I will cross-compile my project ?
Thank you for all answer!

The limits.h header is a standard header that all implementations are required to supply. This contains numerical limits such as INT_MIN and INT_MAX among others. PATH_MAX is not part of this file.
The linux/limits.h header is specific to Linux. It is here that PATH_MAX is defined.

linux/limits.h is a very small header file:
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _LINUX_LIMITS_H
#define _LINUX_LIMITS_H
#define NR_OPEN 1024
#define NGROUPS_MAX 65536 /* supplemental group IDs are available */
#define ARG_MAX 131072 /* # bytes of args + environ for exec() */
#define LINK_MAX 127 /* # links a file may have */
#define MAX_CANON 255 /* size of the canonical input queue */
#define MAX_INPUT 255 /* size of the type-ahead buffer */
#define NAME_MAX 255 /* # chars in a file name */
#define PATH_MAX 4096 /* # chars in a path name including nul */
#define PIPE_BUF 4096 /* # bytes in atomic write to a pipe */
#define XATTR_NAME_MAX 255 /* # chars in an extended attribute name */
#define XATTR_SIZE_MAX 65536 /* size of an extended attribute value (64k) */
#define XATTR_LIST_MAX 65536 /* size of extended attribute namelist (64k) */
#define RTSIG_MAX 32
#endif
And this file is defining PATH_MAX in Linux.
limits.h is a C standard header defining language (not system) related macros.

Related

How to get CRTSCTS defined in termios.h?

My machine has CRTSCTS #defined inside a #ifdef __USE_MISC which stops it being available to C programs which I compile.
/usr/include/x86_64-linux-gnu/bits/termios.h:
...
#define B4000000 0010017
#define __MAX_BAUD B4000000
#ifdef __USE_MISC
# define CIBAUD 002003600000 /* input baud rate (not used) */
# define CMSPAR 010000000000 /* mark or space (stick) parity */
# define CRTSCTS 020000000000 /* flow control */
#endif
/* c_lflag bits */
#define ISIG 0000001
#define ICANON 0000002
...
How do I get access to CRTSCTS without just hacking the value 020000000000 into my program?
I already #include <termios.h> and many other headers.
I am also using:
#define __USE_POSIX199309
#define _POSIX_C_SOURCE 199309L
#include <time.h> /* nanosleep needs lines above */
The __USE_MISC macro is an internal definition that, though I suppose you could define this yourself, it's better to find the proper feature-test macro that enables it.
On my CentOS 7 system, /usr/include/features.h has a whole range of these kinds of macros, and it appears that __USE_MISC is enabled by _BSD_SOURCE or _SVID_SOURCE; it's not clear which one is compatible with other things you're going to need.
... // features.h
#if defined _BSD_SOURCE || defined _SVID_SOURCE
# define __USE_MISC 1
#endif
Try #define _BSD_SOURCE at the top of your program - before all the includes - and see how it goes.
Ref: http://man7.org/linux/man-pages/man7/feature_test_macros.7.html

implement SIP protocol in arm-cortex-m4 FREERTOS

I have been working VOIP software for some time now. I have a 88MW300 (ARM CORTEX M4) micro controller and i was wondering if i could implement SIP Protocol in the controller So that I may be able to use that device as a IP Phone to make and receive calls.
This Controller uses FreeRTOS OS and thus if there is any way to build SIP stacks would also be helpful.
I am very much new to Micro controllers and building firmware into it.So any kind of help will be appreciated.
I Tried using PJSIP source Code to compile in the board. But it is not fully compatible and gives quite a few errors. Reason being PJSIP does not have config for freertos. and also PJSIP is very large compared to the flash memory of the board. I am focusing on reducing the size later but want to successfully built it first.
The basic config file for any os is something like this.
#ifndef __PJ_COMPAT_OS_LINUX_H__
#define __PJ_COMPAT_OS_LINUX_H__
/**
* #file os_linux.h
* #brief Describes Linux operating system specifics.
*/
#define PJ_OS_NAME "linux"
#define PJ_HAS_ARPA_INET_H 1
#define PJ_HAS_ASSERT_H 1
#define PJ_HAS_CTYPE_H 1
#define PJ_HAS_ERRNO_H 1
#define PJ_HAS_LINUX_SOCKET_H 0
#define PJ_HAS_MALLOC_H 1
#define PJ_HAS_NETDB_H 1
#define PJ_HAS_NETINET_IN_H 1
#define PJ_HAS_SETJMP_H 1
#define PJ_HAS_STDARG_H 1
#define PJ_HAS_STDDEF_H 1
#define PJ_HAS_STDIO_H 1
#define PJ_HAS_STDLIB_H 1
#define PJ_HAS_STRING_H 1
#define PJ_HAS_SYS_IOCTL_H 1
#define PJ_HAS_SYS_SELECT_H 1
#define PJ_HAS_SYS_SOCKET_H 1
#define PJ_HAS_SYS_TIME_H 1
#define PJ_HAS_SYS_TIMEB_H 1
#define PJ_HAS_SYS_TYPES_H 1
#define PJ_HAS_TIME_H 1
#define PJ_HAS_UNISTD_H 1
#define PJ_HAS_SEMAPHORE_H 1
#define PJ_HAS_MSWSOCK_H 0
#define PJ_HAS_WINSOCK_H 0
#define PJ_HAS_WINSOCK2_H 0
#define PJ_HAS_LOCALTIME_R 1
#define PJ_SOCK_HAS_INET_ATON 1
/* Set 1 if native sockaddr_in has sin_len member.
* Default: 0
*/
#define PJ_SOCKADDR_HAS_LEN 0
/**
* If this macro is set, it tells select I/O Queue that select() needs to
* be given correct value of nfds (i.e. largest fd + 1). This requires
* select ioqueue to re-scan the descriptors on each registration and
* unregistration.
* If this macro is not set, then ioqueue will always give FD_SETSIZE for
* nfds argument when calling select().
*
* Default: 0
*/
#define PJ_SELECT_NEEDS_NFDS 0
/* Is errno a good way to retrieve OS errors?
*/
#define PJ_HAS_ERRNO_VAR 1
/* When this macro is set, getsockopt(SOL_SOCKET, SO_ERROR) will return
* the status of non-blocking connect() operation.
*/
#define PJ_HAS_SO_ERROR 1
/* This value specifies the value set in errno by the OS when a non-blocking
* socket recv() can not return immediate daata.
*/
#define PJ_BLOCKING_ERROR_VAL EAGAIN
/* This value specifies the value set in errno by the OS when a non-blocking
* socket connect() can not get connected immediately.
*/
#define PJ_BLOCKING_CONNECT_ERROR_VAL EINPROGRESS
/* Default threading is enabled, unless it's overridden. */
#ifndef PJ_HAS_THREADS
# define PJ_HAS_THREADS (1)
#endif
#define PJ_HAS_HIGH_RES_TIMER 1
#define PJ_HAS_MALLOC 1
#ifndef PJ_OS_HAS_CHECK_STACK
# define PJ_OS_HAS_CHECK_STACK 0
#endif
#define PJ_NATIVE_STRING_IS_UNICODE 0
#define PJ_ATOMIC_VALUE_TYPE long
/* If 1, use Read/Write mutex emulation for platforms that don't support it */
#define PJ_EMULATE_RWMUTEX 0
/* If 1, pj_thread_create() should enforce the stack size when creating
* threads.
* Default: 0 (let OS decide the thread's stack size).
*/
#define PJ_THREAD_SET_STACK_SIZE 0
/* If 1, pj_thread_create() should allocate stack from the pool supplied.
* Default: 0 (let OS allocate memory for thread's stack).
*/
#define PJ_THREAD_ALLOCATE_STACK 0
/* Linux has socklen_t */
#define PJ_HAS_SOCKLEN_T 1
#endif /* __PJ_COMPAT_OS_LINUX_H__ */
Again i am a little blurry as to what parameters should i put for FREERTOS.
Another error i get is in error generation.
the Error generation file (errorno.h) is given as.
#ifndef __PJ_COMPAT_ERRNO_H__
#define __PJ_COMPAT_ERRNO_H__
#if defined(PJ_WIN32) && PJ_WIN32 != 0 || \
defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE != 0 || \
defined(PJ_WIN64) && PJ_WIN64 != 0
typedef unsigned long pj_os_err_type;
# define pj_get_native_os_error() GetLastError()
# define pj_get_native_netos_error() WSAGetLastError()
#elif defined(PJ_HAS_ERRNO_VAR) && PJ_HAS_ERRNO_VAR!= 0
typedef int pj_os_err_type;
# define pj_get_native_os_error() (errno)
# define pj_get_native_netos_error() (errno)
#else
# error "Please define how to get errno for this platform here!"
#endif
#endif /* __PJ_COMPAT_ERRNO_H__ */
I have no idea what parameters do i add for my platform.
These are the few errors i get while compiling, After that i think i will succesfully build it.
Any kind of help will be helpful.
Thank you

How to convert between a dev_t and major/minor device numbers?

I'm trying to write a portable program that deals with ustar archives. For device files, these archives store the major and minor device numbers. However, the struct stat as laid out in POSIX only contains a single st_rdev member of type dev_t described with “Device ID (if file is character or block special).”
How can I convert between a pair of major and minor device numbers and a single st_rdev member as returned by stat() in a portable manner?
While all POSIX programming interfaces use the device number (of type dev_t) as is, FUZxxl pointed out in a comment to this answer that the common UStar file format -- most common tar archive format -- does split the device number into major and minor. (They are typically encoded as seven octal digits each, so for compatibility reasons one should limit to 21-bit unsigned major and 21-bit unsigned minor. This also means that mapping the device number to just the major or just the minor is not a reliable approach.)
The following include file expanding on Jonathon Reinhart's answer, after digging on the web for the various systems man pages and documentation (for makedev(), major(), and minor()), plus comments to this question.
#if defined(custom_makedev) && defined(custom_major) && defined(custom_minor)
/* Already defined */
#else
#undef custom_makedev
#undef custom_major
#undef custom_minor
#if defined(__linux__) || defined(__GLIBC__)
/* Linux, Android, and other systems using GNU C library */
#ifndef _BSD_SOURCE
#define _BSD_SOURCE 1
#endif
#include <sys/types.h>
#define custom_makedev(dmajor, dminor) makedev(dmajor, dminor)
#define custom_major(devnum) major(devnum)
#define custom_minor(devnum) minor(devnum)
#elif defined(_WIN32)
/* 32- and 64-bit Windows. VERIFY: These are just a guess! */
#define custom_makedev(dmajor, dminor) ((((unsigned int)dmajor << 8) & 0xFF00U) | ((unsigned int)dminor & 0xFFFF00FFU))
#define custom_major(devnum) (((unsigned int)devnum & 0xFF00U) >> 8)
#define custom_minor(devnum) ((unsigned int)devnum & 0xFFFF00FFU)
#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
/* FreeBSD, OpenBSD, NetBSD, and DragonFlyBSD */
#include <sys/types.h>
#define custom_makedev(dmajor, dminor) makedev(dmajor, dminor)
#define custom_major(devnum) major(devnum)
#define custom_minor(devnum) minor(devnum)
#elif defined(__APPLE__) && defined(__MACH__)
/* Mac OS X */
#include <sys/types.h>
#define custom_makedev(dmajor, dminor) makedev(dmajor, dminor)
#define custom_major(devnum) major(devnum)
#define custom_minor(devnum) minor(devnum)
#elif defined(_AIX) || defined (__osf__)
/* AIX, OSF/1, Tru64 Unix */
#include <sys/types.h>
#define custom_makedev(dmajor, dminor) makedev(dmajor, dminor)
#define custom_major(devnum) major(devnum)
#define custom_minor(devnum) minor(devnum)
#elif defined(hpux)
/* HP-UX */
#include <sys/sysmacros.h>
#define custom_makedev(dmajor, dminor) makedev(dmajor, dminor)
#define custom_major(devnum) major(devnum)
#define custom_minor(devnum) minor(devnum)
#elif defined(sun)
/* Solaris */
#include <sys/types.h>
#include <sys/mkdev.h>
#define custom_makedev(dmajor, dminor) makedev(dmajor, dminor)
#define custom_major(devnum) major(devnum)
#define custom_minor(devnum) minor(devnum)
#else
/* Unknown OS. Try a the BSD approach. */
#ifndef _BSD_SOURCE
#define _BSD_SOURCE 1
#endif
#include <sys/types.h>
#if defined(makedev) && defined(major) && defined(minor)
#define custom_makedev(dmajor, dminor) makedev(dmajor, dminor)
#define custom_major(devnum) major(devnum)
#define custom_minor(devnum) minor(devnum)
#endif
#endif
#if !defined(custom_makedev) || !defined(custom_major) || !defined(custom_minor)
#error Unknown OS: please add definitions for custom_makedev(), custom_major(), and custom_minor(), for device number major/minor handling.
#endif
#endif
One could glean additional definitions from existing UStar-format -capable archivers. Compatibility with existing implementations on each OS/architecture is, in my opinion, the most important thing here.
The above should cover all systems using GNU C library, Linux (including Android), FreeBSD, OpenBSD, NetBSD, DragonFlyBSD, Mac OS X, AIX, Tru64, HP-UX, and Solaris, plus any that define the macros when <sys/types.h> is included. Of the Windows part, I'm not sure.
As I understand it, Windows uses device 0 for all normal files, and a HANDLE (a void pointer type) for devices. I am not at all sure whether the above logic is sane on Windows, but many older systems put the 8 least significant bits of the device number into minor, and the next 8 bits into major, and the convention seems to be that any leftover bits would be put (without shifting) into minor, too. Examining existing UStar-format tar archives with references to devices would be useful, but I personally do not use Windows at all.
If a system is not detected, and the system does not use the BSD-style inclusion for defining the macros, the above will error out stopping the compilation. (I would personally add compile-time machinery that could help finding the correct header definitions, using e.g. find, xargs, and grep, in case that happens, with a suggestion to send the addition upstream, too. touch empty.h ; cpp -dM empty.h ; rm -f empty.h should show all predefined macros, to help with identifying the OS and/or C library.)
Originally, POSIX stated that dev_t must be an arithmetic type (thus, theoretically, it might have been some variant of float or double on some systems), but IEEE Std 1003.1, 2013 Edition says it must be an integer type. I would wager that means no known POSIX-y system ever used a floating-point dev_t type. It would seem that Windows uses a void pointer, or HANDLE type, but Windows is not POSIX-compliant anyway.
Use the major() and minor() macros after defining BSD_SOURCE.
The makedev(), major(), and minor() functions are not specified in
POSIX.1, but are present on many other systems.
http://man7.org/linux/man-pages/man3/major.3.html
I have a program based on an antique version of ls for Minix, but much mangled modified by me since then. It has the following code to detect the major and minor macros — and some comments about (now) antique systems where it has worked in the past. It assumes a sufficiently recent version of GCC is available to support #pragma GCC diagnostic ignored etc. You have to be trying pretty hard (e.g. clang -Weverything) to get the -Wunused-macros option in effect unless you include it explicitly.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-macros"
/* Defines to ensure major and minor macros are available */
#define _DARWIN_C_SOURCE /* In <sys/types.h> on MacOS X */
#define _BSD_SOURCE /* In <sys/sysmacros.h> via <sys/types.h> on Linux (Ubuntu 12.0.4) */
#define __EXTENSIONS__ /* Maybe beneficial on Solaris */
#pragma GCC diagnostic pop
/* From Solaris 2.6 sys/sysmacros.h
**
** WARNING: The device number macros defined here should not be used by
** device drivers or user software. [...] Application software should make
** use of the library routines available in makedev(3). [...] Macro
** routines bmajor(), major(), minor(), emajor(), eminor(), and makedev()
** will be removed or their definitions changed at the next major release
** following SVR4.
**
** #define O_BITSMAJOR 7 -- # of SVR3 major device bits
** #define O_BITSMINOR 8 -- # of SVR3 minor device bits
** #define O_MAXMAJ 0x7f -- SVR3 max major value
** #define O_MAXMIN 0xff -- SVR3 max major value
**
** #define L_BITSMAJOR 14 -- # of SVR4 major device bits
** #define L_BITSMINOR 18 -- # of SVR4 minor device bits
** #define L_MAXMAJ 0x3fff -- SVR4 max major value
** #define L_MAXMIN 0x3ffff -- MAX minor for 3b2 software drivers.
** -- For 3b2 hardware devices the minor is restricted to 256 (0-255)
*/
/* AC_HEADER_MAJOR:
** - defines MAJOR_IN_MKDEV if found in sys/mkdev.h
** - defines MAJOR_IN_SYSMACROS if found in sys/macros.h
** - otherwise, hope they are in sys/types.h
*/
#if defined MAJOR_IN_MKDEV
#include <sys/mkdev.h>
#elif defined MAJOR_IN_SYSMACROS
#include <sys/sysmacros.h>
#elif defined(MAJOR_MINOR_MACROS_IN_SYS_TYPES_H)
/* MacOS X 10.2 - for example */
/* MacOS X 10.5 requires -D_DARWIN_C_SOURCE or -U_POSIX_C_SOURCE - see above */
#elif defined(USE_CLASSIC_MAJOR_MINOR_MACROS)
#define major(x) ((x>>8) & 0x7F)
#define minor(x) (x & 0xFF)
#else
/* Hope the macros are in <sys/types.h> or otherwise magically visible */
#endif
#define MAJOR(x) ((long)major(x))
#define MINOR(x) ((long)minor(x))
You will justifiably not be all that keen on the 'hope the macros are … magically visible' part of the code.
The reference to AC_HEADER_MAJOR is to the macro in the autoconf that deduces this information. It would be relevant if you have a config.h file generated by autoconf.
POSIX
Note that the POSIX pax command defines the ustar format and specifies that it includes devmajor and devminor in the information, but adds:
… Represent character special files and block special files respectively. In this case the devmajor and devminor fields shall contain information defining the device, the format of which is unspecified by this volume of POSIX.1-2008. Implementations may map the device specifications to their own local specification or may ignore the entry.
This means that there isn't a fully portable way to represent the numbers. This is not wholly unreasonable (but it is a nuisance); the meanings of the major and minor device numbers varies across platforms and is unspecified too. Any attempt to create block or character devices via ustar format will only work reasonably reliably if the source and target machines are running the same (version of the same) operating system — though usually they're portable across versions of the same operating system.

Understanding fd_set in unix sys/select.h

I am not really fluent in C but I have experience in Java, C#, Python, Rust etc. I am currently trying to wrap fd_set in Rust but I have absolutely no idea how to read this code.
I am only interested in this part:
typedef struct
{
/* XPG4.2 requires this member name. Otherwise avoid the name
from the global namespace. */
#ifdef __USE_XOPEN
__fd_mask fds_bits[__FD_SETSIZE / __NFDBITS];
# define __FDS_BITS(set) ((set)->fds_bits)
#else
__fd_mask __fds_bits[__FD_SETSIZE / __NFDBITS];
# define __FDS_BITS(set) ((set)->__fds_bits)
#endif
} fd_set;
So far I understood that __fd_mask is just a long int. __NFDBITS just gives me the size of a long int and multiplies it by 8.
But I have no idea what this is doing #define FD_SETSIZE __FD_SETSIZE and there for I don't know what this is doing _fd_mask __fds_bits[__FD_SETSIZE / __NFDBITS]; For me FD_SETSIZE has no value at all. And I have absolutely no idea what # define __FDS_BITS(set) ((set)->__fds_bits) is doing.
I really would like to see how this code would look in java or c# etc
Full header file:
/* `fd_set' type and related macros, and `select'/`pselect' declarations.
Copyright (C) 1996-2003, 2009, 2011 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
/* POSIX 1003.1g: 6.2 Select from File Descriptor Sets <sys/select.h> */
#ifndef _SYS_SELECT_H
#define _SYS_SELECT_H 1
#include <features.h>
/* Get definition of needed basic types. */
#include <bits/types.h>
/* Get __FD_* definitions. */
#include <bits/select.h>
/* Get __sigset_t. */
#include <bits/sigset.h>
#ifndef __sigset_t_defined
# define __sigset_t_defined
typedef __sigset_t sigset_t;
#endif
/* Get definition of timer specification structures. */
#define __need_time_t
#define __need_timespec
#include <time.h>
#define __need_timeval
#include <bits/time.h>
#ifndef __suseconds_t_defined
typedef __suseconds_t suseconds_t;
# define __suseconds_t_defined
#endif
/* The fd_set member is required to be an array of longs. */
typedef long int __fd_mask;
/* Some versions of <linux/posix_types.h> define this macros. */
#undef __NFDBITS
/* It's easier to assume 8-bit bytes than to get CHAR_BIT. */
#define __NFDBITS (8 * (int) sizeof (__fd_mask))
#define __FD_ELT(d) ((d) / __NFDBITS)
#define __FD_MASK(d) ((__fd_mask) 1 << ((d) % __NFDBITS))
/* fd_set for select and pselect. */
typedef struct
{
/* XPG4.2 requires this member name. Otherwise avoid the name
from the global namespace. */
#ifdef __USE_XOPEN
__fd_mask fds_bits[__FD_SETSIZE / __NFDBITS];
# define __FDS_BITS(set) ((set)->fds_bits)
#else
__fd_mask __fds_bits[__FD_SETSIZE / __NFDBITS];
# define __FDS_BITS(set) ((set)->__fds_bits)
#endif
} fd_set;
/* Maximum number of file descriptors in `fd_set'. */
#define FD_SETSIZE __FD_SETSIZE
#ifdef __USE_MISC
/* Sometimes the fd_set member is assumed to have this type. */
typedef __fd_mask fd_mask;
/* Number of bits per word of `fd_set' (some code assumes this is 32). */
# define NFDBITS __NFDBITS
#endif
/* Access macros for `fd_set'. */
#define FD_SET(fd, fdsetp) __FD_SET (fd, fdsetp)
#define FD_CLR(fd, fdsetp) __FD_CLR (fd, fdsetp)
#define FD_ISSET(fd, fdsetp) __FD_ISSET (fd, fdsetp)
#define FD_ZERO(fdsetp) __FD_ZERO (fdsetp)
__BEGIN_DECLS
/* Check the first NFDS descriptors each in READFDS (if not NULL) for read
readiness, in WRITEFDS (if not NULL) for write readiness, and in EXCEPTFDS
(if not NULL) for exceptional conditions. If TIMEOUT is not NULL, time out
after waiting the interval specified therein. Returns the number of ready
descriptors, or -1 for errors.
This function is a cancellation point and therefore not marked with
__THROW. */
extern int select (int __nfds, fd_set *__restrict __readfds,
fd_set *__restrict __writefds,
fd_set *__restrict __exceptfds,
struct timeval *__restrict __timeout);
#ifdef __USE_XOPEN2K
/* Same as above only that the TIMEOUT value is given with higher
resolution and a sigmask which is been set temporarily. This version
should be used.
This function is a cancellation point and therefore not marked with
__THROW. */
extern int pselect (int __nfds, fd_set *__restrict __readfds,
fd_set *__restrict __writefds,
fd_set *__restrict __exceptfds,
const struct timespec *__restrict __timeout,
const __sigset_t *__restrict __sigmask);
#endif
/* Define some inlines helping to catch common problems. */
#if __USE_FORTIFY_LEVEL > 0 && defined __GNUC__
# include <bits/select2.h>
#endif
__END_DECLS
#endif /* sys/select.h */
fd_set is used to represent file descriptor set. For example, I need select() to work on 1024 file descriptors, but a long has only 8 bytes, so that's 64 (8 * 8) bits, so naturally fd_set should be represented as an array of long.
typedef struct
{
long fds_bits[1024 / 64];
} fd_set;
Note that this is just an example to demonstrate, but you get the idea, compare this with the real fd_set, and you'll see.

GCC option to get statvfs64

I am using statvfs function call on AIX. And using GCC compiler.
I would like statvfs call to resolve to statvfs64 by preprocessor.
Ex: In Solaris, using "-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64" flags with gcc i am resolved to statvfs64.
Could you please help in getting the similar flags on AIX which resolves me to statvfs64 from statvfs.
Thanks & Regards,
Sivaram T
Thanks a lot for immediate response.
Unfortunately there is no "_LARGEFILE64_SOURCE" define on AIX include file.
I come to know the following options
"-maix64 -mpowerpc64" can resolve to the statvfs64. Not sure whether these are right to use or not.
Please find the following sys/statvfs.h file
=================================================
#ifndef _H_STATVFS
#define _H_STATVFS
#ifndef _H_STANDARDS
#include <standards.h>
#endif
#if _XOPEN_SOURCE_EXTENDED==1
#include <strict_stdtypes.h>
#ifndef _H_TYPES
#include <sys/types.h>
#endif
#include <end_strict_stdtypes.h>
#define _FSTYPSIZ 16
#ifdef _ALL_SOURCE
#include <sys/vmount.h>
#define FSTYPSIZ _FSTYPSIZ
#endif
/*
* statvfs system call return structure
*/
struct statvfs {
ulong_t f_bsize; /* preferred file system block size */
ulong_t f_frsize; /* fundamental file system block size */
fsblkcnt_t f_blocks; /* total # of blocks of f_frsize in fs */
fsblkcnt_t f_bfree; /* total # of free blocks */
fsblkcnt_t f_bavail; /* # of blocks available to non super user */
fsfilcnt_t f_files; /* total # of file nodes (inode in JFS) */
fsfilcnt_t f_ffree; /* total # of free file nodes */
fsfilcnt_t f_favail; /* # of nodes available to non super user */
#ifdef _ALL_SOURCE
fsid_t f_fsid; /* file system id */
#else
ulong_t f_fsid; /* file system id */
#ifndef __64BIT__
ulong_t f_fstype; /* file system type */
#endif
#endif /* _ALL_SOURCE */
char f_basetype[_FSTYPSIZ]; /* Filesystem type name (eg. jfs) */
ulong_t f_flag; /* bit mask of flags */
ulong_t f_namemax; /* maximum filename length */
char f_fstr[32]; /* filesystem-specific string */
ulong_t f_filler[16];/* reserved for future use */
};
#define ST_NOSUID 0x0040 /* don't maintain SUID capability */
#define ST_RDONLY 0x0001 /* file system mounted read only */
#define ST_NODEV 0x0080 /* don't allow device access across */
/* this mount */
/*
* Prototypes
*/
#ifdef _NO_PROTO
extern int statvfs();
extern int fstatvfs();
#else
extern int statvfs(const char *__restrict__, struct statvfs *__restrict__);
extern int fstatvfs(int, struct statvfs *);
#endif
/*
* statvfs64 system call return structure
*/
#ifdef _ALL_SOURCE
struct statvfs64 {
blksize64_t f_bsize; /* preferred file system block size */
blksize64_t f_frsize; /* fundamental file system block size */
blkcnt64_t f_blocks; /* total # of blocks of f_frsize in fs */
blkcnt64_t f_bfree; /* total # of free blocks */
blkcnt64_t f_bavail; /* # of blocks available to non super user */
blkcnt64_t f_files; /* total # of file nodes (inode in JFS) */
blkcnt64_t f_ffree; /* total # of free file nodes */
blkcnt64_t f_favail; /* # of nodes available to non super user */
fsid64_t f_fsid; /* file system id */
char f_basetype[FSTYPSIZ]; /* Filesystem type name (eg. jfs) */
ulong_t f_flag; /* bit mask of flags */
ulong_t f_namemax; /* maximum filename length */
char f_fstr[32]; /* filesystem-specific string */
ulong_t f_filler[16];/* reserved for future use */
};
/*
* Prototypes
*/
#ifdef _NO_PROTO
extern int statvfs64();
extern int fstatvfs64();
#else
extern int statvfs64(const char *__restrict__, struct statvfs64 *__restrict__);
extern int fstatvfs64(int, struct statvfs64 *);
#endif
#endif /* _ALL_SOURCE */
#endif /* _XOPEN_SOURCE_EXTENDED */
#endif /* _H_STATVFS */
=================================================
I don't have an AIX system, so I can't tell you the flags to set. However, on Solaris you can view sys/statvfs.h and see how this works, e.g search for statvfs64 and look for the #ifdef blocks surrounding it. You'll see the lines
#if defined(_LARGEFILE64_SOURCE)
typedef struct statvfs64 {
.....
} statvfs64_t;
#endif
#if !defined(_LP64) && _FILE_OFFSET_BITS == 64
...
#define statvfs_t statvfs64_t
#define statvfs statvfs64
#define fstatvfs fstatvfs64
#endif
You will be able to do exactly the same thing on AIX. However, AIX may behave differently and not use the pre-processor to switch between the 32 and 64 bit versions.
If it's not obvious to you, then you could post the contents of sys/statvfs.h up here and we can take a look for you.
iirc on AIX you need the _LARGE_FILES token set, which will enable implicit large file support.
-D_LARGE_FILES
If you want to call statvfs64 explicittly, you have to do
-D_LARGE_FILE_API

Resources