/******************************************************* free.c CMSC-421 Fall 2004 HW 1 Spencer Shimko *********************************************************/ #include #include #include #include #include #include #define MEMFILE "/proc/meminfo" #define CMDOPTS "bkmots:V" /* The description displayed by this usage function is copied verbatim from "free -h" to be as accurate as possible */ void show_usage(const char *self) { fprintf(stderr, "usage: %s [-b|-k|-m] [-o] [-t] [-s delay] [-V]\n", self); fprintf(stderr,"\t-b,-k,-m show output in bytes, KB, or MB\n"); fprintf(stderr,"\t-o use old format (no -/+buffers/cache line)\n"); fprintf(stderr,"\t-t display total for RAM + swap\n"); fprintf(stderr,"\t-s update every [delay] seconds\n"); fprintf(stderr,"\t-V display version information and exit\n"); } /* Begin main */ int main( int argc, char **argv ){ char arg; FILE *memfile; unsigned long total, used, free, shared, buffers, cached, bufncache, swap_total, swap_used, swap_free; int delay = 0; /* no delay by default */ int f_old = 0, f_ttl = 0; /* no flags by default */ int posshift = 10; /* default output is in KB */ /* parse command line */ while ( ( arg = getopt ( argc, argv, CMDOPTS ) ) != EOF ) { switch ( arg ){ case 'b': posshift = 0; break; case 'k': posshift = 10; break; case 'm': posshift = 20; break; case 'o': f_old = 1; break; case 't': f_ttl = 1; break; case 's': delay = 1000000 * atof ( optarg ); break; case 'V': printf( "Spencer's free implementation v0.1\n" ); return 0; default: show_usage ( argv[0] ); return 1; } } if ( optind < argc ) { show_usage ( argv[0] ); return 1; } do { memfile = fopen( MEMFILE, "r"); /* open a text file for reading */ if ( memfile == NULL ) { fprintf(stderr, "Fatal Error: can't open %s\nIs /proc filesystem mounted?\n", MEMFILE ); return 1; } else { fscanf(memfile, " total: used: free: shared: buffers: cached:\nMem:%lu%lu%lu%lu%lu%lu\nSwap:%lu%lu%lu", &total, &used, &free,&shared, &buffers, &cached, &swap_total, &swap_used, &swap_free ); fclose(memfile); printf(" total used free shared buffers cached\n"); /* print formatting strings are all altered forms of those found in procps * they are not copied */ printf("%-7s %10lu %10lu %10lu %10lu %10lu %10lu\n", "Mem:", total >> posshift, used >> posshift, free >> posshift, shared >> posshift, buffers >> posshift, cached >> posshift); if ( ! f_old ) { bufncache = buffers + cached; printf( "-/+ buffers/cache: %10lu %10lu\n", (used - bufncache) >> posshift, (free + bufncache) >> posshift); } /* swap info is printed regardless of flags */ printf( "%-7s %10lu %10lu %10lu\n", "Swap:", swap_total >> posshift, swap_used >> posshift, swap_free >> posshift); if ( f_ttl ){ printf ( "%-7s %10lu %10lu %10lu\n", "Total:", ( total + swap_total ) >> posshift, ( used + swap_used ) >> posshift, ( free + swap_free ) >> posshift ); } if ( delay ){ /* fputc('\n', stdout); fflush(stdout); if ( usleep(delay) == -1 ){ fprintf(stderr, "Error processing delay!\n"); return 1; } */ } } } while ( delay ); return 0; }