User Tools

Site Tools


Sidebar

os_cp:open_fork:solutions

Exercise 1

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
int main(int argc, char *argv[]){
    int fd = open("/tmp/z", O_RDONLY);
    if(fd == -1){
        perror(NULL);
        return 1;
    }
    char buffer[256];
    while(1){
        int length = read(fd, buffer, 256);
        if(length == -1){
            perror(NULL);
            return 1;
        }
        if(length == 0)
            break;
        write(STDOUT_FILENO, buffer, length);
    }
    close(fd);
    return 0;
}

Exercise 2

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
int main(int argc, char *argv[]){
    int fd = open(argv[1], O_RDONLY);
    if(fd == -1){
        perror(NULL);
        return 1;
    }
    char buffer[256];
    while(1){
        int length = read(fd, buffer, 256);
        if(length == -1){
            perror(NULL);
            return 1;
        }
        if(length == 0)
            break;
        write(STDOUT_FILENO, buffer, length);
    }
    close(fd);
    return 0;
}

Exercise 3

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main(int argc, char *argv[]){
    int fd = open(argv[1], O_RDONLY);
    if(fd == -1){
        perror(NULL);
        return 1;
    }
    int num = 1;
    int printNumber = 1;
    while(1){
        char c;
        int count = read(fd, &c, 1);
        if(count == -1){
            perror(NULL);
            return 1;
        }
        if(count == 0)
            break;
        if(printNumber){
            char numBuf[16];
            sprintf(numBuf, "%5d ", num++);
            write(STDOUT_FILENO, numBuf, strlen(numBuf));
            printNumber=0;
        }
        write(STDOUT_FILENO, &c, 1);
        if(c == '\n')
            printNumber=1;
    }
    close(fd);
    return 0;
}

The program above is intentionally made simple rather than efficient; the program below is more efficient, but has a few more lines.

Exercise 4

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
 
#define CHECK(result, textOnFail) \
if(result == -1){                 \
    perror(textOnFail);           \
    return 1;                     \
}
int main(int argc, char *argv[]){
    if(argc < 3){
        write(STDERR_FILENO, "Not enough arguments\n", 21);
        return 1;
    }
    int file1 = open(argv[1], O_RDONLY);
    CHECK(file1, argv[1]);
    int file2 = open(argv[2], O_RDONLY);
    CHECK(file2, argv[2]);
    while(1){
        char buf1[256], buf2[256];
        int len1 = read(file1, buf1, 256);
        CHECK(len1, argv[1]);
        int len2 = read(file2, buf2, 256);
        CHECK(len2, argv[2]);
        if(len1 != len2)
            break;
        if(len1 == 0){
            write(STDOUT_FILENO, "Files have the same contents\n", 29);
            return 0;
        }
        if(memcmp(buf1, buf2, len1))
            break;
    }
    write(STDOUT_FILENO, "Files differ\n", 13);
    return 0;
}

Exercise 5

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
 
int main(int argc, char *argv[]){
    ++argv; --argc; // get rid of program name; simplifies array indexes
    int *file = malloc(sizeof(int) * argc);
    int running = 0;
    for(int i = 0; i < argc; ++i){
        file[i] = open(argv[i], O_RDONLY);
        if(file[i] == -1)
            perror(argv[i]);
        else
            running = 1;
    }
    while(running){
        running = 0;
        for(int i = 0; i < argc; ++i){
            while(file[i] != -1){
                char c;
                int l = read(file[i], &c, 1);
                if(l <= 0){
                    if(l == -1)
                        perror(argv[i]);
                    close(file[i]);
                    file[i] = -1;
                    break;
                }
                if(c == '\n'){
                    running = 1;
                    break;
                }
                write(STDOUT_FILENO, &c, 1);
            }
            write(STDOUT_FILENO, (i == argc-1) ? "\n" : "\t", 1);
        }
    }
    free(file);
    return 0;
}

The program above is intentionally made simple rather than efficient; the program below is more efficient, but has more lines.

Exercise 6

#include <unistd.h>
int main(void) {
  sleep(5);
  write(1, "about to fork...\n", 17);
  fork();
  write(1, "forked.\n", 8);
  sleep(5);
  return 0;
}

Exercise 7

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(void) {
  pid_t f = fork();
  printf("fork: %-10dpid: %-10dppid: %-10d\n", f, getpid(), getppid());
  return 0;
}

Exercise 8

#include <unistd.h>
int main(void) {
  if (fork()) {
    write(1, "parent\n", 7);
  } else {
    write(1, "child\n", 6);
  }
  return 0;
}

Exercise 9

#include <unistd.h>
int main(void) {
  if (fork()) {
    char c;
    read(0, &c, 1);
  }
  return 0;
}
os_cp/open_fork/solutions.txt · Last modified: 2023/04/11 23:45 by jkonczak