From: Carl Worth Date: Mon, 23 Sep 2013 14:48:27 +0000 (-0700) Subject: Rename glaze.c to libglaze.c X-Git-Url: https://git.cworth.org/git?p=glaze;a=commitdiff_plain;h=f5afe7a34b5f7adc8451f01db92be1de5f0830af Rename glaze.c to libglaze.c This is in preparation for a new main program named, simply, glaze which will be implemented in glaze.c. --- diff --git a/Makefile b/Makefile index 0984ce3..5ab342a 100644 --- a/Makefile +++ b/Makefile @@ -44,10 +44,10 @@ all: $(TARGETS) GLAZE_CFLAGS = $(CFLAGS) $(WARN_CFLAGS) -$(LIBGLAZE_32_LIBNAME): glaze.c +$(LIBGLAZE_32_LIBNAME): libglaze.c $(CC) $(GLAZE_CFLAGS) -m32 -fPIC -shared -Wl,-Bsymbolic,-soname=$(LIBGLAZE_SONAME) -ldl -ltalloc -o $@ $< -$(LIBGLAZE_LIBNAME): glaze.c +$(LIBGLAZE_LIBNAME): libglaze.c $(CC) $(GLAZE_CFLAGS) -m64 -fPIC -shared -Wl,-Bsymbolic,-soname=$(LIBGLAZE_SONAME) -ldl -ltalloc -o $@ $< $(LIB64_DIR)/libGL.so.1: glaze-gl.c diff --git a/glaze.c b/glaze.c deleted file mode 100644 index 8377d84..0000000 --- a/glaze.c +++ /dev/null @@ -1,314 +0,0 @@ -/* Copyright © 2013, Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "config.h" - -#define _GNU_SOURCE -#include - -#include "glaze.h" - -#include - -#include -#include -#include -#include -#include -#include -#include - -/* For PATH_MAX */ -#include - -void * -glaze_lookup (char *function) -{ - static void *libgl_handle = NULL; - void *ret; - - if (libgl_handle == NULL) { - const char *path; - - path = getenv ("GLAZE_LIBGL"); - if (path == NULL) { - fprintf (stderr, "GLAZE_LIBGL unset. " - "Please set to path of libGL.so under glaze.\n" - ); - exit (1); - } - - libgl_handle = dlopen (path, RTLD_LAZY | RTLD_GLOBAL); - if (libgl_handle == NULL) { - fprintf (stderr, "glaze_lookup: Error: Failed to dlopen %s\n", path); - exit (1); - } - } - - ret = dlsym (libgl_handle, function); - - if (ret == NULL) { - fprintf (stderr, "Error: glaze_lookup failed to dlsym %s\n", - function); - exit (1); - } - - return ret; -} - -/* Terminate a string representing a filename at the final '/' to - * eliminate the final filename component, (leaving only the directory - * portions of the original path). - * - * Notes: A path containing no '/' character will not be modified. - * A path consisting only of "/" will not be modified. - */ -static void -chop_trailing_path_component (char *path) -{ - char *slash; - - slash = strrchr (path, '/'); - - if (slash == NULL) - return; - - if (slash == path) - return; - - *slash = '\0'; -} - -/* Find the absolute path of the currently executing binary. - * - * Returns: a string talloc'ed to 'ctx' - */ -static char * -get_bin_name (void *ctx) -{ - const char *link = "/proc/self/exe"; - char *name; - - /* Yes, PATH_MAX is cheesy. I would have preferred to have - * used lstat and read the resulting st_size, but everytime I - * did that with /proc/self/exe I got a value of 0, (whereas - * with a "real" symbolic link I make myself I get the length - * of the filename being linked to). Go figure. */ - int name_len = PATH_MAX + 1; - - name = talloc_size (ctx, name_len); - if (name == NULL) { - fprintf (stderr, "Out of memory.\n"); - exit (1); - } - - name_len = readlink (link, name, name_len - 1); - if (name_len < 0) { - fprintf (stderr, "Failed to readlink %s: %s\n", link, - strerror (errno)); - exit (1); - } - - name[name_len] = '\0'; - - return name; -} - -/* Does path exist? */ -static int -exists (const char *path) -{ - struct stat st; - int err; - - err = stat (path, &st); - - /* Failed to stat. It either doesn't exist, or might as well not. */ - if (err == -1) - return 0; - - return 1; -} - -/* Execute "program" in a pipe, reads its first line of output on - * stdout, and returns that as a string (discarding any further - * output). - * - * Returns NULL if the program failed to execute for any reason. - * - * NOTE: The caller should free() the returned string when done with - * it. - */ -static char * -read_process_output_one_line (const char *program) -{ - FILE *process; - int status; - char *line = NULL; - size_t len = 0; - ssize_t bytes_read; - - process = popen (program, "r"); - if (process == NULL) - return NULL; - - bytes_read = getline (&line, &len, process); - - status = pclose (process); - if (! WIFEXITED (status)) - return NULL; - - if (WEXITSTATUS (status)) - return NULL; - - if (bytes_read == -1) - return NULL; - - if (bytes_read) { - if (line[strlen(line)-1] == '\n') - line[strlen(line)-1] = '\0'; - return line; - } else { - return NULL; - } -} - - -/* Look for "wrapper" library next to currently executing binary. - * - * If "wrapper" is an absolute path, return it directly. - * - * Otherwise, ("wrapper" is relative), look for an existing file named - * "wrapper" in the same directory as the currently executing binary, - * (as determined by /proc/self/exe). If that file exists, return its - * path. - * - * Otherwise, return the original, relative "wrapper". - */ -static const char * -resolve_wrapper_path (void *ctx, const char *wrapper) -{ - char *bin_path, *lib_path; - - if (*wrapper == '/') - return wrapper; - - bin_path = get_bin_name (ctx); - - chop_trailing_path_component (bin_path); - - lib_path = talloc_asprintf (ctx, "%s/%s", bin_path, wrapper); - - talloc_free (bin_path); - - if (exists (lib_path)) - return lib_path; - - talloc_free (lib_path); - - return wrapper; -} - -/* Return path to directory containing Glaze wrapper's libGL.so.1 - * suitable for use in LD_PRELOAD or LD_LIBRARY_PATH. Note that the - * path returned may not be a full path to the directory but may end - * with "$LIB" which will be expanded by the Linux dynamic linker to - * an architecture specific string (such as "lib/i386-linux-gnu" or - * "lib/x86_64-linux-gnu"). */ -static const char * -find_glaze_libgl_dir (void) -{ - return CONFIG_LIBDIR "/glaze/$LIB"; -} - -void -glaze_execute (int argc, char *argv[], const char *wrapper) -{ - void *ctx = talloc_new (NULL); - int i; - - /* Set GLAZE_WRAPPER to absolute path of wrapper library */ - if (wrapper == NULL || *wrapper == '\0') { - fprintf (stderr, "Error: glaze_execute called with empty wrapper library.\n"); - return; - } - - wrapper = resolve_wrapper_path (ctx, wrapper); - - setenv ("GLAZE_WRAPPER", wrapper, 1); - - /* Ensure GLAZE_LIBGL is set. If not, set GLAZE_LIBGL_32_AUTO - * and GLAZE_LIBGL_64_AUTO - * - * Note that we must do this before setting LD_LIBRARY_PATH, - * since after that, of course we would find Glaze's wrapper - * libGL.so.1. */ - if (getenv ("GLAZE_LIBGL") == NULL) { - char *libgl_path; - - libgl_path = read_process_output_one_line ("glaze-find-libgl-32"); - if (libgl_path) { - setenv ("GLAZE_LIBGL_32_AUTO", libgl_path, 1); - free (libgl_path); - } - - libgl_path = read_process_output_one_line ("glaze-find-libgl-64"); - if (libgl_path) { - setenv ("GLAZE_LIBGL_64_AUTO", libgl_path, 1); - free (libgl_path); - } - } - - /* Set LD_LIBRARY_PATH to include glaze's own libGL.so */ - const char *glaze_libgl_dir, *ld_library_path; - - glaze_libgl_dir = find_glaze_libgl_dir (); - - ld_library_path = getenv ("LD_LIBRARY_PATH"); - - if (ld_library_path == NULL) - ld_library_path = glaze_libgl_dir; - else - ld_library_path = talloc_asprintf (ctx, "%s:%s", - glaze_libgl_dir, - ld_library_path); - - setenv ("LD_LIBRARY_PATH", ld_library_path, 1); - - talloc_free (ctx); - - /* Execute program */ - execvp (argv[0], argv); - - /* If execvp returns, something went wrong. */ - fprintf (stderr, "Error: Failed to exec:"); - for (i = 0; i < argc; i++) - fprintf (stderr, " %s", argv[i]); - fprintf (stderr, "\n"); - - return; -} - -void -glaze_set_first_gl_call_callback (const char *function_name) -{ - setenv ("GLAZE_FIRST_GL_CALL_CALLBACK", function_name, 1); -} diff --git a/libglaze.c b/libglaze.c new file mode 100644 index 0000000..8377d84 --- /dev/null +++ b/libglaze.c @@ -0,0 +1,314 @@ +/* Copyright © 2013, Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "config.h" + +#define _GNU_SOURCE +#include + +#include "glaze.h" + +#include + +#include +#include +#include +#include +#include +#include +#include + +/* For PATH_MAX */ +#include + +void * +glaze_lookup (char *function) +{ + static void *libgl_handle = NULL; + void *ret; + + if (libgl_handle == NULL) { + const char *path; + + path = getenv ("GLAZE_LIBGL"); + if (path == NULL) { + fprintf (stderr, "GLAZE_LIBGL unset. " + "Please set to path of libGL.so under glaze.\n" + ); + exit (1); + } + + libgl_handle = dlopen (path, RTLD_LAZY | RTLD_GLOBAL); + if (libgl_handle == NULL) { + fprintf (stderr, "glaze_lookup: Error: Failed to dlopen %s\n", path); + exit (1); + } + } + + ret = dlsym (libgl_handle, function); + + if (ret == NULL) { + fprintf (stderr, "Error: glaze_lookup failed to dlsym %s\n", + function); + exit (1); + } + + return ret; +} + +/* Terminate a string representing a filename at the final '/' to + * eliminate the final filename component, (leaving only the directory + * portions of the original path). + * + * Notes: A path containing no '/' character will not be modified. + * A path consisting only of "/" will not be modified. + */ +static void +chop_trailing_path_component (char *path) +{ + char *slash; + + slash = strrchr (path, '/'); + + if (slash == NULL) + return; + + if (slash == path) + return; + + *slash = '\0'; +} + +/* Find the absolute path of the currently executing binary. + * + * Returns: a string talloc'ed to 'ctx' + */ +static char * +get_bin_name (void *ctx) +{ + const char *link = "/proc/self/exe"; + char *name; + + /* Yes, PATH_MAX is cheesy. I would have preferred to have + * used lstat and read the resulting st_size, but everytime I + * did that with /proc/self/exe I got a value of 0, (whereas + * with a "real" symbolic link I make myself I get the length + * of the filename being linked to). Go figure. */ + int name_len = PATH_MAX + 1; + + name = talloc_size (ctx, name_len); + if (name == NULL) { + fprintf (stderr, "Out of memory.\n"); + exit (1); + } + + name_len = readlink (link, name, name_len - 1); + if (name_len < 0) { + fprintf (stderr, "Failed to readlink %s: %s\n", link, + strerror (errno)); + exit (1); + } + + name[name_len] = '\0'; + + return name; +} + +/* Does path exist? */ +static int +exists (const char *path) +{ + struct stat st; + int err; + + err = stat (path, &st); + + /* Failed to stat. It either doesn't exist, or might as well not. */ + if (err == -1) + return 0; + + return 1; +} + +/* Execute "program" in a pipe, reads its first line of output on + * stdout, and returns that as a string (discarding any further + * output). + * + * Returns NULL if the program failed to execute for any reason. + * + * NOTE: The caller should free() the returned string when done with + * it. + */ +static char * +read_process_output_one_line (const char *program) +{ + FILE *process; + int status; + char *line = NULL; + size_t len = 0; + ssize_t bytes_read; + + process = popen (program, "r"); + if (process == NULL) + return NULL; + + bytes_read = getline (&line, &len, process); + + status = pclose (process); + if (! WIFEXITED (status)) + return NULL; + + if (WEXITSTATUS (status)) + return NULL; + + if (bytes_read == -1) + return NULL; + + if (bytes_read) { + if (line[strlen(line)-1] == '\n') + line[strlen(line)-1] = '\0'; + return line; + } else { + return NULL; + } +} + + +/* Look for "wrapper" library next to currently executing binary. + * + * If "wrapper" is an absolute path, return it directly. + * + * Otherwise, ("wrapper" is relative), look for an existing file named + * "wrapper" in the same directory as the currently executing binary, + * (as determined by /proc/self/exe). If that file exists, return its + * path. + * + * Otherwise, return the original, relative "wrapper". + */ +static const char * +resolve_wrapper_path (void *ctx, const char *wrapper) +{ + char *bin_path, *lib_path; + + if (*wrapper == '/') + return wrapper; + + bin_path = get_bin_name (ctx); + + chop_trailing_path_component (bin_path); + + lib_path = talloc_asprintf (ctx, "%s/%s", bin_path, wrapper); + + talloc_free (bin_path); + + if (exists (lib_path)) + return lib_path; + + talloc_free (lib_path); + + return wrapper; +} + +/* Return path to directory containing Glaze wrapper's libGL.so.1 + * suitable for use in LD_PRELOAD or LD_LIBRARY_PATH. Note that the + * path returned may not be a full path to the directory but may end + * with "$LIB" which will be expanded by the Linux dynamic linker to + * an architecture specific string (such as "lib/i386-linux-gnu" or + * "lib/x86_64-linux-gnu"). */ +static const char * +find_glaze_libgl_dir (void) +{ + return CONFIG_LIBDIR "/glaze/$LIB"; +} + +void +glaze_execute (int argc, char *argv[], const char *wrapper) +{ + void *ctx = talloc_new (NULL); + int i; + + /* Set GLAZE_WRAPPER to absolute path of wrapper library */ + if (wrapper == NULL || *wrapper == '\0') { + fprintf (stderr, "Error: glaze_execute called with empty wrapper library.\n"); + return; + } + + wrapper = resolve_wrapper_path (ctx, wrapper); + + setenv ("GLAZE_WRAPPER", wrapper, 1); + + /* Ensure GLAZE_LIBGL is set. If not, set GLAZE_LIBGL_32_AUTO + * and GLAZE_LIBGL_64_AUTO + * + * Note that we must do this before setting LD_LIBRARY_PATH, + * since after that, of course we would find Glaze's wrapper + * libGL.so.1. */ + if (getenv ("GLAZE_LIBGL") == NULL) { + char *libgl_path; + + libgl_path = read_process_output_one_line ("glaze-find-libgl-32"); + if (libgl_path) { + setenv ("GLAZE_LIBGL_32_AUTO", libgl_path, 1); + free (libgl_path); + } + + libgl_path = read_process_output_one_line ("glaze-find-libgl-64"); + if (libgl_path) { + setenv ("GLAZE_LIBGL_64_AUTO", libgl_path, 1); + free (libgl_path); + } + } + + /* Set LD_LIBRARY_PATH to include glaze's own libGL.so */ + const char *glaze_libgl_dir, *ld_library_path; + + glaze_libgl_dir = find_glaze_libgl_dir (); + + ld_library_path = getenv ("LD_LIBRARY_PATH"); + + if (ld_library_path == NULL) + ld_library_path = glaze_libgl_dir; + else + ld_library_path = talloc_asprintf (ctx, "%s:%s", + glaze_libgl_dir, + ld_library_path); + + setenv ("LD_LIBRARY_PATH", ld_library_path, 1); + + talloc_free (ctx); + + /* Execute program */ + execvp (argv[0], argv); + + /* If execvp returns, something went wrong. */ + fprintf (stderr, "Error: Failed to exec:"); + for (i = 0; i < argc; i++) + fprintf (stderr, " %s", argv[i]); + fprintf (stderr, "\n"); + + return; +} + +void +glaze_set_first_gl_call_callback (const char *function_name) +{ + setenv ("GLAZE_FIRST_GL_CALL_CALLBACK", function_name, 1); +}