Þæs Ofereode - free/main.c
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <libgen.h>
#include <math.h>
#include <mach/mach.h>
#include <sys/sysctl.h>
#include <string.h>
unsigned int pageSize;
mach_port_t hostPort;
char bn[BUFSIZ],kflag=0,bflag=0,mflag=0,pflag=0,vflag=0;
useconds_t delay=0;
double inDelay=0.0;
extern int errno;
void displayOutput(void);
void displayBanner(void);
void usage(void);
void version(void);
int main (int argc, const char * argv[])
{
char oc;
pageSize=4096; //seems to be the default page size - see e.g. vm_stat(1)
strncpy(bn,basename(argv[0]),BUFSIZ);
// parse argv in here....
while((oc=getopt(argc,argv,"bkmps:vV"))!=-1)
{
switch(oc)
{
case 'b':
bflag=1;
break;
case 'k':
kflag=1;
break;
case 'm':
mflag=1;
break;
case 'p':
pflag=1;
break;
case 's':
if((sscanf(optarg,"%lf",&inDelay))==0)
{
usage();
exit(EXIT_FAILURE);
}
break;
case 'v':
vflag=1;
break;
case 'V':
version();
exit(EXIT_SUCCESS);
break;
case '?':
default:
usage();
exit(EXIT_FAILURE);
}
}
if ((bflag && kflag) || (bflag && mflag) || (kflag && mflag) || (bflag && pflag) || (kflag && pflag) || (mflag && pflag))
{
usage();
exit(EXIT_FAILURE);
}
if(bflag==0 && kflag==0 && mflag==0 && pflag==0) kflag=1;
// .....
hostPort=mach_host_self(); // connect to our own mach port, I think.
// check the page size
if(host_page_size(hostPort,&pageSize)!=KERN_SUCCESS)
{
fprintf(stderr,"%s: could not get page size: using default 4096\n",bn);
pageSize=4096;
}
displayBanner();
if(inDelay==0.0)
{
displayOutput();
}
else
{
delay=(useconds_t)floor(inDelay*1000000.0);
while(1)
{
displayOutput();
usleep(delay);
if(vflag)
{
printf("\n");
displayBanner();
}
}
}
exit(EXIT_SUCCESS);
}
void displayBanner(void)
{
printf("%16s%12s%12s\n","total","used","free");
return;
}
void displayOutput(void)
{
unsigned int count=HOST_VM_INFO_COUNT;
unsigned int totalMemory,usedMemory,freeMemory,denominator;
vm_statistics_data_t vms; //eww...VMS
struct xsw_usage xsu;
size_t xsusiz=sizeof(xsu);
int mib[2]={CTL_VM,VM_SWAPUSAGE};
if(bflag) denominator=1;
if(kflag) denominator=1024;
if(mflag) denominator=1024*1024;
if(pflag) denominator=pageSize; //how stupid is that?
if(host_statistics(hostPort, HOST_VM_INFO, (host_info_t)&vms,&count) != KERN_SUCCESS)
{
fprintf(stderr,"%s: could not get VM stats: aborting\n",bn);
exit(EXIT_FAILURE);
}
usedMemory=(vms.active_count+vms.inactive_count+vms.wire_count)*pageSize;
freeMemory=vms.free_count*pageSize;
totalMemory=usedMemory+freeMemory;
printf("Mem:%12u%12u%12u\n",totalMemory/denominator,usedMemory/denominator,freeMemory/denominator);
errno=0;
if(sysctl(mib,2,&xsu,&xsusiz,NULL,0)==-1)
{
fprintf(stderr,"%s: could not get swap usage: %s\n",bn,strerror(errno));
exit(EXIT_FAILURE);
}
printf("Swap:%11llu%12llu%12llu\n",xsu.xsu_total/denominator,xsu.xsu_used/denominator,xsu.xsu_avail/denominator);
if(vflag)
{
printf("pageins: %7u\tpageouts:%7u\n",vms.pageins,vms.pageouts);
}
return;
}
void usage(void)
{
printf("%s [-b|-k|-m|-p] [-s delay] [-vV]\n\n",bn);
printf("display free memory on the system.\n");
printf("-b\tdisplay output in bytes\n");
printf("-k\tdisplay output in kilobytes\n");
printf("-m\tdisplay output in megabytes\n");
printf("-p\tdisplay output in #pages\n");
printf("-s delay\tprint output every delay seconds\n");
printf("-v\tinclude pagein/pageout statistics\n");
printf("-V\tprint version information\n");
}
void version(void)
{
printf("Darwin free version 1.0\n");
printf("By Graham J. Lee\n");
}
Raw Source