blob: c15a72d5792a91028f2b8d7b576d6320934ea2ed (
plain) (
tree)
|
|
#include <errno.h>
#include <math.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <time.h>
#include <unistd.h>
#define FALSE 0
#define FILE_BUFF 4096
#define TRUE 1
struct NODE {
int inode;
long size;
struct NODE *next;
};
int main() {
/*
* totalsize takes in a list of filenames on its stdin and adds up the
* total size of those files (using stat) and prints the results as
* either bytes or kilobytes. It checks the UNITS environment variable to
* know whether to print in bytes or kilobytes. It checks the TSTALL
* environment variable for an integer to use as a delay before checking
* for files. It also checks the TMOM environment variable for the
* process ID of a parent process to send a SIGUSR1 signal to.
*
* totalsize builds a linked list out of the entered filenames and then
* goes through the unique, regular files and uses stat() to grab
* information about those files (inode, size).
*/
char *envar = NULL;
char filename[FILE_BUFF];
int inList = FALSE;
int sigPID;
int sleepTime;
long long byteSum = 0;
struct NODE *currentNode = NULL;
struct NODE *head = NULL;
struct NODE *newNode = NULL;
struct stat statData;
// Check TSTALL for time delay
errno = 0;
if ((envar = getenv("TSTALL")) != NULL
&& (sleepTime = strtol(envar, NULL, 10)) > 0
&& errno == 0) {
sleep(sleepTime);
}
// Take in standard input and build linked list.
while (scanf(" %s", filename) == 1) {
if (stat(filename, &statData) == 0 && S_ISREG(statData.st_mode)) {
inList = FALSE;
for (currentNode = head; currentNode != NULL; currentNode = currentNode->next) {
if (currentNode->inode == statData.st_ino) {
inList = TRUE;
}
}
if (!inList) {
newNode = (struct NODE *) malloc(sizeof(struct NODE));
newNode->inode = statData.st_ino;
newNode->size = statData.st_size;
newNode->next = head;
head = newNode;
}
}
// Check TSTALL for time delay
errno = 0;
if ((envar = getenv("TSTALL")) != NULL
&& (sleepTime = strtol(envar, NULL, 10)) > 0
&& errno == 0) {
sleep(sleepTime);
}
}
// Add up the number of bytes and print out the results
byteSum = 0;
for (currentNode = head; currentNode != NULL; currentNode = currentNode->next) {
byteSum += currentNode->size;
}
if ((envar = getenv("UNITS")) != NULL
&& (envar[0] == 'k' || envar[0] == 'K')
&& envar[1] == '\0') {
byteSum /= 1024;
printf("%lldkB\n", byteSum);
}
else {
printf("%lld\n", byteSum);
}
// Free list
while (currentNode != NULL) {
currentNode = head;
head = head->next;
free(currentNode);
}
errno = 0;
// Send SIGNUSR1 signal to calling parent
if ((envar = getenv("TMOM")) != NULL
&& (sigPID = strtol(envar, NULL, 10)) > 0
&& errno == 0) {
kill(sigPID, SIGUSR1);
}
exit(0);
}
|