Table of Contents

Systems Programming Journal

01/22/2014

On the first day of class we started our discussion with the topic of file operations. We were asked to create code that will sort the numbers that the program takes out of the text file. The code in its entirety can be found below.

#include <stdio.h>
#include <stdlib.h>

int main()
{
        FILE *fptr;
        int *data;
        int *data2;
        int i, count = 0, j;

        fptr = fopen("numbers.txt", "r");

        if(fptr == NULL)
        {
                fprintf(stdout, "Error opening file!\n");
                exit(1);
        }

        while(fscanf(fptr, "%d", &i) != EOF)
        {
                count++;
        }

        fclose(fptr);
        fptr = fopen("numbers.txt", "r");
        data = (int *)malloc(sizeof(int)*count);
        data2 = (int *)malloc(sizeof(int)*count);

        for(i = 0; i < count; i++)
        {
                fscanf(fptr, "%d", &j);
                *(data + i) = j;
                fprintf(stdout, "%d\n", *(data + i));
        }

        i = 0;
        while(i != count)
        {
                int numb =  *(data + i);
                for(int first = 1; first < count; first++)
                {
                        if(numb < *(data + first))
                        {
                                numb = *(data + first);
                        }
                }
                *(data2 + first) = numb;
                fprintf(stdout, "%d\n", *(data2 + i));
                i++;
        }

        fclose(fptr);

        return(0);
}

01/24/2014

The other day in class we created code to sort to output of our original code. The updated code is shown below.

#include <stdio.h>
#include <stdlib.h>

int main()
{
        FILE *fptr;
        int *data;
        int *data2;
        int i, count = 0, j, low = 9999, pos = -1;

        fptr = fopen("numbers.txt", "r");

        if(fptr == NULL)
        {
                fprintf(stdout, "Error opening file!\n");
                exit(1);
        }

        while(fscanf(fptr, "%d", &i) != EOF)
        {
                count++;
        }

        fclose(fptr);
        fptr = fopen("numbers.txt", "r");
        data = (int *)malloc(sizeof(int)*count);

        for(i = 0; i < count; i++)
        {
                fscanf(fptr, "%d", &j);
                *(data + i) = j;
                //fprintf(stdout, "%d\n", *(data + i));
        }

        fclose(fptr);

        for(i = 0; i < count; i++)
        {
                low = 9999;
                pos = -1;
                for(j = 0; j < (count - i); j++)
                {
                        if(*(data + j) < low)
                        {
                                low = *(data + j);
                                pos = j;
                        }
                }
                j = *(data + (count - i - 1));
                *(data + (count - i - 1)) = low;
                *(data + pos) = j;
        }

        if((fptr = fopen("out.txt", "w")) == NULL)
        {
                fprintf(stderr, "Error opening file for write\n");
                exit(2);
        }

        for(i = 0; i < count; i++)
        {
                fprintf(fptr, "%d, ", *(data+i));
        }

        fprintf(fptr, "END\n");
        fclose(fptr);
        return(0);
}

We also created new code based on our old code that will take in a specific file to grab the numbers from and will take in a specific file to serve as an output location after the numbers have been sorted, code shown below.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
        FILE *fptr;
        char filename[20];
        int *data;
        int *data2;
        int i, count = 0, j, low = 9999, pos = -1;

        if(argc == 1)
        {
                sprintf(filename, "data.txt");
        }
        else
        {
                sprintf(filename, "%s", argv[1]);
        }

        fptr = fopen(filename, "r");

        if(fptr == NULL)
        {
                fprintf(stdout, "Error opening file!\n");
                exit(1);
        }

        while(fscanf(fptr, "%d", &i) != EOF)
        {
                count++;
        }

        fclose(fptr);
        fptr = fopen(filename, "r");
        data = (int *)malloc(sizeof(int)*count);

        for(i = 0; i < count; i++)
        {
                fscanf(fptr, "%d", &j);
                *(data + i) = j;
                //fprintf(stdout, "%d\n", *(data + i));
        }

        fclose(fptr);

        for(i = 0; i < count; i++)
        {
                low = 9999;
                pos = -1;
                for(j = 0; j < (count - i); j++)
                {
                        if(*(data + j) < low)
                        {
                                low = *(data + j);
                                pos = j;
                        }
                }
                j = *(data + (count - i - 1));
                *(data + (count - i - 1)) = low;
                *(data + pos) = j;
        }

        if(argc > 2)
        {
                sprintf(filename, "%s", argv[2]);
        }
        else
        {
                sprintf(filename, "out.txt");
        }

        if((fptr = fopen(filename, "w")) == NULL)
        {
                fprintf(stderr, "Error opening file for write\n");
                exit(2);
        }
        for(i = 0; i < count; i++)
        {
                fprintf(fptr, "%d, ", *(data+i));
        }

        fprintf(fptr, "END\n");
        fclose(fptr);
        return(0);
}

