commit 9b4d8ee92bc8ba0131cf79f2bfbee913c9a03a1b
parent e2fadc1e7900d5788733266795e43334e990fc8e
Author: Kyle Milz <kyle@0x30.net>
Date: Tue, 10 Jan 2017 00:23:46 -0700
lib: split into os independent parts
Diffstat:
M | lib.c | | | 215 | ++++--------------------------------------------------------------------------- |
A | lib_os.h | | | 6 | ++++++ |
A | lib_unix.c | | | 101 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | lib_win32.c | | | 153 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
4 files changed, 270 insertions(+), 205 deletions(-)
diff --git a/lib.c b/lib.c
@@ -13,208 +13,20 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#ifdef _WIN32
-#include <direct.h> /* getcwd */
-#include <stdio.h> /* stderr */
-#include <windows.h> /* HANDLE, MapViewOfFile, ... */
-#include <io.h>
-#define PATH_MAX 32000
-
-#define DEFAULT_PROCDIR "C:\\CItRun"
-static HANDLE h = INVALID_HANDLE_VALUE;
-#else /* _WIN32 */
-#include <sys/mman.h> /* mmap */
-#include <sys/stat.h> /* S_IRUSR, S_IWUSR, mkdir */
-
-#include <assert.h>
-#include <err.h>
-#include <errno.h> /* EEXIST */
-#include <fcntl.h> /* O_CREAT */
-#include <limits.h> /* PATH_MAX */
-#include <stdio.h>
-#include <stdlib.h> /* atexit, get{env,progname} */
-#include <string.h> /* str{l,n}cpy */
-#include <unistd.h> /* lseek get{cwd,pid,ppid,pgrp} */
-
-#define DEFAULT_PROCDIR "/tmp/citrun"
-static int fd;
-#endif /* _WIN32 */
+#include <stdlib.h> /* exit */
+#include <stdio.h> /* fprintf, stderr */
+#include <string.h> /* strncpy */
+#include <unistd.h> /* getcwd */
#include "lib.h" /* citrun_*, struct citrun_{header,node} */
+#include "lib_os.h" /* extend, open_fd */
+static int init;
static struct citrun_header *header;
-#ifdef _WIN32
-static void
-Err(int code, const char *fmt)
-{
- char buf[256];
-
- FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 256, NULL);
-
- fprintf(stderr, "%s: %s", fmt, buf);
- exit(code);
-}
-
-HANDLE
-mkstemp(char *template)
-{
- int i;
- unsigned int r;
-
- char chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
-
- for (i = strlen(template) - 1; i > 0; --i) {
- if (template[i] != 'X')
- break;
-
- if (rand_s(&r)) {
- fprintf(stderr, "rand failed: %s\n", strerror(errno));
- exit(1);
- }
-
- template[i] = chars[r % (sizeof(chars) - 1)];
- }
-
- return CreateFile(
- template,
- GENERIC_READ | GENERIC_WRITE,
- 0,
- NULL,
- CREATE_NEW,
- 0,
- NULL
- );
-}
-#endif /* _WIN32 */
-
-static size_t
-align_bytes(size_t unaligned_bytes)
-{
- size_t page_mask;
-
-#ifdef _WIN32
- SYSTEM_INFO system_info;
- GetSystemInfo(&system_info);
-
- page_mask = system_info.dwAllocationGranularity - 1;
-#else
- page_mask = getpagesize() - 1;
-#endif /* _WIN32 */
- return (unaligned_bytes + page_mask) & ~page_mask;
-}
-
-/*
- * Extends the file and memory mapping length of fd by a requested amount of
- * bytes (rounded up to the next page size).
- * Returns a pointer to the extended region on success, exits on failure.
- */
-static void *
-extend(size_t req_bytes)
-{
- size_t aligned_bytes;
- size_t len;
- void *mem;
-
- aligned_bytes = align_bytes(req_bytes);
-
-#ifdef _WIN32
- HANDLE fm;
-
- /* Get current file length. */
- if ((len = GetFileSize(h, NULL)) == INVALID_FILE_SIZE)
- Err(1, "GetFileSize");
-
- /* Increase file pointer to new length. */
- if (SetFilePointer(h, len + aligned_bytes, NULL, FILE_BEGIN)
- == INVALID_SET_FILE_POINTER)
- Err(1, "SetFilePointer");
-
- /* Set new length. */
- if (SetEndOfFile(h) == 0)
- Err(1, "SetEndOfFile");
-
- /* Create a new mapping that's used temporarily. */
- if ((fm = CreateFileMapping(h, NULL, PAGE_READWRITE, 0, 0, NULL)) == NULL)
- Err(1, "CreateFileMapping");
-
- /* Create a new memory mapping for the newly extended space. */
- if ((mem = MapViewOfFile(fm, FILE_MAP_READ | FILE_MAP_WRITE, 0, len, req_bytes)) == NULL)
- Err(1, "MapViewOfFile");
-
- CloseHandle(fm);
-#else /* _WIN32 */
- /* Get current file length. */
- if ((len = lseek(fd, 0, SEEK_END)) < 0)
- err(1, "lseek");
-
- /* Increase file length, filling with zeros. */
- if (ftruncate(fd, len + aligned_bytes) < 0)
- err(1, "ftruncate from %lld to %llu", len, len + aligned_bytes);
-
- /* Increase memory mapping length. */
- mem = mmap(NULL, req_bytes, PROT_READ | PROT_WRITE, MAP_SHARED, fd, len);
-
- if (mem == MAP_FAILED)
- err(1, "mmap %zu bytes @ %llu", req_bytes, len);
-#endif /* _WIN32 */
-
- return mem;
-}
-
-static void
-get_prog_name(char *buf, size_t buf_size)
-{
-#ifdef _WIN32
- if (GetModuleFileName(NULL, buf, buf_size) == 0)
- Err(1, "GetModuleFileName");
-#else
- strlcpy(buf, getprogname(), buf_size);
-#endif
-}
-
-/*
- * Opens a file with a random suffix. Exits on error.
- */
-static void
-open_fd()
-{
- char *procdir;
- char procfile[PATH_MAX];
-
- if ((procdir = getenv("CITRUN_PROCDIR")) == NULL)
- procdir = DEFAULT_PROCDIR;
-
-#ifdef _WIN32
- if (CreateDirectory(procdir, NULL) == 0 &&
- GetLastError() != ERROR_ALREADY_EXISTS)
- Err(1, "CreateDirectory");
-
- strncpy(procfile, procdir, PATH_MAX);
- strncat(procfile, "\\", PATH_MAX);
- strncat(procfile, "program", PATH_MAX);
- strncat(procfile, "_XXXXXXXXXX", PATH_MAX);
-
- if ((h = mkstemp(procfile)) == INVALID_HANDLE_VALUE)
- Err(1, "mkstemp");
-#else /* _WIN32 */
- if (mkdir(procdir, S_IRWXU) && errno != EEXIST)
- err(1, "mkdir '%s'", procdir);
-
- strlcpy(procfile, procdir, PATH_MAX);
- strlcat(procfile, "/", PATH_MAX);
- strlcat(procfile, getprogname(), PATH_MAX);
- strlcat(procfile, "_XXXXXXXXXX", PATH_MAX);
-
- if ((fd = mkstemp(procfile)) < 0)
- err(1, "mkstemp");
-#endif /* _WIN32 */
-}
-
/*
- * Called by atexit(3), which doesn't always get called (this is unreliable).
+ * Try and set a flag if the atexit() trigger actually fires.
*/
static void
set_exited(void)
@@ -235,12 +47,8 @@ add_header()
header->major = citrun_major;
header->minor = citrun_minor;
- header->pids[0] = getpid();
-#ifndef _WIN32
- header->pids[1] = getppid();
- header->pids[2] = getpgrp();
-#endif /* ! _WIN32 */
+ get_pids(header->pids);
get_prog_name(header->progname, sizeof(header->progname));
if (getcwd(header->cwd, sizeof(header->cwd)) == NULL)
@@ -270,13 +78,10 @@ citrun_node_add(unsigned int major, unsigned int minor, struct citrun_node *n)
exit(1);
}
-#ifdef _WIN32
- if (h == INVALID_HANDLE_VALUE) {
-#else
- if (fd == 0) {
-#endif /* _WIN32 */
+ if (init == 0) {
open_fd();
add_header();
+ init = 1;
}
/* Allocate enough room for node and live execution buffers. */
diff --git a/lib_os.h b/lib_os.h
@@ -0,0 +1,6 @@
+/*
+ * Operating system specific functions.
+ */
+void *extend(size_t);
+void get_prog_name(char *, size_t);
+void open_fd();
diff --git a/lib_unix.c b/lib_unix.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2016 Kyle Milz <kyle@0x30.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <sys/mman.h> /* mmap */
+#include <sys/stat.h> /* S_IRUSR, S_IWUSR, mkdir */
+
+#include <assert.h>
+#include <err.h>
+#include <errno.h> /* EEXIST */
+#include <fcntl.h> /* O_CREAT */
+#include <limits.h> /* PATH_MAX */
+#include <stdlib.h> /* get{env,progname} */
+#include <string.h> /* strl{cpy,cat} */
+#include <unistd.h> /* lseek get{cwd,pid,ppid,pgrp} */
+
+#include "lib_os.h"
+
+static int fd;
+
+/*
+ * Extends the file and memory mapping length of fd by a requested amount of
+ * bytes (rounded up to the next page size).
+ * Returns a pointer to the extended region on success, exits on failure.
+ */
+void *
+extend(size_t req_bytes)
+{
+ size_t aligned_bytes;
+ size_t len;
+ void *mem;
+ size_t page_mask;
+
+ page_mask = getpagesize() - 1;
+ aligned_bytes = (req_bytes + page_mask) & ~page_mask;
+
+ /* Get current file length. */
+ if ((len = lseek(fd, 0, SEEK_END)) < 0)
+ err(1, "lseek");
+
+ /* Increase file length, filling with zeros. */
+ if (ftruncate(fd, len + aligned_bytes) < 0)
+ err(1, "ftruncate from %lld to %llu", len, len + aligned_bytes);
+
+ /* Increase memory mapping length. */
+ mem = mmap(NULL, req_bytes, PROT_READ | PROT_WRITE, MAP_SHARED, fd, len);
+
+ if (mem == MAP_FAILED)
+ err(1, "mmap %zu bytes @ %llu", req_bytes, len);
+
+ return mem;
+}
+
+/*
+ * Opens a file with a random suffix. Exits on error.
+ */
+void
+open_fd()
+{
+ char *procdir;
+ char procfile[PATH_MAX];
+
+ if ((procdir = getenv("CITRUN_PROCDIR")) == NULL)
+ procdir = "/tmp/citrun";
+
+ if (mkdir(procdir, S_IRWXU) && errno != EEXIST)
+ err(1, "mkdir '%s'", procdir);
+
+ strlcpy(procfile, procdir, PATH_MAX);
+ strlcat(procfile, "/", PATH_MAX);
+ strlcat(procfile, getprogname(), PATH_MAX);
+ strlcat(procfile, "_XXXXXXXXXX", PATH_MAX);
+
+ if ((fd = mkstemp(procfile)) < 0)
+ err(1, "mkstemp");
+}
+
+void
+get_pids(unsigned int pids[3])
+{
+ pids[0] = getpid();
+ pids[1] = getppid();
+ pids[2] = getpgrp();
+}
+
+void
+get_prog_name(char *buf, size_t buf_size)
+{
+ strlcpy(buf, getprogname(), buf_size);
+}
diff --git a/lib_win32.c b/lib_win32.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2016 Kyle Milz <kyle@0x30.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <direct.h> /* getcwd */
+#include <stdio.h> /* stderr */
+#include <windows.h> /* HANDLE, MapViewOfFile, ... */
+#include <io.h>
+#define PATH_MAX 32000
+
+#include "lib_os.h"
+
+
+static HANDLE h = INVALID_HANDLE_VALUE;
+
+static void
+Err(int code, const char *fmt)
+{
+ char buf[256];
+
+ FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 256, NULL);
+
+ fprintf(stderr, "%s: %s", fmt, buf);
+ exit(code);
+}
+
+static HANDLE
+mkstemp(char *template)
+{
+ int i;
+ unsigned int r;
+
+ char chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+ for (i = strlen(template) - 1; i > 0; --i) {
+ if (template[i] != 'X')
+ break;
+
+ if (rand_s(&r)) {
+ fprintf(stderr, "rand failed: %s\n", strerror(errno));
+ exit(1);
+ }
+
+ template[i] = chars[r % (sizeof(chars) - 1)];
+ }
+
+ return CreateFile(
+ template,
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ CREATE_NEW,
+ 0,
+ NULL
+ );
+}
+
+/*
+ * Extends the file and memory mapping length of fd by a requested amount of
+ * bytes (rounded up to the next page size).
+ * Returns a pointer to the extended region on success, exits on failure.
+ */
+void *
+extend(size_t req_bytes)
+{
+ size_t aligned_bytes;
+ size_t len;
+ void *mem;
+ size_t page_mask;
+
+ SYSTEM_INFO system_info;
+ GetSystemInfo(&system_info);
+
+ page_mask = system_info.dwAllocationGranularity - 1;
+ aligned_bytes (req_bytes + page_mask) & ~page_mask;
+
+ HANDLE fm;
+
+ /* Get current file length. */
+ if ((len = GetFileSize(h, NULL)) == INVALID_FILE_SIZE)
+ Err(1, "GetFileSize");
+
+ /* Increase file pointer to new length. */
+ if (SetFilePointer(h, len + aligned_bytes, NULL, FILE_BEGIN)
+ == INVALID_SET_FILE_POINTER)
+ Err(1, "SetFilePointer");
+
+ /* Set new length. */
+ if (SetEndOfFile(h) == 0)
+ Err(1, "SetEndOfFile");
+
+ /* Create a new mapping that's used temporarily. */
+ if ((fm = CreateFileMapping(h, NULL, PAGE_READWRITE, 0, 0, NULL)) == NULL)
+ Err(1, "CreateFileMapping");
+
+ /* Create a new memory mapping for the newly extended space. */
+ if ((mem = MapViewOfFile(fm, FILE_MAP_READ | FILE_MAP_WRITE, 0, len, req_bytes)) == NULL)
+ Err(1, "MapViewOfFile");
+
+ CloseHandle(fm);
+
+ return mem;
+}
+
+/*
+ * Opens a file with a random suffix. Exits on error.
+ */
+void
+open_fd()
+{
+ char *procdir;
+ char procfile[PATH_MAX];
+
+ if ((procdir = getenv("CITRUN_PROCDIR")) == NULL)
+ procdir = "C:\\CItRun";
+
+ if (CreateDirectory(procdir, NULL) == 0 &&
+ GetLastError() != ERROR_ALREADY_EXISTS)
+ Err(1, "CreateDirectory");
+
+ strncpy(procfile, procdir, PATH_MAX);
+ strncat(procfile, "\\", PATH_MAX);
+ strncat(procfile, "program", PATH_MAX);
+ strncat(procfile, "_XXXXXXXXXX", PATH_MAX);
+
+ if ((h = mkstemp(procfile)) == INVALID_HANDLE_VALUE)
+ Err(1, "mkstemp");
+}
+
+void
+get_prog_name(char *buf, size_t buf_size)
+{
+ if (GetModuleFileName(NULL, buf, buf_size) == 0)
+ Err(1, "GetModuleFileName");
+}
+
+void
+get_pids(unsigned int pids[3])
+{
+ pids[0] = getpid();
+}