static int write_string_file_atomic(const char *fn, const char *line, bool enforce_newline) { _cleanup_fclose_ FILE *f = NULL; _cleanup_free_ char *p = NULL; int r; assert(fn); assert(line); r = fopen_temporary(fn, &f, &p); if (r < 0) return r; (void) fchmod_umask(fileno(f), 0644); r = write_string_stream(f, line, enforce_newline); if (r >= 0) { if (rename(p, fn) < 0) r = -errno; } if (r < 0) (void) unlink(p); return r; }
int write_string_file(const char *fn, const char *line, WriteStringFileFlags flags) { _cleanup_fclose_ FILE *f = NULL; assert(fn); assert(line); if (flags & WRITE_STRING_FILE_ATOMIC) { assert(flags & WRITE_STRING_FILE_CREATE); return write_string_file_atomic(fn, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE)); } if (flags & WRITE_STRING_FILE_CREATE) { f = fopen(fn, "we"); if (!f) return -errno; } else { int fd; /* We manually build our own version of fopen(..., "we") that * works without O_CREAT */ fd = open(fn, O_WRONLY|O_CLOEXEC|O_NOCTTY); if (fd < 0) return -errno; f = fdopen(fd, "we"); if (!f) { safe_close(fd); return -errno; } } return write_string_stream(f, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE)); }
int write_string_file(const char *fn, const char *line) { _cleanup_fclose_ FILE *f = NULL; assert(fn); assert(line); f = fopen(fn, "we"); if (!f) return -errno; return write_string_stream(f, line); }
static void test_clock_is_localtime(void) { char adjtime[] = "/tmp/test-adjtime.XXXXXX"; int fd = -1; _cleanup_fclose_ FILE* f = NULL; static const struct scenario { const char* contents; int expected_result; } scenarios[] = { /* adjtime configures UTC */ {"0.0 0 0\n0\nUTC\n", 0}, /* adjtime configures local time */ {"0.0 0 0\n0\nLOCAL\n", 1}, /* no final EOL */ {"0.0 0 0\n0\nUTC", 0}, {"0.0 0 0\n0\nLOCAL", 1}, /* empty value -> defaults to UTC */ {"0.0 0 0\n0\n", 0}, /* unknown value -> defaults to UTC */ {"0.0 0 0\n0\nFOO\n", 0}, /* no third line */ {"0.0 0 0", 0}, {"0.0 0 0\n", 0}, {"0.0 0 0\n0", 0}, }; /* without an adjtime file we default to UTC */ assert_se(clock_is_localtime("/nonexisting/adjtime") == 0); fd = mkostemp_safe(adjtime); assert_se(fd >= 0); log_info("adjtime test file: %s", adjtime); f = fdopen(fd, "w"); assert_se(f); for (size_t i = 0; i < ELEMENTSOF(scenarios); ++i) { log_info("scenario #%zu:, expected result %i", i, scenarios[i].expected_result); log_info("%s", scenarios[i].contents); rewind(f); ftruncate(fd, 0); assert_se(write_string_stream(f, scenarios[i].contents, WRITE_STRING_FILE_AVOID_NEWLINE) == 0); assert_se(clock_is_localtime(adjtime) == scenarios[i].expected_result); } unlink(adjtime); }
int write_string_file_no_create(const char *fn, const char *line) { _cleanup_fclose_ FILE *f = NULL; int fd; assert(fn); assert(line); /* We manually build our own version of fopen(..., "we") that * without O_CREAT */ fd = open(fn, O_WRONLY|O_CLOEXEC|O_NOCTTY); if (fd < 0) return -errno; f = fdopen(fd, "we"); if (!f) { safe_close(fd); return -errno; } return write_string_stream(f, line); }
int write_string_file(const char *fn, const char *line, WriteStringFileFlags flags) { _cleanup_fclose_ FILE *f = NULL; int q, r; assert(fn); assert(line); if (flags & WRITE_STRING_FILE_ATOMIC) { assert(flags & WRITE_STRING_FILE_CREATE); r = write_string_file_atomic(fn, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE)); if (r < 0) goto fail; return r; } if (flags & WRITE_STRING_FILE_CREATE) { f = fopen(fn, "we"); if (!f) { r = -errno; goto fail; } } else { int fd; /* We manually build our own version of fopen(..., "we") that * works without O_CREAT */ fd = open(fn, O_WRONLY|O_CLOEXEC|O_NOCTTY); if (fd < 0) { r = -errno; goto fail; } f = fdopen(fd, "we"); if (!f) { r = -errno; safe_close(fd); goto fail; } } r = write_string_stream(f, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE)); if (r < 0) goto fail; return 0; fail: if (!(flags & WRITE_STRING_FILE_VERIFY_ON_FAILURE)) return r; f = safe_fclose(f); /* OK, the operation failed, but let's see if the right * contents in place already. If so, eat up the error. */ q = verify_file(fn, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE)); if (q <= 0) return r; return 0; }