diff options
Diffstat (limited to 'pgm3/totalsize.c')
-rw-r--r-- | pgm3/totalsize.c | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/pgm3/totalsize.c b/pgm3/totalsize.c new file mode 100644 index 0000000..c15a72d --- /dev/null +++ b/pgm3/totalsize.c @@ -0,0 +1,126 @@ +#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); +} |