/* this function is intended to encapsulate the basic swupd * initializations for the majority of commands, that is: * - Make sure root is the user running the code * - Initialize log facility * - Get the lock * - initialize mounted directories * - Initialize curl */ int swupd_init(int *lock_fd) { int ret = 0; check_root(); *lock_fd = p_lockfile(); if (*lock_fd < 0) { ret = ELOCK_FILE; goto out_fds; } get_mounted_directories(); if (swupd_curl_init() != 0) { ret = ECURL_INIT; goto out_close_lock; } return ret; out_close_lock: v_lockfile(*lock_fd); out_fds: dump_file_descriptor_leaks(); return ret; }
/* this function is intended to encapsulate the basic swupd * initializations for the majority of commands, that is: * - Make sure root is the user running the code * - Initialize globals * - initialize mounted directories * - Create necessary directories * - Get the lock * - Initialize curl * - Initialize signature checking */ int swupd_init(void) { int ret = 0; check_root(); record_fds(); /* Check that our system time is reasonably valid before continuing, * or the certificate verification will fail with invalid time */ if (timecheck) { if (!verify_time()) { ret = EBADTIME; goto out_fds; } } if (!init_globals()) { ret = EINIT_GLOBALS; goto out_fds; } get_mounted_directories(); if (create_required_dirs()) { ret = EREQUIRED_DIRS; goto out_fds; } if (p_lockfile() < 0) { ret = ELOCK_FILE; goto out_fds; } if (swupd_curl_init() != 0) { ret = ECURL_INIT; goto out_close_lock; } /* If --nosigcheck, we do not attempt any signature checking */ if (sigcheck && !initialize_signature()) { ret = ESIGNATURE; terminate_signature(); goto out_close_lock; } return ret; out_close_lock: v_lockfile(); out_fds: dump_file_descriptor_leaks(); return ret; }
static int clean_init(void) { int ret = 0; check_root(); if (!init_globals()) { return SWUPD_INIT_GLOBALS_FAILED; } if (p_lockfile() < 0) { free_globals(); return SWUPD_LOCK_FILE_FAILED; } return ret; }
/* this function is intended to encapsulate the basic swupd * initializations for the majority of commands, that is: * - Make sure root is the user running the code * - Initialize log facility * - Get the lock * - initialize mounted directories * - Initialize curl */ int swupd_init(int *lock_fd) { int ret = 0; check_root(); if (!init_globals()) { ret = EINIT_GLOBALS; goto out_fds; } get_mounted_directories(); if (create_required_dirs()) { ret = EREQUIRED_DIRS; goto out_fds; } *lock_fd = p_lockfile(); if (*lock_fd < 0) { ret = ELOCK_FILE; goto out_fds; } if (swupd_curl_init() != 0) { ret = ECURL_INIT; goto out_close_lock; } if (!initialize_signature()) { ret = ESIGNATURE; terminate_signature(); goto out_close_lock; } return ret; out_close_lock: v_lockfile(*lock_fd); out_fds: dump_file_descriptor_leaks(); return ret; }
/* Attempt to get a write lock protecting the file test/protected_data using * p_lockfile(). If successful, no two processess should be able to hold the * lock similtaneously. */ static void work(int id) { int lock_fd; int successes = 0; FILE *file; char buffer[LINE_MAX]; while (successes < NUM_ACCESS) { int prev_id = -1; char prev_action = ' '; char c = ' '; // Sleep for a random amount of time, up to half a second so // not all processes attempt to access lock at once. usleep(rand() % 500000); // Attempt to access the lock lock_fd = p_lockfile(); if (lock_fd < 0) { printf("process %i unable to acquire lock\n", id); fflush(stdout); continue; } printf("process %i acquired lock\n", id); file = fopen(PROTECTED_FILE, "a+"); fseek(file, 0, SEEK_END); // Check if file is empty if (ftell(file) != 0) { // Go to start of last line while (c != '\n' && fseek(file, -2, SEEK_CUR) == 0) { c = getc(file); } // If the file only has one line, return to start of file if (c != '\n') { rewind(file); } // Read last line of protected_data sscanf(fgets(buffer, LINE_MAX, file), "%i%c\n", &prev_id, &prev_action); } fprintf(file, "%ip\n", id); fflush(file); if (prev_action == 'p') { printf("process %i accessed lock being held by process %i\n", id, prev_id); printf("process %i aborting\n\n", id); return; } // Sleep for up to a fifth of a second while holding lock. During this time // other processes should try to access lock and fail. This sleep is shorter // than the one before attempting to get the lock because we don't need to // wait for all other processes to attempt to access lock, just some of them usleep(rand() % 200000); fseek(file, 0, SEEK_END); if (ftell(file) == 0) { printf("process %i failed to write to protected_data", id); printf("process %i aborting\n\n", id); } else { char c = ' '; while (c != '\n' && fseek(file, -2, SEEK_CUR) == 0) { c = getc(file); } if (c != '\n') { rewind(file); } sscanf(fgets(buffer, LINE_MAX, file), "%i%c\n", &prev_id, &prev_action); } // Log that this thread released the lock fprintf(file, "%iv\n", id); fclose(file); if (prev_action != 'p' || prev_id != id) { if (prev_id == -1) { printf("process %i released lock without holding it\n", id); } else { printf("process %i and process %i held lock similtaneously\n", id, prev_id); } printf("process %i aborting\n\n", id); return; } printf("process %i released lock\n\n", id); v_lockfile(lock_fd); successes++; } return; }