I need to change a sched process' state by creating and calling a system call. And that's my code for do_settickets system call.
#include <stdio.h>
#include "pm.h"
#include "../sched/sched.h"
#include "../sched/schedproc.h"
#include <assert.h>
#include <minix/com.h>
#include <machine/archtypes.h>
#include <stdlib.h>
#define LOW_THRESHOLD 1
#define HIGH_THRESHOLD 30
int do_settickets(void){
struct schedproc *rpm;
int set_ticket = m_in.m1_i2; // get wanted set ticket value from message
int index = m_in.m1_i1; //get processIndex
rpm = &schedproc[index];
if(set_ticket < LOW_THRESHOLD){
rpm->ticket = LOW_THRESHOLD;
}else if(set_ticket > HIGH_THRESHOLD){
rpm->ticket = HIGH_THRESHOLD;
}else{
rpm->ticket = set_ticket;
}
return 1;
}
When i use "make hdboot" int /usr/src/releasetools, there is a linking error that say:
do_settickets.o: In function `do_settickets':
do_settickets.c:(.text+0x1a): undefined reference to `schedproc'
do_settickets.c:(.text+0x2d): undefined reference to `schedproc'
That's the header file that contains declaration for "struct schedproc"
GNU nano 2.4.2 File: schedproc.h
/* This table has one slot per process. It contains scheduling information
* for each process.
*/
#include <limits.h>
#include <minix/bitmap.h>
/* EXTERN should be extern except in main.c, where we want to keep the struct */
#ifdef _MAIN
#undef EXTERN
#define EXTERN
#endif
#ifndef CONFIG_SMP
#define CONFIG_MAX_CPUS 1
#endif
/**
* We might later want to add more information to this table, such as the
* process owner, process group or cpumask.
*/
EXTERN struct schedproc {
endpoint_t endpoint; /* process endpoint id */
endpoint_t parent; /* parent endpoint id */
unsigned flags; /* flag bits */
int ticket;
int hasTorpil;
/* User space scheduling */
unsigned max_priority; /* this process' highest allowed priority */
unsigned priority; /* the process' current priority */
unsigned time_slice; /* this process's time slice */
unsigned cpu; /* what CPU is the process running on */
bitchunk_t cpu_mask[BITMAP_CHUNKS(CONFIG_MAX_CPUS)]; /* what CPUs is the
process allowed
to run on */
} schedproc[NR_PROCS];
/* Flag values */
#define IN_USE 0x00001 /* set when 'schedproc' slot in use */
What should i do to modify schedproc array in a systemcall?
Related
I'm learning unix network programming. I include #include <sys/select.h> and call FD_SET function. The code can compile successfully when I run gcc manually.
The problem is my IDE Clion can not recognize FD_SET, so it can not help me auto-complete the rest code when I type FD_. So I check the select.h file, I can not find FD_SET declaration in the file.
Here is the source code of select.h on my Mac:
#ifndef _SYS_SELECT_H_
#define _SYS_SELECT_H_
#include <sys/appleapiopts.h>
#include <sys/cdefs.h>
#include <sys/_types.h>
/*
* [XSI] The <sys/select.h> header shall define the fd_set type as a structure.
* The timespec structure shall be defined as described in <time.h>
* The <sys/select.h> header shall define the timeval structure.
*/
#include <sys/_types/_fd_def.h>
#include <sys/_types/_timespec.h>
#include <sys/_types/_timeval.h>
/*
* The time_t and suseconds_t types shall be defined as described in
* <sys/types.h>
* The sigset_t type shall be defined as described in <signal.h>
*/
#include <sys/_types/_time_t.h>
#include <sys/_types/_suseconds_t.h>
#include <sys/_types/_sigset_t.h>
/*
* [XSI] FD_CLR, FD_ISSET, FD_SET, FD_ZERO may be declared as a function, or
* defined as a macro, or both
* [XSI] FD_SETSIZE shall be defined as a macro
*/
/*
* Select uses bit masks of file descriptors in longs. These macros
* manipulate such bit fields (the filesystem macros use chars). The
* extra protection here is to permit application redefinition above
* the default size.
*/
#include <sys/_types/_fd_setsize.h>
#include <sys/_types/_fd_set.h>
#include <sys/_types/_fd_clr.h>
#include <sys/_types/_fd_isset.h>
#include <sys/_types/_fd_zero.h>
#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
#include <sys/_types/_fd_copy.h>
#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
__BEGIN_DECLS
#ifndef __MWERKS__
int pselect(int, fd_set * __restrict, fd_set * __restrict,
fd_set * __restrict, const struct timespec * __restrict,
const sigset_t * __restrict)
#if defined(_DARWIN_C_SOURCE) || defined(_DARWIN_UNLIMITED_SELECT)
__DARWIN_EXTSN_C(pselect)
#else /* !_DARWIN_C_SOURCE && !_DARWIN_UNLIMITED_SELECT */
# if defined(__LP64__) && !__DARWIN_NON_CANCELABLE
__DARWIN_1050(pselect)
# else /* !__LP64__ || __DARWIN_NON_CANCELABLE */
__DARWIN_ALIAS_C(pselect)
# endif /* __LP64__ && !__DARWIN_NON_CANCELABLE */
#endif /* _DARWIN_C_SOURCE || _DARWIN_UNLIMITED_SELECT */
;
#endif /* __MWERKS__ */
#include <sys/_select.h> /* select() prototype */
__END_DECLS
#endif /* !_SYS_SELECT_H_ */
So, where can I find FD_SET declaration? And how should I configure my clion so it can recognize it?
port_pin.h
#ifndef __PORT_PIN_H__
#define __PORT_PIN_H__
typedef enum
{
IO_PORT_A = ((uint16_t)0), /* IO Port A Selected */
IO_PORT_B = ((uint16_t)1), /* IO Port B Selected */
IO_PORT_NONE = ((uint16_t)0xFF) /* No IO Port Selected */
}PortName_t;
/* IO Driver GPIO Pin Numbers */
typedef enum
{
IO_PIN_0 = ((uint16_t)0), /* Pin 0 selected */
IO_PIN_1 = ((uint16_t)1), /* Pin 1 selected */
IO_PIN_2 = ((uint16_t)2), /* Pin 2 selected */
IO_PIN_3 = ((uint16_t)3), /* Pin 3 selected */
}PinNumber_t;
hal_io.h
#ifndef __HAL_IO_H__
#define __HAL_IO_H__
#ifdef DEF_HAL_IO
#define EXTERN_HAL_IO
#else
#define EXTERN_HAL_IO extern
#endif
EXTERN_HAL_IO void HalIo_fct(PortName_t, PinNumber_t);
#endif
drv_io.h
#ifndef __DRV_IO_H__
#define __DRV_IO_H__
#ifdef DEF_DRV_IO
#define EXTERN_DRV_IO
#else
#define EXTERN_DRV_IO extern
#endif
EXTERN_DRV_IO Status_t DDrvIOPinSet_fct(const BoardCfgPortPin_t *pointer);
#endif
board_cfg.h
#ifndef __BOARD_CFG_H__
#define __BOARD_CFG_H__
#ifdef DEF_BOARD_CFG
#define EXTERN_BOARD_CFG
#else
#define EXTERN_BOARD_CFG extern
#endif
/* IO driver Gpio Port and Pin Configuration */
typedef struct
{
PortName_t Name_en; /* Specifies the IO Port module */
/* This parameter can be a value of #ref */
/* GpioPort_t */
PinNumber_t PinNo_en; /* Specifies the IO Pin number */
/* This parameter can be a value of #ref */
/* PinNumber_t */
}BoardCfgPortPin_t;
EXTERN_BOARD_CFG const BoardCfgPortPin_t BoardCfgPortPin_sta[4];
EXTERN_BOARD_CFG void BoardCfg_fct();
#endif
main.c
#include <stdio.h>
#include "common.h"
#include "port_pin.h"
#include "board_cfg.h"
#include "drv_io.h"
int main()
{
BoardCfg_fct();
printf("\n\n");
return 0;
}
hal_io.c
#define DEF_HAL_IO
#include <stdio.h>
#include "common.h"
#include "port_pin.h"
#include "hal_io.h"
void HalIo_fct(PortName_t PortName_en, PinNumber_t PinNo_en)
{
printf("\nIN HAL\n");
printf("PORTNAME : %d, PIN NUMBER : %d", PortName_en, PinNo_en);
}
drv_io.c
#define DEF_DRV_IO
#include <stdio.h>
#include "common.h"
#include "port_pin.h"
#include "hal_io.h"
#include "board_cfg.h"
#include "drv_io.h"
Status_t DDrvIOPinSet_fct(const BoardCfgPortPin_t *pointer)
{
printf("\nin DRV IO \n");
HalIo_fct(pointer->Name_en, pointer->PinNo_en);
return (PASS);
}
board_cfg.c
#define DEF_BOARD_CFG
#include <stdio.h>
#include "common.h"
#include "port_pin.h"
#include "drv_io.h"
#include "board_cfg.h"
const BoardCfgPortPin_t BoardCfgPortPin_sta[4] =
{
{ IO_PORT_B, IO_PIN_0 }, /* SENSE_INV_TEMP */
{ IO_PORT_B, IO_PIN_1 }, /* SENSE_INV_AC */
{ IO_PORT_B, IO_PIN_2 }, /* BUZZER */
{ IO_PORT_B, IO_PIN_3 }, /* STAUS_230V_AC */
};
void BoardCfg_fct()
{
DDrvIOPinSet_fct(&BoardCfgPortPin_sta[0]);
DDrvIOPinSet_fct(&BoardCfgPortPin_sta[1]);
DDrvIOPinSet_fct(&BoardCfgPortPin_sta[2]);
DDrvIOPinSet_fct(&BoardCfgPortPin_sta[3]);
}
Regarding the above files, when I try to compile the code I am getting the following errors:
drv_io.h(10): error C2143: syntax error : missing ')' before '*'
drv_io.h(10): error C2143: syntax error : missing '{' before '*'
drv_io.h(10): error C2059: syntax error : ')'
If I comment the code in board_cfg.h
/* IO driver Gpio Port and Pin Configuration */
typedef struct
{
PortName_t Name_en; /* Specifies the IO Port module */
/* This parameter can be a value of #ref */
/* GpioPort_t */
PinNumber_t PinNo_en; /* Specifies the IO Pin number */
/* This parameter can be a value of #ref */
/* PinNumber_t */
}BoardCfgPortPin_t;
and add it to port_pin.h, I could compile the code successfully.
But I need to have the struct in board_cfg.h only
Why am I getting this error?
In the file board_cfg.c, it has drv_io.h first followed by board_cfg.h. However, the delaration of DDrvIOPinSet_fct has an argument of type BoardCfgPortPin_t which is defined in board_cfg.h. Since drv_io.h is listed first, BoardCfgPortPin_t hasn't been declared yet. This is what is causing the error.
Your header files are dependent on each other. Rather than depending on the files that include them to put things in the right order, each header file needs to include the other headers they depend on.
In port_pin.h, add #include <stdint.h>
In hal_io.h, add #include "port_pin.h"
In drv_io.h, add #include "board_cfg.h" and #include "common.h"
In board_cfg.h add #include "port_pin.h"
By doing this, each header has everything it needs. Then it doesn't matter in which order they are included by source files.
Also, you don't need any of the defines related to extern. Function declarations are extern by default.
In line 10 of drv_io.h you have
EXTERN_DRV_IO Status_t DDrvIOPinSet_fct(const BoardCfgPortPin_t *pointer);
So you are using BoardCfgPortPin_t which means that the compiler has to know at this point what BoardCfgPortPin_t is. There are several ways to achieve this:
#include board_cfg.h in drv_io.h before line 10
use a forward declaration: put typedef struct BoardCfgPortPin_t; before line 10
make sure all .c files include board_cfg.h before drv_io.h; this is already the case for all but board_cfg.c
I have the following two files, the first one creates a signal handler for SIGUSR1, which sets up a fake call to the function foo() in the interrupted context. The second file is a template header for accessing IA32 registers.
stack.c:
#ifdef HARMONY
#define LINUX
#include "hythread.h"
#endif
#ifndef _GNU_SOURCE
#define _GNU_SOURCE // so that string.h will include strsignal()
#endif
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/mman.h>
#include <errno.h>
#include <string.h>
#include <stdarg.h> // va_list, va_start(), va_end()
#ifndef __USE_GNU // Deal with current ucontext ugliness. The current
#define __USE_GNU // mess of asm/ucontext.h & sys/ucontext.h and their
#include <sys/ucontext.h> // mutual exclusion on more recent versions of gcc
#undef __USE_GNU // dictates this ugly hack.
#else
#include <sys/ucontext.h>
#endif
#include <assert.h>
#include "linux_ucontext.h"
#define DBG(fncn,name) if (fncn) { perror(name); return 1; }
void foo(void *fp) {
printf("Inside foo(%p)\n", fp);
}
typedef long unsigned int* Address;
void handler(int signo, siginfo_t *si, void *context) {
if (signo == SIGUSR1) {
printf("Handling SIGUSR1...\n");
// Set fake pointer (0xDEADBEEF) as first argument to foo()
Address sp = (Address)IA32_ESP(context);
IA32_ESP(context) = IA32_ESP(context) - sizeof(void *);
sp = (Address)IA32_ESP(context);
((Address *)sp)[0] = IA32_EIP(context);
IA32_EAX(context) = 0xDEADBEEF;
// Put return address of interrupted instruction onto stack
IA32_ESP(context) = IA32_ESP(context) - sizeof(void *);
sp = IA32_ESP(context);
((Address *)sp)[0] = IA32_EIP(context);
// Setup function call to foo()
IA32_EIP(context) = foo;
return;
}
printf("Received unknown signal signo=%d\n",signo);
}
int main(int argc, char *argv[]) {
struct sigaction action;
memset(&action, 0, sizeof(action));
action.sa_sigaction = &handler;
// Mask all signals from reaching handler while handler is running
DBG(sigfillset(&(action.sa_mask)),"sigfillset");
DBG(sigdelset(&(action.sa_mask), SIGCONT),"sigdelset");
action.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_RESTART;
action.sa_sigaction = &handler;
DBG(sigaction(SIGUSR1, &action, 0),"sigaction")
int count = 0;
while (1) {
sleep(1);
printf("Inside while loop %08d...\n",count);
count += 1;
}
}
linux_context.h:
/*
* This file is part of the Jikes RVM project (http://jikesrvm.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License. You
* may obtain a copy of the License at
*
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership.
*/
#ifndef JRVM_LINUX_IA32_UCONTEXT
#define JRVM_LINUX_IA32_UCONTEXT
#define __MC(context) ((ucontext_t*)context)->uc_mcontext
#define __GREGS(context) (__MC(context).gregs)
#ifndef __x86_64__
# define IA32_EAX(context) (__GREGS(context)[REG_EAX])
# define IA32_EBX(context) (__GREGS(context)[REG_EBX])
# define IA32_ECX(context) (__GREGS(context)[REG_ECX])
# define IA32_EDX(context) (__GREGS(context)[REG_EDX])
# define IA32_EDI(context) (__GREGS(context)[REG_EDI])
# define IA32_ESI(context) (__GREGS(context)[REG_ESI])
# define IA32_EBP(context) (__GREGS(context)[REG_EBP])
# define IA32_ESP(context) (__GREGS(context)[REG_ESP])
# define IA32_EIP(context) (__GREGS(context)[REG_EIP])
# define IA32_CS(context) (__GREGS(context)[REG_CS])
# define IA32_DS(context) (__GREGS(context)[REG_DS])
# define IA32_ES(context) (__GREGS(context)[REG_ES])
# define IA32_FS(context) (__GREGS(context)[REG_FS])
# define IA32_GS(context) (__GREGS(context)[REG_GS])
# define IA32_SS(context) (__GREGS(context)[REG_SS])
# define IA32_OLDMASK(context) (__MC(context).oldmask)
# define IA32_FPFAULTDATA(context) (__MC(context).cr2)
#else
# define IA32_EAX(context) (__GREGS(context)[REG_RAX])
# define IA32_EBX(context) (__GREGS(context)[REG_RBX])
# define IA32_ECX(context) (__GREGS(context)[REG_RCX])
# define IA32_EDX(context) (__GREGS(context)[REG_RDX])
# define IA32_EDI(context) (__GREGS(context)[REG_RDI])
# define IA32_ESI(context) (__GREGS(context)[REG_RSI])
# define IA32_EBP(context) (__GREGS(context)[REG_RBP])
# define IA32_ESP(context) (__GREGS(context)[REG_RSP])
# define IA32_EIP(context) (__GREGS(context)[REG_RIP])
#endif
#define IA32_EFLAGS(context) (__GREGS(context)[REG_EFL])
#define IA32_TRAPNO(context) (__GREGS(context)[REG_TRAPNO])
#define IA32_ERR(context) (__GREGS(context)[REG_ERR])
#define IA32_FALUTVADDR(context) (__GREGS(context)[REG_CS])
#define IA32_FPREGS(context) (__MC(context).fpregs)
// reg = 0..7, n = 0 .. 3
#define IA32_STMM(context, reg, n) (IA32_FPREGS(context)->_st[reg].significand[n])
#define IA32_STMMEXP(context, reg) (IA32_FPREGS(context)->_st[reg].exponent)
/* Currently unused
#define IA32_XMM(context, reg, n) \
*/
#endif
When I compile and run this, and hit the process with a SIGUSR1, foo() is called correctly and returns back to the while loop. However when I set up a similar signal handler which interrupts some arbitrary code (running a JVM), the fake "foo()" executes correctly but the process segmentation faults when it returns to the arbitrary interrupted code.
Am I clobbering some registers in the fake function call? Also what am I doing wrong in trying to pass 0xDEADBEEF to foo (right now it seems to be printing a garbage pointer)?
I would like to let a process be scheduled under the new Linux SCHED_DEADLINE scheduling policy. Meanwhile, this process has to create some worker threads do to some other work. However, when I called pthread_create after a successful call of sched_setattr(which is to set the process scheduling policy), I got an EAGAIN.
I know it might be a little strange to create a thread in a realtime process. Some problems such as "what scheduling policy of the new thread will be" may arise.
Despite of that , is there a way to create a new thread in a SCHED_DEADLINE process?
And how to define the scheduling policy of the new thread?
The code to reproduce my problem can be found at
https://github.com/lookflying/pthread_deadline/
When merging SCHED_DEADLINE, the kernel community explicitly discussed this topic in the list, and decided to not allow SCHED_DEADLINE tasks create other tasks (either by fork() or by pthread_create()).
Therefore, currently, there is no way of achieving such behavior. You have to create the tasks before setting the SCHED_DEADLINE priority.
Concerning the second question, unfortunately the glibc has not yet wrapped the sched_setattr() syscall (despite available since 4 years). Here is some code for creating a SCHED_DEADLINE task:
#define _GNU_SOURCE
#include <linux/kernel.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <time.h>
#include <linux/types.h>
#include <sched.h>
#include <linux/sched.h>
#include <sys/types.h>
#define SCHED_DEADLINE 6
/* __NR_sched_setattr number */
#ifndef __NR_sched_setattr
#ifdef __x86_64__
#define __NR_sched_setattr 314
#endif
#ifdef __i386__
#define __NR_sched_setattr 351
#endif
#ifdef __arm__
#define __NR_sched_setattr 380
#endif
#ifdef __aarch64__
#define __NR_sched_setattr 274
#endif
#endif
/* __NR_sched_getattr number */
#ifndef __NR_sched_getattr
#ifdef __x86_64__
#define __NR_sched_getattr 315
#endif
#ifdef __i386__
#define __NR_sched_getattr 352
#endif
#ifdef __arm__
#define __NR_sched_getattr 381
#endif
#ifdef __aarch64__
#define __NR_sched_getattr 275
#endif
#endif
struct sched_attr {
__u32 size;
__u32 sched_policy;
__u64 sched_flags;
/* SCHED_NORMAL, SCHED_BATCH */
__s32 sched_nice;
/* SCHED_FIFO, SCHED_RR */
__u32 sched_priority;
/* SCHED_DEADLINE */
__u64 sched_runtime;
__u64 sched_deadline;
__u64 sched_period;
};
int sched_setattr(pid_t pid,
const struct sched_attr *attr,
unsigned int flags)
{
return syscall(__NR_sched_setattr, pid, attr, flags);
}
int sched_getattr(pid_t pid,
struct sched_attr *attr,
unsigned int size,
unsigned int flags)
{
return syscall(__NR_sched_getattr, pid, attr, size, flags);
}
Then, in the task code:
struct sched_attr attr;
attr.size = sizeof(attr);
attr.sched_flags = 0;
attr.sched_nice = 0;
attr.sched_priority = 0;
/* This creates a 10ms/30ms reservation */
attr.sched_policy = SCHED_DEADLINE;
attr.sched_runtime = 10 * 1000 * 1000;
attr.sched_period = attr.sched_deadline = 30 * 1000 * 1000;
if (sched_setattr(0, &attr, flags) < 0) {
perror("sched_setattr()");
}
I think you will find that the default scheduling policy for a new pthread is PTHREAD_INHERIT_SCHED. To override this you need to pthread_attr_init() an explicit set of attributes, futz about with pthread_attr_setschedpolicy() and pthread_attr_setschedparam(), and then apply those attributes in pthread_create().
You could sched_getscheduler() and sched_getparam() before setting the process to SCHED_DEADLINE and feed those into the pthread_attr for use later.
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