01/28/2014

The code that we created today

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>

int main(int argc, char **argv)
{
        int c;
        int digit_optind = 0;

        while(1)
        {
                int this_option_optind = optind?optind:1;
                int option_index = 0;
                static struct option long_options[]={
                {"add", 1, 0, 0},
                {"append", 0, 0, 0},
                {"delete", 1, 0, 0},
                {"verbose", 0, 0, 0},
                {"create", 1, 0, 'c'},
                {"file", 1, 0, 0},
                {0, 0, 0, 0} };

                c = getopt_long(argc, argv, "abc:d:012", long_options, &option_index);
                if(c == -1)
                        break;
                switch(c)
                {
                        case 0:
                                printf("option %s", long_options[option_index].name);
                                if(optarg)
                                        printf("with arg %s", optarg);
                                printf("\n");
                        break;

                        case '0':

                        case '1':

                        case '2':
                                if(digit_optind !=0 && digit_optind != this_option_optind)
                                        printf("digits occur in two different argv elements \n");
                                        digit_optind = this_option_optind;
                                        printf("option %c\n",c);
                        break;

                        case 'a':
                                printf("option a\n");
                        break;

                        case 'b':
                                printf("option b\n");
                        break;

                        case 'c':
                                printf("option c with value '%s'\n", optarg);
                        break;

                        case 'd':
                                printf("option d with value '%s'\n",  optarg);
                        break;

                        case '?':
                        break;

                        default:
                                printf("?? getopt returned character code 0%o??\n", c);
                }
        }

        if(optind < argc)
        {
                printf("non-option ARGV elements: ");
                printf("%s ", argv[optind++]);
                printf("\n");
        }

        return(0);
}

01/30/2014

Started the group of project

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>

