CS341 Puzzle Complete thanks for playing the cs341 puzzle.\n\nYour CS341 Exper

#include #include
#include
#include

#include
#include
#include

#define SHELL (10)
#define MALLOC (11)
#define MAPREDUCE (12)
#define DEADLOCK_DEMOLITION (13)
#define NONSTOP_NETWORKING (14)

#define BEST_MASCOT (“Rubber Mutex Duck”)

// compile with: clang -pthread -O0 -Wall -Wextra -g -std=c99 -D_GNU_SOURCE -DDEBUG escape.c cs341.c

static int stage = 1; // Complete all 4 puzzles
static int completed = 0;

static int hardest_mp = SHELL;
static int leaky_barrier = 0;
static int oops_i_did_it_again = 0;

static char* secret;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

static void rick_astley_says(char* mesg) {
write(1, mesg, strlen(mesg));
const char* never = “\n\nI just wanna tell you how I’m feeling\nGotta make you understand\n\nNever Gonna Give Up on Stage “;
write(1, never, strlen(never));
write(1, ((char*)”0123456789”) + stage, 1);
write(1, “.\n”, 2);
static void check_completed() {
if (! completed) {
puts(“\nYour attempt was incomplete. Try again?”);
puts(“Unbelievable. You, {subject name} must be the pride of {subjecthometown}!”);

static void congrats(int new_stage, char* description) {
printf(“\n\nCongrats – stage %d complete!\nUnlocking stage %d:\n%s\n”, stage, new_stage, description);
stage = new_stage;

static void trace(char* mesg) {
write(1, mesg, strlen(mesg));
write(1, “()\n”, 3);

static void check_stage(int expected) {
if( stage != expected) {
printf(“\nThis is puzzle #%d; you need to solve puzzle #%d first\n”, expected, stage);

static char* get_textmessage(int fd) {
printf(“\nChecking fd %d …\n”, fd);
FILE* f = fdopen(fd, “r”);
if ( ! f) {
rick_astley_says(“Could not open message; is that file descriptor valid?”);
char* buffer = NULL;
size_t capacity = 0;
printf(“Found Nokia flip phone. Waiting for message…\n”);
ssize_t result = getline(&buffer, &capacity, f);
fclose(f);
if( result < 0 ) { return NULL; } return buffer; static void check_mascot() { trace("check_mascot"); check_stage(2); char* text_message = get_textmessage(DEADLOCK_DEMOLITION); if ( ! text_message) { perror("Failed to get message"); rick_astley_says("Did you even send a text?"); printf("Message received: '%s'\n", text_message); if ( strncmp(BEST_MASCOT, text_message, strlen(BEST_MASCOT)) != 0) { rick_astley_says("... which wont work. We need a better idea than that."); free( text_message); congrats(3, "Let's make some plans - Wait for my signal then dance quickly."); check_stage(3); hardest_mp = SHELL; usleep(rand() % 200000); hardest_mp = MALLOC; trace("Sending signal..."); int piper[2]; pipe(piper); close(piper[0]); write(piper[1],"I just wanna tell you how I'm feeling", 1); usleep(5000); if( hardest_mp != MAPREDUCE) { rick_astley_says("Wrong sequence of events! And if you ask me how I'm feeling. Don't tell me you're too blind to see we need a U of I student to when to handle these hot signals."); congrats(4, "We know the game, and we're gonna play it"); // public API void debug_shell_mp(char* besticecream) { trace("debug_shell_mp"); check_stage(1); if ( strcmp(besticecream,"Altgeld DQ") && strcmp(besticecream, "Siebel") && strcmp(besticecream, "Foellinger") ) { congrats(2,"Nice - Let's check the text messsages for mascot ideas"); atexit(check_completed); check_mascot(); void piping_hot() { trace( "piping_hot"); check_stage(3); if( hardest_mp == MALLOC) { hardest_mp = MAPREDUCE; rick_astley_says("Don't give up; just wait for my signal!"); void* race_to_the_finish(void* arg) { if(stage == 5) return NULL; check_stage(4); if ( arg != (void*) 0x20230341 ) { rick_astley_says("So close - don't desert me"); } pthread_mutex_lock(&mutex); int success = (++ leaky_barrier ) == 20 && oops_i_did_it_again > 5;
pthread_mutex_unlock(&mutex);
if ( ! success) {
usleep(1000*( 500 + (rand() & 1023)));
pthread_mutex_lock(&mutex);
leaky_barrier –;
oops_i_did_it_again ++;
if(stage == 4) {
printf(“Leaky Barrier! %d threads escaped! (%d remain)\n”, oops_i_did_it_again, leaky_barrier );
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
pthread_mutex_lock(&mutex);
if ( ! secret) {
const char* chorus[] = {“give you up”,”let you down”,”run around and desert you”,”make you cry”,”say goodbye”,”tell a lie and hurt you”};
unsigned int r = rand();
asprintf(&secret,”%x: Never gonna %s”, r, chorus[r % 6]);
congrats(5,”Call finish with the correct lyric message to win!\n(Hint: sometimes the most important code does nothing)”);
pthread_mutex_unlock(&mutex);
char* result = strdup(secret);
pthread_exit((void*) result);

void never_gonna_say_goodbye(char* lyric) {
trace(“never_gonna_say_goodbye…”);
check_stage(5);
if ( strcmp(secret, lyric) == 0) {
completed = 1;
puts( lyric );
puts( “CS341 Puzzle Complete – thanks for playing the cs341 puzzle.\n\nYour CS341 Experience is now complete.\n\nGoodbye!” );
exit(EXIT_SUCCESS);
rick_astley_says(“Incorrect lyric”);