Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #7

Merged
merged 7 commits into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"files.associations": {
"*html": "html",
"unistd.h": "c"
}
}
18 changes: 18 additions & 0 deletions ostep/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
CC=gcc
CCOPTS=#-Wall -Wextra
LIBS=

SRCS=$(wildcard *.c)
TARGETS=$(SRCS:.c=)

.PHONY: all clean pristine

all: $(TARGETS)

clean:
rm -f $(TARGETS) & rm -f *.output

pristine: clean all

%: %.c
$(CC) $(CCOPTS) -o $@ $< $(LIBS)
43 changes: 43 additions & 0 deletions ostep/ex5_1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

int main(int argc, char* argv[]) {
int* x = (int*)malloc(sizeof(int));

int rc = fork();

if (rc == 0) {
for (int i = 0; i <= 10; i++) {
printf("child | x=%d\n", (*x)++);
usleep(1);
}

} else {
for (int i = 0; i <= 10; i++) {
printf("parent| x=%d\n", (*x)++);
usleep(1);
}

wait(NULL);
}

return 0;
}

/*
Q: Write a program that calls fork(). Before calling fork(), have the
main process access a variable (e.g., x) and set its value to something (e.g.,
100). What value is the variable in the child process? What happens to the
variable when both the child and parent change the value of x?

A:
No race condition happens because they don't share memory actually.
Child process gets its own "private memory" (copy of parent's address space)
Therefore parent & child modify their own copy of x, indepedently.

Things would break if they were using shared memory.

note: Even if x is a pointer, nothing changes!
*/
47 changes: 47 additions & 0 deletions ostep/ex5_2.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>

int main(int argc, char* argv[]) {
int fd = open("./ex5_2.output", O_CREAT | O_WRONLY | O_TRUNC, S_IRWXU);
int rc = fork();

if (rc == 0) {
char* msg = "msg from child\n";

for (int i = 0; i < 5; i++) {
write(fd, msg, strlen(msg));
usleep(100);
}

} else {
char* msg = "msg from parent\n";
write(fd, msg, strlen(msg));

for (int i = 0; i < 5; i++) {
write(fd, msg, strlen(msg));
usleep(200);
}

wait(NULL);
close(fd);
}

return 0;
}

/*
Q: Write a program that opens a file (with the open() system call)
and then calls fork() to create a new process. Can both the child
and parent access the file descriptor returned by open()? What
happens when they are writing to the file concurrently, i.e., at the
same time?

A: the order in which the content will be written to the file is
undeterministic. I needed to introduce loops & delays to force the race
condition to happen, but it was clear
*/
42 changes: 42 additions & 0 deletions ostep/ex5_3.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>

int main() {
int pipe_fds[2];
assert(pipe(pipe_fds) >= 0);

int pipe_read_fd = pipe_fds[0];
int pipe_write_fd = pipe_fds[1];

int rc = fork();
assert(rc >= 0);

if (rc == 0) {
sleep(2); // sleep to prove that nothing happens in parent until child
// writes to pipe
char* msg = "msg from child!";
write(pipe_write_fd, msg, strlen(msg));
} else {
char buffer[200];
printf("parent blocked on read() ...\n");
read(pipe_read_fd, buffer, 200);
printf("parent received: “%s”\n", buffer);
printf("parent terminating\n");
}

return 0;
}

/*
Q: Write another program using fork(). The child process should
print “hello”; the parent process should print “goodbye”. You should
try to ensure that the child process always prints first; can you do
this without calling wait() in the parent?

A: can be achieved using a pipe. parent blocks on read() until child writes to
it.
*/
74 changes: 74 additions & 0 deletions ostep/ex5_8.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>

int main() {
int status;

int pipe_fds[2];
assert(pipe(pipe_fds) >= 0);

int pipe_read_fd = pipe_fds[0];
int pipe_write_fd = pipe_fds[1];

pid_t rc1 = fork();
assert(rc1 >= 0);

if (rc1 == 0) {
char* out_buffer = "msg from child 1!";

printf("child 1 is writing...\n");
write(pipe_write_fd, out_buffer, strlen(out_buffer));

close(pipe_write_fd);
printf("child 1 terminating...\n");

exit(0);
}

pid_t rc2 = fork();
assert(rc2 >= 0);

if (rc2 == 0) {
printf("child 2 blocked on read()...\n");

char in_buffer[200];
read(pipe_read_fd, in_buffer, 200);
printf("child 2 finished reading...\n");

char out_buffer[400];
sprintf(out_buffer, "%s || msg from child 2!", in_buffer);

printf("child 2 is writing...\n");
write(pipe_write_fd, out_buffer, strlen(out_buffer));

close(pipe_write_fd);
printf("child 2 terminating...\n");

exit(0);
}

// Parent process

printf("parent waiting for child 1 (pid: %d) ...\n", rc1);
waitpid(rc1, &status, 0);
printf("parent waiting for child 2 (pid: %d) ...\n", rc1);
waitpid(rc2, &status, 0);

char buffer[200];
read(pipe_read_fd, buffer, 200);
printf("parent received: “%s”\n", buffer);

close(pipe_write_fd);
printf("parent terminating...\n");

return 0;
}

/*
Q: Write a program that creates two children, and connects the standard output
of one to the standard input of the other, using the pipe() system call.
*/
2 changes: 0 additions & 2 deletions sandbox/.gitignore

This file was deleted.

Loading