int main(int argc, char **argv)
{
        while(1)
        {
                Static struct option long_options[]={
                {"add animal", 1, 0, -a},
                {"add group", 1, 0, -g},
                {"verbose", 0, 0, -v},
                {"list", 0, 0, -l},
                {"help", 0, 0, -h},
                {"count", 0, 0, -c},
                {0, 0, 0, 0,} };
                

02/04/2014

Today was really cool because we created our own chmod program. I'm a little lost with what systems programming is but I think I'm starting to get it

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <errno.h>

int main(char argc, char **argv)
{
        if(argc != 3)
        {
                fprintf(stdout, "%s: missing operand\n", argv[0]);
                exit(1);
        }

        if(chmod(argv[2], strtol(argv[1], NULL, 8)) < 0)
        {
                fprintf(stderr, "%s: error in chmod(%s, %s) - %d(%s)\n",
                         argv[0], argv[2], argv[1], errno, strerror(errno));
                exit(1);
        }

        return(0);
}

02/06/2014

Today in class we created our own ls. It's really cool that we are seeing how the tools that we have used for almost a year now work.

#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>

void process(char *);

int main(int argc, char **argv)
{
        if(argc == 1)
                process(".");
        else
        {
                while(--argc)
                {
                        fprintf(stdout, "%s:\n", *++argv);
                        process(*argv);
                }
        }
        return(0);
}

void process(char *dirname)
{
        DIR *dirPtr;
        struct dirent *direntp;
        if((dirPtr = opendir(dirname)) == NULL)
                fprintf(stderr, "ls: cannot open %s\n", dirname);
        else
        {
                while((direntp = readdir(dirPtr)) != NULL)
                {
                        fprintf(stdout, "name: %s, reclen: %hu, type: %hhu\n", direntp->d_name, direntp->d_reclen, direntp->d_type);
                }
                closedir(dirPtr);
        }
}

02/11/2014

Today we worked on the spwd code from the book. We learned that for some reason it does not work on lab46 but will work if used through the system regularly.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>

ino_t get_inode(char *);
void printpathto(ino_t);
void inum_to_name(ino_t, char *, int);

int main()
{
        printpathto(get_inode("."));
        putchar('\n');
        return(0);
}

void printpathto(ino_t this_inode)
{
        ino_t my_inode;
        char its_name[BUFSIZ];

        if(get_inode("..") != this_inode)
        {
                chdir("..");
                inum_to_name(this_inode,its_name,BUFSIZ);
                my_inode = get_inode(".");
                printpathto(my_inode);
                printf("/%s", its_name);
        }
}

void inum_to_name(ino_t inode_to_find, char *namebuf, int buflen)
{
        DIR             *dir_ptr;
        struct dirent   *direntp;
        dir_ptr = opendir(".");
        if(dir_ptr == NULL)
        {
                perror(".");
                exit(1);
        }
        while((direntp = readdir(dir_ptr)) != NULL)
                if(direntp->d_ino == inode_to_find)
                {
                        strncpy(namebuf, direntp->d_name, buflen);
                        namebuf[buflen-1] = '\0';
                        closedir(dir_ptr);
                        return;
                }
        fprintf(stdout, "error looking for inum %d\n", inode_to_find);
        exit(1);
}

ino_t get_inode(char *fname)
{
        struct stat info;
        if(stat(fname, &info) == -1)
        {
                fprintf(stderr, "Cannot stat ");
                perror(fname);
                exit(1);
        }
        return info.st_ino;
}

02/12/2014

For fun I decided to do the code that is found in book. In the first chapter I created my own version of the more command.

#include <stdio.h>
#include <stdlib.h>
#define PAGELEN 24
#define LINELEN 512

void do_more(FILE *);
int see_more(FILE *);

int main(int ac, char *av[])
{
        FILE *fp;
        if(ac == 1)
                do_more(stdin);
        else
                while(--ac)
                {
                        if((fp = fopen(*++av, "r")) != NULL)
                        {
                                do_more(fp);
                                fclose(fp);
                        }
                        else
                                exit(1);
                }
        return(0);
}

void do_more(FILE *fp)
{
        char line[LINELEN];
        int num_of_lines = 0;
        int reply;
        FILE *fp_tty;

        fp_tty = fopen("/dev/tty", "r");
        if(fp_tty == NULL)
                exit(1);

        while(fgets(line, LINELEN, fp))
        {
                if(num_of_lines == PAGELEN)
                {
                        reply = see_more(fp_tty);
                        if(reply == 0)
                                break;
                        num_of_lines -= reply;
                }
                if(fputs(line, stdout) == EOF)
                        exit(1);
                num_of_lines++;
        }
}

int see_more(FILE *cmd)
{
        int c;
        printf("\033[7m more? \033[m");
        while((c=getc(cmd)) != EOF)
        {
                if(c == 'q')
                        return(0);
                if(c == ' ')
                        return(PAGELEN);
                if(c == '\n')
                        return(1);
        }
        return(0);
}

I really need to take the time to sit down and walk through the code I've written line by line to get a better understanding of what each program is doing.

02/13/2014

Today we worked on the matrix multiplier. I think I'm very close to figuring it out, but I can't seem to figure out the algorithm.

#include <stdio.h>

int main()
{
        int TableA[2][2] = {
                {1,2},
                {3,4},
        };

        int TableB[2][2] = {
                {4,3},
                {2,1},
        };

        int TableC[2][2];
        int a, b, c = 0;
        int x, y, z;
        for(a = 0; a < 2; a++)
        {
                x = 0;
                for(b = 0; b < 2; b++)
                {
                        y = TableA[a][b];
                        for(c = 0; c < 2; c++)
                        {
                                for(d = 0; d < 2; d++)
                                {
                                        z = TableB[c][d];
                                }

                        x = x + (y*z);
                }

        }
}

02/18/2014

Today I finished my Matrix multiplier. It turns out I was actually really close with my first attempt. I also added a lot of user input, so that it will work with any size.

#include <stdio.h>

int main()
{
        int a, b, c, d, e, f, g, h = 0;

        //Creating and assigning values for the first matrix
        fprintf(stdout, "What are the dimensions of the first matrix?\n");
        fscanf(stdin, "%d%d", &a, &b);
        int MatrixA[a][b];
        fprintf(stdout, "Enter the values for the matrix: ");
        for(e = 0; e < a; e++)
        {
                for(f = 0; f < b; f++)
                {
                        fscanf(stdin, "%d", &MatrixA[e][f]);
                }
        }

        //Creating and assign values for the second matrix
        fprintf(stdout, "What are the dimensions of the second matrix?\n");
        fscanf(stdin, "%d%d", &c, &d);
        int MatrixB[c][d];
        fprintf(stdout, "Enter the values for the matrix: ");
        for(g = 0; g < c; g++)
        {
                for(h = 0; h < d; h++)
                {
                        fscanf(stdin, "%d", &MatrixB[g][h]);
                }
        }

        int MatrixC[a][d];

        //Checks to see if the matrixes can be multiplied
        if(b != c)
        {
                fprintf(stdout, "Error Invalid Matrix Dimensions\n");
        }
        else
        {
                int i, x = 0;
                for(g = 0; g < a; g++)
                {
                        for(h = 0; h < d; h++)
                        {
                                for(i = 0; i < c; i++)
                                {
                                        x = x + MatrixA[g][i]*MatrixB[i][h];
                                }
                                MatrixC[g][h] = x;
                                x = 0;
                        }
                }

                //Display final Matrix
                for(g = 0; g < a; g++)
                {
                        for(h = 0; h < d; h++)
                        {
                                fprintf(stdout, " %d", MatrixC[g][h]);
                        }
                        fprintf(stdout, "\n");
                }

        }

        return(0);
}

02/19/2014

Today I did the chapter two book programs and created my own who and copy commands

who

#include <stdio.h>
#include <stdlib.h>
#include <utmp.h>
#include <fcntl.h>
#include <time.h>
#include <unistd.h>

//#define SHOWHOST

void showtime(long);
void show_info(struct utmp *);

int main()
{
        struct utmp     utbuf;
        int             utmpfd;
        //int           reclen = sizeof(current_record);

        if((utmpfd = open(UTMP_FILE, O_RDONLY) == -1))
        {
                perror(UTMP_FILE);
                exit(1);
        }
        while(read(utmpfd, &utbuf, sizeof(utbuf)) == sizeof(utbuf))
                show_info(&utbuf);
        close(utmpfd);
        return(0);
}

void show_info(struct utmp *utbufp)
{
        if(utbufp->ut_type != USER_PROCESS)
                return;
        printf("%-8.8s", utbufp->ut_name);
        printf(" ");
        printf("%-8.8s", utbufp->ut_line);
        printf(" ");
        showtime(utbufp->ut_time);

#ifdef  SHOWHOST
        if(utbufp->ut_host[0] != '\0'))
                printf(" (%s)", utbufp->ut_host);
#endif
        printf("\n");
}

void showtime(long timeval)
{
        char *cp;
        cp = ctime(&timeval);

        printf("%12.12s", cp+4);
}

For some reason this code compiles but it does not do what it is supposed to do when it is run

Copy

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

#define BUFFERSIZE      4096
#define COPYMODE        0644

void oops(char *, char *);

void main(int ac, char *av[])
{
        int     in_fd, out_fd, n_chars;
        char    buf[BUFFERSIZE];

        if(ac != 3)
        {
                fprintf(stderr, "usage: %s source destination\n", *av);
        }

        if((in_fd = open(av[1], O_RDONLY)) == -1)
                oops("Cannot open ", av[1]);

        if((out_fd = creat(av[2], COPYMODE)) == -1)
                oops("Cannot creat ", av[2]);

        while((n_chars = read(in_fd, buf, BUFFERSIZE)) > 0)
                if(write(out_fd, buf, n_chars) != n_chars)
                        oops("Write error to ", av[2]);

        if(n_chars == -1)
                oops("Read error from ", av[1]);

        if(close(in_fd) == -1 || close(out_fd) == -1)
                oops("Error closing files", "");
}

void oops(char *s1, char *s2)
{
        fprintf(stderr, "Error: %s ", s1);
        perror(s2);
        exit(1);
}

This code works fine

This is still really cool. The fact that I am seeing that the commands that I use everyday are not even a lot of code, is fascinating. Something that people use everyday are smaller than most programs that I write.

02/25/2014

Today we wrote the write command from the book

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

int main(int argc, char **argv)
{
        int fd;
        char buf[BUFSIZ];

        if(argc != 2)
        {
                fprintf(stderr, "usage: %sttyname\n", argv[0]);
                exit(1);
        }

        fd = open(argv[1], O_WRONLY);
        if(fd == -1)
        {
                perror(argv[1]);
                exit(1);
        }
        while(fgets(buf, BUFSIZ, stdin) != NULL)
        {
                if(write(fd, buf, strlen(buf)) == -1)
                        break;
        }

        close(fd);
        return(0);
}

I think I am starting to understand how these commands work, I still need to sit down and dissect them

02/27/2014

Today in class we went over the chapter 5 code examples and I also worked on the groupof program for a little bit

setecho.c

#include <stdio.h>
#include <stdlib.h>
#include <termios.h>

#define oops(s,x) {perror(s); exit(x);}

main(int ac, char *av[])
{
        struct termios info;

        if(ac == 1)
                exit(0);
        if(tcgetattr(0, &info) == -1)
                oops("tcgetattr", 1);
        if(av[1][0] == 'y')
                info.c_lflag |= ECHO;
        else
                info.c_lflag &= ~ECHO;
        if(tcsetattr(0, TCSANOW, &info) == -1)
                oops("tcgetattr", 2);
}

echostate.c

#include <stdio.h>
#include <termios.h>
#include <stdlib.h>

main()
{
        struct termios info;
        int rv;

        rv = tcgetattr(0, &info);

        if(rv == -1)
        {
                perror("tcgetattr");
                exit(1);
        }

        printf("info.c_lfag is: %X\n", info.c_lflag);
        printf("ICANON is: %X\n", ICANON);

        if(info.c_lflag & ICANON)
                printf(" ICANON is on, since its bit is 1\n");
        else
                printf(" ICANON is OFF, since its bit is 0\n");
}

03/04/2014

Today we created the playagain3 program from chapter 6

#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>
#define ASK "Do you want another transaction?"
#define TRIES 3
#define SLEEPTIME 2
#define BEEP putchar('\a')

int main()
{
        int response;
        tty_mode(0);
        set_cr_noecho_mode();
        set_nodedelay_mode();
        response = get_response(ASK, TRIES);
        tty_mode(1);
        return(response);
}

int get_response(char *question, int maxtries)
{
        int input;
        printf("%s(y/n)?", question);
        fflush(stdout);
        while(1)
        {
                sleep(SLEEPTIME);
                input = tolower(get_ok_char());
                if(input == 'y')
                        printf("Yes\n");
                        return(0);
                if(input == 'n')
                        printf("No\n");
                        return(1);
                if(maxtries-- == 0)
                        printf("Timeout\n");
                        return(2);
                BEEP;
        }
}

int get_ok_char()
{
        int c;
        while((c = getchar()) != EOF && strchr("yYnN", c) == NULL)
                ;
                return(c);
}

void set_cr_noecho_mode()
{
        struct termios ttystate;

        tcgetattr(0, &ttystate);
        ttystate.c_lflag &= ~ICANON;
        ttystate.c_lflag &= ~ECHO;
        ttystate.c_cc[VMIN] = 1;
        tcsetattr(0, ICANON, &ttystate);
}

void set_nodedelay_mode()
{
        int termflags;
        termflags - fcntl(0, F_GETFL);
        printf("termflags: %X, O_NDELAY: %X\n", termflags, O_NDELAY);
        termflags |= O_NDELAY;
        fcntl(0, F_SETFL, termflags);
}

tty_mode(int how)
{
        static struct  termios original_mode;
        static int original_flags;
        if(how == 0)
        {
                tcgetattr(0, &original_mode);
                original_flags = fcntl(0, F_GETFL);
        }
        else
        {
                tcsetattr(0, TCSANOW, &original_mode);
                fcntl(0, F_SETFL, original_flags);
        }
}

03/05/2014

Created the completed ls program from the book

#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>

void do_ls(char[]);
void dostat(char *);
void show_file_info(char *, struct stat *);
void mode_to_letters(int , char []);
char *uid_to_name(uid_t);
char *gid_to_name(gid_t);

int main(int ac, char *av[])
{
        if(ac == 1)
                do_ls(".");
        else
        {
                while(--ac)
                {
                        fprintf(stdout, "%s:\n", *++av);
                        do_ls(*av);
                }
        }
        return(0);
}

void do_ls(char dirname[])
{
        DIR *dirPtr;
        struct dirent *direntp;
        if((dirPtr = opendir(dirname)) == NULL)
                fprintf(stderr, "ls: cannot open %s\n", dirname);
        else
        {
                while((direntp = readdir(dirPtr)) != NULL)
                {
                        dostat(direntp->d_name);
                }
                closedir(dirPtr);
        }
}

void dostat(char *filename)
{
        struct stat info;

        if(stat(filename, &info) == -1)
                perror(filename);
        else
                show_file_info(filename, &info);
}

void show_file_info(char *filename, struct stat *info_p)
{
        char *uid_to_name(), *ctime(), *gid_to_name(), *filemode();
        void mode_to_letters();
        char modestr[11];

        mode_to_letters(info_p->st_mode, modestr);

        printf("%s ", modestr);
        printf("%4d ", (int) info_p->st_nlink);
        printf("%-8s ", uid_to_name(info_p->st_uid));
        printf("%-8s ", gid_to_name(info_p->st_gid));
        printf("%8ld ", (long)info_p->st_size);
        printf(".12s ", 4+ctime(&info_p->st_mtime));
        printf("%s\n", filename);
}

void mode_to_letters(int mode, char str[])
{
        strcpy(str, "----------");

        if( S_ISDIR(mode)) str[0] = 'd';
        if( S_ISCHR(mode)) str[0] = 'c';
        if( S_ISBLK(mode)) str[0] = 'b';

        if(mode & S_IRUSR) str[1] = 'r';
        if(mode & S_IWUSR) str[2] = 'w';
        if(mode & S_IXUSR) str[3] = 'x';

        if(mode & S_IRGRP) str[4] = 'r';
        if(mode & S_IWGRP) str[5] = 'w';
        if(mode & S_IXGRP) str[6] = 'x';

        if(mode & S_IROTH) str[7] = 'r';
        if(mode & S_IWOTH) str[8] = 'w';
        if(mode & S_IXOTH) str[9] = 'x';
}

#include <pwd.h>

char *uid_to_name(uid_t uid)
{
        struct passwd *getpwuid(), *pw_ptr;
        static char numstr[10];

        if((pw_ptr = getpwuid(uid)) == NULL)
        {
                sprintf(numstr, "%d", uid);
                return(numstr);
        }
        else
                return(pw_ptr->pw_name);
}

#include <grp.h>

char *gid_to_name(gid_t gid)
{
        struct group *getgrgid(), *grp_ptr;
        static char numstr[10];

        if((grp_ptr = getgrgid(gid)) == NULL)
        {
                sprintf(numstr, "%d", gid);
                return(numstr);
        }
        else
                return(grp_ptr->gr_name);
}

03/11/2014

Today we created a signal program from chapter six

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>

void thing1();
void thing2();
void thing3();

int main()
{
        signal(SIGQUIT, thing1);
        signal(SIGINT, thing2);
        sleep(10);
        fprintf(stdout, "you can't stop me!\n");
        signal(SIGINT, thing3);
        while(1)
        {
                sleep(1);
                fprintf(stdout, "loop\n");
        }
        return(0);
}

void thing1()
{
        fprintf(stdout, "QUIT signal given, exiting...\n");
        exit(0);
}

void thing2()
{
        fprintf(stdout, "HAHA!\n");
}

void thing3()
{
        fprintf(stdout, "RAWR!\n");
}

I like this program because it is the first time I am seeing something new that systems programming can do. I've created programs that simulate commands, but I knew about those commands already.

I also went back and read chapter 4 of the book and had a nice refresher on how UNIX trees work. One thing that was new that I thought was interesting is the of inodes. This put a whole different spin on directories and files in UNIX. Even though we created in class I will included the spwd code from the chapter.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>

ino_t get_inode(char *);
void printpathto(ino_t);
void inum_to_name(ino_t, char *, int);

int main()
{
        printpathto(get_inode("."));
        putchar('\n');
        return(0);
}

void printpathto(ino_t this_inode)
{
        ino_t my_inode;
        char its_name[BUFSIZ];

        if(get_inode("..") != this_inode)
        {
                chdir("..");
                inum_to_name(this_inode,its_name,BUFSIZ);
                my_inode = get_inode(".");
                printpathto(my_inode);
                printf("/%s", its_name);
        }
}

void inum_to_name(ino_t inode_to_find, char *namebuf, int buflen)
{
        DIR             *dir_ptr;
        struct dirent   *direntp;
        dir_ptr = opendir(".");
        if(dir_ptr == NULL)
        {
                perror(".");
                exit(1);
        }
        while((direntp = readdir(dir_ptr)) != NULL)
                if(direntp->d_ino == inode_to_find)
                {
                        strncpy(namebuf, direntp->d_name, buflen);
                        namebuf[buflen-1] = '\0';
                        closedir(dir_ptr);
                        return;
                }
        fprintf(stdout, "error looking for inum %d\n", inode_to_find);
        exit(1);
}

ino_t get_inode(char *fname)
{
        struct stat info;
        if(stat(fname, &info) == -1)
        {
                fprintf(stderr, "Cannot stat ");
                perror(fname);
                exit(1);
        }
        return info.st_ino;
}

03/18/2014

Today we discussed the concept of processes, including the use of the fork command to lead to the creation of children processes.

fork.c

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>

int main()
{
        pid_t me, you, parent;
        me = getpid();
        parent = getppid();
        printf("Run top in another terminal and hit ENTER when ready");
        fgetc(stdin);
        printf("PID of me: %d\n", me);
        you = fork();
        if(me == getpid())
        {
                printf("Parent PID: %d\n", me);
                printf("Child PID: %d\n", you);
                printf("PPID: %d\n", parent);
                sleep(5);
        }
        else
        {
                //signal(SIGCHLD, SIG_IGN);
                sleep(10);
                me = getpid();
                parent = getppid();
                printf("New Parent PID: %d\n", me);
                printf("New Child PID: %d\n", you);
                printf("New PPID: %d\n", parent);
                sleep(5);
                printf("Child is done waitng\n");
        }
        //sleep(8);
        return(0);
}

fork2.c

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>

int main(int argc, char **argv)
{
        pid_t me, you;
        char input, *fname;
        FILE *fptr;

        int i, j, data[100][2], rank = 0, numproc = 0;
        int pidlist[5];

        for(i=0; i<100; i++)
        {
                data[i][0] = i * i;
        }

        pidlist[0] = getpid();
        for(i = 1; i <= 4; i++)
        {
                if(pidlist[0] == getpid())
                {
                        rank = rank + 1;
                        pidlist[i] = fork();
                }
        }

        if (getpid() == pidlist[0])
        {
                printf("I am PID %i, my child processes are: ", pidlist[0]);
                for(i=1; i<=4; i++)
                        printf("%i ", pidlist[i]);
                printf("\n");

                // could put code to wait for child process termination here
        }
        else
        {
                me = getpid();
                printf("I am child %i (pid %i), so I will process ", rank, me);
                printf("elements %i-%i ...\n", ((rank*25)-25), ((((rank+1)*25)-1)-25));
                for(i = ((rank*25)-25); i < (((rank+1)*25)-25); i++)
                        data[i][1] = data[i][0] * rank;

                fname = (char *) malloc (sizeof(char) * 8);
                sprintf(fname, "rank%i", rank);
                fptr = fopen(fname, "w");

                fprintf(fptr, "%i\n", (rank*25)-25);
                fprintf(fptr, "%i\n", (((rank+1)*25)-1)-25);
                for(i = rank*25-25; i < ((rank+1)*25)-25; i++)
                        fprintf(fptr, "%i\t%i\n", data[i][0], data[i][1]);

                fclose(fptr);
        }

        return(0);
}

I also read the chapter 6 material. I feel really good with signals but I need to get a better understanding of what tty is and how to use it.

03/20/2014

Today we kept working with different process examples.

First we looked at fork3.c, in which we utilized the wait function

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>

int main(int argc, char **argv)
{
        pid_t me, you;
        char input, *fname;
        FILE *fptr;

        int i, j, data[100][2], rank = 0, numproc = 0;
        int pidlist[5];

        for(i=0; i<100; i++)
        {
                data[i][0] = i * i;
        }

        pidlist[0] = getpid();
        for(i = 1; i <= 4; i++)
        {
                if(pidlist[0] == getpid())
                {
                        rank = rank + 1;
                        pidlist[i] = fork();
                }
        }

        if (getpid() == pidlist[0])
        {
                printf("I am PID %i, my child processes are: ", pidlist[0]);
                for(i=1; i<=4; i++)
                        printf("%i ", pidlist[i]);
                printf("\n");

                // could put code to wait for child process termination here
                for(i = 0; i < rank; i++)
                {
                        you = wait(&j);
                        printf("child PID %d has finished with status %d\n", you, j);
                }
        }
        else
        {
                me = getpid();
                printf("I am child %i (pid %i), so I will process ", rank, me);
                printf("elements %i-%i ...\n", ((rank*25)-25), ((((rank+1)*25)-1)-25));
                for(i = ((rank*25)-25); i < (((rank+1)*25)-25); i++)
                        data[i][1] = data[i][0] * rank;

                fname = (char *) malloc (sizeof(char) * 8);
                sprintf(fname, "rank%i", rank);
                fptr = fopen(fname, "w");

                fprintf(fptr, "%i\n", (rank*25)-25);
                fprintf(fptr, "%i\n", (((rank+1)*25)-1)-25);
                for(i = rank*25-25; i < ((rank+1)*25)-25; i++)
                        fprintf(fptr, "%i\t%i\n", data[i][0], data[i][1]);

                fclose(fptr);
                sleep(rank * 2 + 60);
        }

        return(0);
}

Next we explored the use of exec. I really liked this one because it replaces processes with whatever you want to do instead.

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>

int main(int argc, char **argv)
{
        pid_t me, you;
        char input, *fname;
        FILE *fptr;

        int i, j, data[100][2], rank = 0, numproc = 0;
        int pidlist[5];

        for(i=0; i<100; i++)
        {
                data[i][0] = i * i;
        }

        pidlist[0] = getpid();
        for(i = 1; i <= 4; i++)
        {
                if(pidlist[0] == getpid())
                {
                        rank = rank + 1;
                        pidlist[i] = fork();
                }
        }

        if (getpid() == pidlist[0])
        {
                printf("I am PID %i, my child processes are: ", pidlist[0]);
                for(i=1; i<=4; i++)
                        printf("%i ", pidlist[i]);
                printf("\n");

                // could put code to wait for child process termination here
                for(i = 0; i < rank; i++)
                {
                        you = wait(&j);
                        printf("child PID %d has finished with status %d\n", you, j);
                }
        }
        else
        {
                if(rank == 2)
                        execl("/bin/ls", "ls", "-l", NULL);
                me = getpid();
                printf("I am child %i (pid %i), so I will process ", rank, me);
                printf("elements %i-%i ...\n", ((rank*25)-25), ((((rank+1)*25)-1)-25));
                for(i = ((rank*25)-25); i < (((rank+1)*25)-25); i++)
                        data[i][1] = data[i][0] * rank;

                fname = (char *) malloc (sizeof(char) * 8);
                sprintf(fname, "rank%i", rank);
                fptr = fopen(fname, "w");

                fprintf(fptr, "%i\n", (rank*25)-25);
                fprintf(fptr, "%i\n", (((rank+1)*25)-1)-25);
                for(i = rank*25-25; i < ((rank+1)*25)-25; i++)
                        fprintf(fptr, "%i\t%i\n", data[i][0], data[i][1]);

                fclose(fptr);
                sleep(rank * 2 + 60);
        }

        return(0);
}

03/25/2014

Today we didn't have a standard class due to the amount of people that came. I did however work through the chapter 8 material.

exec1.c

main()
{
        char *arglist[3];
        arglist[0] = "ls";
        arglist[1] = "-l";
        arglist[2] = 0;
        printf("* * *About to esec ls -l\n");
        execvp("ls", arglist);
        printf("* * *ls is done. Bye\n");
}

This program taught me a couple things. First, the whole idea that when a new process is started the previous process vanishes from existence, I remember Matt saying that but now it has really been inserted into my mind. Second, this program does not have and “include” statements, I did not even know that this was possible and I will have to ask Matt about this.

psh1.c

#include <stdio.h>
#include <signal.h>
#include <string.h>

#define MAXARGS 20
#define ARGLEN  100

int main()
{
        char *arglist[MAXARGS + 1];
        int numargs;
        char argbuf[ARGLEN];
        char *makestring();
        numargs = 0;
        while(numargs < MAXARGS)
        {
                printf("Arg[%d]? ", numargs);
                if(fgets(argbuf, ARGLEN, stdin) && *argbuf != '\n')
                        arglist[numargs++] = makestring(argbuf);
                else
                {
                        if(numargs > 0)
                        {
                                arglist[numargs] = NULL;
                                execute(arglist);
                                numargs = 0;
                        }
                }
        }
        return(0);
}

int execute(char *arglist[])
{
        execvp(arglist[0], arglist);
        perror("execvp failed");
        exit(1);
}

char *makestring(char *buf)
{
        char *cp, *malloc();

        buf[strlen(buf)-1] = '\0';
        cp = malloc(strlen(buf)+1);
        if(cp == NULL)
        {
                fprintf(stderr, "No memory\n");
                exit(1);
        }
        strcpy(cp, buf);
        return(cp);
}

waitdemo1.c

#include <stdio.h>

#define DELAY 2

main()
{
        int newpid;

        void child_code(), parent_code();

        printf("before: mypid is %d\n", getpid());

        if((newpid = fork()) == -1)
                perror("fork");
        else if(newpid == 0)
                child_code(DELAY);
        else
                parent_code(newpid);
}

void child_code(int delay)
{
        printf("child %d here. will sleep for %d seconds\n", getpid(), delay);
        sleep(delay);
        printf("child done. about to exit\n");
        exit(17);
}

void parent_code(int childpid)
{
        int wait_rv;
        wait_rv = wait(NULL);
        printf("done waiting for %d. wait returned: %d\n", childpid, wait_rv);
}

I think I fully understand this code but I need to talk to Matt and make sure what I think is happening is actually what is happening

waitdemo2.c

#include <stdio.h>

#define DELAY 5

main()
{
        int newpid;

        void child_code(), parent_code();

        printf("before: mypid is %d\n", getpid());

        if((newpid = fork()) == -1)
                perror("fork");
        else if(newpid == 0)
                child_code(DELAY);
        else
                parent_code(newpid);
}

void child_code(int delay)
{
        printf("child %d here. will sleep for %d seconds\n", getpid(), delay);
        sleep(delay);
        printf("child done. about to exit\n");
        exit(17);
}

void parent_code(int childpid)
{
        int wait_rv;
        int child_status;
        int high_8, low_7, bit_7;

        wait_rv = wait(&child_status);
        printf("done waiting for %d. wait returned: %d\n", childpid, wait_rv);

        high_8 = child_status >> 8;
        low_7 = child_status & 0X7F;
        bit_7 = child_status & 0X80;
        printf("status: exit=%d, sig=%d, core=%d\n", high_8, low_7, bit_7);
}

This code is pretty much what we did in class, just not nearly as in depth

psh2.c

#include <stdio.h>
#include <signal.h>
#include <string.h>

#define MAXARGS 20
#define ARGLEN  100

int main()
{
        char *arglist[MAXARGS + 1];
        int numargs;
        char argbuf[ARGLEN];
        char *makestring();
        numargs = 0;
        while(numargs < MAXARGS)
        {
                printf("Arg[%d]? ", numargs);
                if(fgets(argbuf, ARGLEN, stdin) && *argbuf != '\n')
                        arglist[numargs++] = makestring(argbuf);
                else
                {
                        if(numargs > 0)
                        {
                                arglist[numargs] = NULL;
                                execute(arglist);
                                numargs = 0;
                        }
                }
        }
        return(0);
}

execute(char *arglist[])
{
        int pid, exitstatus;

        pid = fork();
        switch(pid)
        {
                case -1:
                        perror("fork failed");
                        exit(1);
                case 0:
                        execvp(arglist[0], arglist);
                        perror("execvp failed");
                        exit(1);
                default:
                        while(wait(&exitstatus) != pid)
                                ;//ask matt about this
                        printf("child exited with status %d, %d\n", exitstatus >> 8, exitstatus&0377);
        }
}

char *makestring(char *buf)
{
        char *cp, *malloc();

        buf[strlen(buf)-1] = '\0';
        cp = malloc(strlen(buf)+1);
        if(cp == NULL)
        {
                fprintf(stderr, "No memory\n");
                exit(1);
        }
        strcpy(cp, buf);
        return(cp);
}

For some reason I cannot run the psh1 from earlier like the book can, do not know if I am just entering it wrong or if I screwed up some where.