static void get_log_file_tail(const char *despath, const char *srcpath, const int lines) { char *start; int start_line; int file_lines; struct mm_file_t *mfile; int ret; mfile = mmap_file(srcpath); if (!mfile) { LOGE("mmap (%s) failed, error (%s)\n", srcpath, strerror(errno)); return; } file_lines = mm_count_lines(mfile); if (file_lines <= 0) { LOGW("get lines (%s, %d) failed\n", mfile->path, file_lines); goto unmap; } start_line = MAX(file_lines - lines, 0) + 1; start = mm_get_line(mfile, start_line); ret = overwrite_file(despath, start); if (ret < 0) { LOGE("create file with (%s, %p) failed, error (%s)\n", despath, start, strerror(errno)); goto unmap; } unmap: unmap_file(mfile); }
int main(void) { size_t num_bytes = sysconf(_SC_PAGESIZE); int fd = open(DUMMY_FILE, O_CREAT | O_EXCL | O_RDWR, 0600); int* rpage; size_t i; test_assert(fd >= 0); overwrite_file(DUMMY_FILE, num_bytes); rpage = mmap(NULL, num_bytes, PROT_READ, MAP_SHARED, fd, 0); atomic_printf("rpage:%p\n", rpage); test_assert(rpage != (void*)-1); for (i = 0; i < num_bytes / sizeof(magic); ++i) { test_assert(rpage[i] == magic); } lseek(fd, 0, SEEK_SET); for (i = 0; i < num_bytes / sizeof(i); ++i) { int written; write(fd, &i, sizeof(i)); written = rpage[i]; atomic_printf("(wrote %d, read %d)", (int)i, written); test_assert(written == (ssize_t)i); } atomic_puts(" done"); return 0; }
int main(int argc, char *argv[]) { size_t num_bytes = sysconf(_SC_PAGESIZE); int fd = open(DUMMY_FILE, O_CREAT | O_EXCL | O_RDWR, 0600); int* wpage; int* rpage; int* old_wpage; test_assert(fd >= 0); overwrite_file(DUMMY_FILE, 2 * num_bytes); wpage = mmap(NULL, num_bytes, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); rpage = mmap(NULL, num_bytes, PROT_READ, MAP_SHARED, fd, 0); atomic_printf("wpage:%p rpage:%p\n", wpage, rpage); test_assert(wpage != (void*)-1 && rpage != (void*)-1 && rpage != wpage); /* NB: this is a bad test in that it assumes * ADDR_COMPAT_LAYOUT address-space allocation semantics. If * this test is run "normally", it will most likely fail this * assertion. To fix this we'd need to dyanmically determine * which page is mapped just before the other and then remap * that page. */ test_assert((byte*)rpage - (byte*)wpage == num_bytes); check_mapping(rpage, wpage, num_bytes / sizeof(*wpage)); overwrite_file(DUMMY_FILE, 2 * num_bytes); old_wpage = wpage; wpage = mremap(old_wpage, num_bytes, 2 * num_bytes, MREMAP_MAYMOVE); atomic_printf("remapped wpage:%p\n", wpage); test_assert(wpage != (void*)-1 && wpage != old_wpage); check_mapping(rpage, wpage, num_bytes / sizeof(*wpage)); atomic_puts(" done"); return 0; }
SILICIUM_USE_RESULT inline boost::system::error_code write_file(Si::native_path_string name, Si::memory_range data) { Si::error_or<Si::file_handle> const file = overwrite_file(name); if (file.is_error()) { return file.error(); } file_sink sink(file.get().handle); return Si::append(sink, file_sink_element{data}); }
int is_boot_id_changed(void) { void *boot_id; void *logged_boot_id; char logged_boot_id_path[PATH_MAX]; unsigned long size; struct sender_t *crashlog; int res; int result = 1; /* returns changed by default */ crashlog = get_sender_by_name("crashlog"); if (!crashlog) return result; res = read_file(BOOTID_NODE, &size, &boot_id); if (res == -1 || !size) return result; res = snprintf(logged_boot_id_path, sizeof(logged_boot_id_path), "%s/%s", crashlog->outdir, BOOTID_LOG); if (s_not_expect(res, sizeof(logged_boot_id_path))) goto out; if (file_exists(logged_boot_id_path)) { res = read_file(logged_boot_id_path, &size, &logged_boot_id); if (res == -1 || !size) goto out; if (!strcmp((char *)logged_boot_id, (char *)boot_id)) result = 0; free(logged_boot_id); } if (result) overwrite_file(logged_boot_id_path, boot_id); out: free(boot_id); return result; }
/* * Given a remctl object, the Kerberos context, the name of a keytab object, * and a file name, call the correct wallet commands to download a keytab and * write it to that file. Returns the status or 255 on an internal error. */ int get_keytab(struct remctl *r, krb5_context ctx, const char *type, const char *name, const char *file, const char *srvtab) { const char *command[5]; char *tempfile; char *data = NULL; size_t length = 0; int status; command[0] = type; command[1] = "get"; command[2] = "keytab"; command[3] = name; command[4] = NULL; status = run_command(r, command, &data, &length); if (status != 0) return status; if (data == NULL) { warn("no data returned by wallet server"); return 255; } if (access(file, F_OK) == 0) { xasprintf(&tempfile, "%s.new", file); overwrite_file(tempfile, data, length); if (srvtab != NULL) write_srvtab(ctx, srvtab, name, tempfile); merge_keytab(ctx, tempfile, file); if (unlink(tempfile) < 0) sysdie("unlink of temporary keytab file %s failed", tempfile); free(tempfile); } else { write_file(file, data, length); if (srvtab != NULL) write_srvtab(ctx, srvtab, name, file); } return 0; }
int sunlink(const char *path) { struct stat statbuf; struct statfs fs_stats; #if HAVE_LINUX_EXT2_FS_H int flags = 0; #endif int fmode = (options & OPT_VERIFY) ? O_RDWR : O_WRONLY; struct flock flock; if (lstat(path, &statbuf) == -1) return -1; if (!S_ISREG(statbuf.st_mode)) return rename_unlink(path); if (statbuf.st_nlink > 1) { rename_unlink(path); errno = EMLINK; return -1; } if ( (file = open(path, fmode)) == -1) /* BSD doesn't support O_SYNC */ return -1; if (fcntl(file, F_WRLCK, &flock) == -1) { close(file); return -1; } if (fstatfs(file, &fs_stats) == -1 && errno != ENOSYS) { close(file); return -1; } /* warn when trying to overwrite files on a non-local fs, since there are no guarantees that writes will not be buffered on the server, or will overwrite the same spot. */ if (options & OPT_V) { if ((fs_stats.f_flags & MNT_LOCAL) == 0) { printf("warning: %s is not on a local filesystem!\n", path); fflush(stdout); } } #if HAVE_LINUX_EXT2_FS_H if (fs_stats.f_type == EXT2_SUPER_MAGIC) if (ioctl(file, EXT2_IOC_GETFLAGS, &flags) == -1) { close(file); return -1; } if ( (flags & EXT2_UNRM_FL) || (flags & EXT2_IMMUTABLE_FL) || (flags & EXT2_APPEND_FL) ) { close(file); errno = EPERM; return -1; } #endif /* HAVE_LINUX_EXT2_FS_H */ /* chflags(2) turns out to be a different system call in every BSD derivative. The important thing is to make sure we'll be able to unlink it after we're through messing around. Unlinking it first would remove the need for any of these checks, but would leave the user with no way to overwrite the file if the process was interrupted during the overwriting. So, instead we assume that the open() above will fail on immutable and append-only files and try and catch only platforms supporting NOUNLINK here. FreeBSD - supports NOUNLINK (from 4.4 on?) MacOS X - doesn't support NOUNLINK (as of 10.3.5) OpenBSD - doesn't support NOUNLINK (as of 3.1) Tru64 - unknown Note: unsupported flags are defined as 0 at the top of this file, so a specific platform check is not required here. */ #if HAVE_CHFLAGS if ((statbuf.st_flags & UF_IMMUTABLE) || (statbuf.st_flags & UF_APPEND) || (statbuf.st_flags & UF_NOUNLINK) || (statbuf.st_flags & SF_IMMUTABLE) || (statbuf.st_flags & SF_APPEND) || (statbuf.st_flags & SF_NOUNLINK)) { close(file); errno = EPERM; return -1; } #endif /* HAVE_CHFLAGS */ if (init_write_buffer(&statbuf, &fs_stats) == -1) { close(file); return -1; } #if defined F_NOCACHE /* before performing file I/O, set F_NOCACHE to prevent caching */ (void)fcntl(file, F_NOCACHE, 1); #endif overwrite_file(); #if HAVE_LINUX_EXT2_FS_H ioctl(file, EXT2_IOC_SETFLAGS, EXT2_SECRM_FL); #endif if ((options & OPT_N) == 0) { if (ftruncate(file, 0) == -1) { close(file); return -1; } } close(file); #if __APPLE__ /* Also overwrite the file's resource fork, if present. */ { static const char *RSRCFORKSPEC = "/..namedfork/rsrc"; size_t rsrc_fork_size; size_t rsrc_path_size = strlen(path) + strlen(RSRCFORKSPEC) + 1; char *rsrc_path = (char *)alloca(rsrc_path_size); if (rsrc_path == NULL) { errno = ENOMEM; return -1; } if (snprintf(rsrc_path, MAXPATHLEN, "%s%s", path, RSRCFORKSPEC ) > MAXPATHLEN - 1) { errno = ENAMETOOLONG; return -1; } if (lstat(rsrc_path, &statbuf) != 0) { int err = errno; if (err == ENOENT || err == ENOTDIR) { rsrc_fork_size = 0; } else { return -1; } } else { rsrc_fork_size = statbuf.st_size; } if (rsrc_fork_size > 0) { if ((file = open(rsrc_path, O_WRONLY)) == -1) { return -1; } if (fcntl(file, F_WRLCK, &flock) == -1) { close(file); return -1; } if (options & OPT_V) { printf("removing %s\n", rsrc_path); fflush(stdout); } if (init_write_buffer(&statbuf, &fs_stats) == -1) { close(file); return -1; } #if defined F_NOCACHE /* before performing file I/O, set F_NOCACHE to prevent caching */ (void)fcntl(file, F_NOCACHE, 1); #endif overwrite_file(); if ((options & OPT_N) == 0) { if (ftruncate(file, 0) == -1) { close(file); return -1; } } close(file); } } #endif /* __APPLE__ */ if (options & OPT_N) return 0; return rename_unlink(path); }
/** * Create a crashfile with given params. * * @param dir Where to generate crashfile. * @param event Event name. * @param hashkey Event id. * @param type Subtype of this event. * @param data* String obtained by get_data. */ void generate_crashfile(const char *dir, const char *event, size_t elen, const char *hashkey, size_t hlen, const char *type, size_t tlen, const char *data0, size_t d0len, const char *data1, size_t d1len, const char *data2, size_t d2len) { char *buf; char *path; char *tail; char datetime[LONG_TIME_SIZE]; char uptime[UPTIME_SIZE]; int hours; const int fmtsize = 128; size_t ltlen; int n; int filesize; if (!dir || !event || !elen || !hashkey || !hlen || !type || !tlen) return; if (d0len > 0 && !data0) return; if (d1len > 0 && !data1) return; if (d2len > 0 && !data2) return; ltlen = get_current_time_long(datetime); if (!ltlen) return; n = get_uptime_string(uptime, &hours); if (n < 0) return; filesize = fmtsize + ltlen + n + elen + hlen + tlen + d0len + d1len + d2len + strnlen(guuid, UUID_SIZE) + strnlen(gbuildversion, BUILD_VERSION_SIZE); buf = malloc(filesize); if (buf == NULL) { LOGE("out of memory\n"); return; } tail = cf_line(buf, "EVENT=", 6, event, elen); tail = cf_line(tail, "ID=", 3, hashkey, hlen); tail = cf_line(tail, "DEVICEID=", 9, guuid, strnlen(guuid, UUID_SIZE)); tail = cf_line(tail, "DATE=", 5, datetime, ltlen); tail = cf_line(tail, "UPTIME=", 7, uptime, n); tail = cf_line(tail, "BUILD=", 6, gbuildversion, strnlen(gbuildversion, BUILD_VERSION_SIZE)); tail = cf_line(tail, "TYPE=", 5, type, tlen); if (d0len) tail = cf_line(tail, "DATA0=", 6, data0, d0len); if (d1len) tail = cf_line(tail, "DATA1=", 6, data1, d1len); if (d2len) tail = cf_line(tail, "DATA2=", 6, data2, d2len); tail = mempcpy(tail, "_END\n", 5); *tail = '\0'; if (asprintf(&path, "%s/crashfile", dir) == -1) { LOGE("out of memory\n"); free(buf); return; } if (overwrite_file(path, buf) != 0) LOGE("failed to new crashfile (%s), error (%s)\n", path, strerror(errno)); free(buf); free(path); }