comparison gtk3/dw.c @ 2857:59106bf7f9f4

GTK2/3/4: Refactor dw_init(), splitting off path detection into _dw_init_path(). Using argv[0] to detect the executable path is very inaccurate, so we will add platform specific code for Linux and FreeBSD to query the executable path. If platform specific code fails, fall back to argv[0] like before.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Tue, 15 Nov 2022 10:18:52 +0000
parents 86286f528adf
children ecfbc48e933a
comparison
equal deleted inserted replaced
2856:de1a0cd26691 2857:59106bf7f9f4
41 #elif defined(USE_WEBKIT) 41 #elif defined(USE_WEBKIT)
42 #include <webkit/webkit.h> 42 #include <webkit/webkit.h>
43 #endif 43 #endif
44 44
45 #include <gdk-pixbuf/gdk-pixbuf.h> 45 #include <gdk-pixbuf/gdk-pixbuf.h>
46
47 #ifdef __FreeBSD__
48 #include <sys/param.h>
49 #include <sys/sysctl.h>
50 #endif
46 51
47 #if !GTK_CHECK_VERSION(3,1,0) 52 #if !GTK_CHECK_VERSION(3,1,0)
48 #error GTK 3.0 is no longer supported, please use 3.2 or later. 53 #error GTK 3.0 is no longer supported, please use 3.2 or later.
49 #endif 54 #endif
50 55
2030 } 2035 }
2031 return dw_init(newthread, argc, argv); 2036 return dw_init(newthread, argc, argv);
2032 } 2037 }
2033 #endif 2038 #endif
2034 2039
2035 /* 2040 void _dw_init_path(char *arg)
2036 * Initializes the Dynamic Windows engine. 2041 {
2037 * Parameters: 2042 char path[PATH_MAX+1] = {0};
2038 * newthread: True if this is the only thread. 2043
2039 * False if there is already a message loop running. 2044 #ifdef __linux__
2040 */ 2045 if(readlink("/proc/self/exe", path, PATH_MAX) == -1)
2041 int dw_init(int newthread, int argc, char *argv[]) 2046 #elif defined(__FreeBSD__)
2042 { 2047 int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
2043 /* Setup the private data directory */ 2048 size_t length = PATH_MAX;
2044 if(argc > 0 && argv[0]) 2049
2045 { 2050 if(sysctl(name, 4, exe, &length, NULL, 0) == -1 || length <= 1)
2046 char *pathcopy = strdup(argv[0]); 2051 #endif
2047 char *pos = strrchr(pathcopy, '/'); 2052 strncpy(path, arg ? arg : "", PATH_MAX);
2048 char *binname = pathcopy; 2053
2054 if(path[0])
2055 {
2056 char *pos = strrchr(path, '/');
2057 char *binname = path;
2049 2058
2050 /* If we have a / then... 2059 /* If we have a / then...
2051 * the binary name should be at the end. 2060 * the binary name should be at the end.
2052 */ 2061 */
2053 if(pos) 2062 if(pos)
2056 *pos = 0; 2065 *pos = 0;
2057 } 2066 }
2058 2067
2059 if(*binname) 2068 if(*binname)
2060 { 2069 {
2061 char *binpos = strstr(pathcopy, "/bin"); 2070 char *binpos = strstr(path, "/bin");
2062 2071
2063 if(binpos) 2072 if(binpos)
2064 strncpy(_dw_share_path, pathcopy, (size_t)(binpos - pathcopy)); 2073 strncpy(_dw_share_path, path, (size_t)(binpos - path));
2065 else 2074 else
2066 strcpy(_dw_share_path, "/usr/local"); 2075 strcpy(_dw_share_path, "/usr/local");
2067 strcat(_dw_share_path, "/share/"); 2076 strcat(_dw_share_path, "/share/");
2068 strcat(_dw_share_path, binname); 2077 strcat(_dw_share_path, binname);
2069 #if GLIB_CHECK_VERSION(2,28,0) 2078 #if GLIB_CHECK_VERSION(2,28,0)
2072 /* If we have a binary name, use that for the Application ID instead. */ 2081 /* If we have a binary name, use that for the Application ID instead. */
2073 snprintf(_dw_app_id, _DW_APP_ID_SIZE, "%s.%s", DW_APP_DOMAIN_DEFAULT, binname); 2082 snprintf(_dw_app_id, _DW_APP_ID_SIZE, "%s.%s", DW_APP_DOMAIN_DEFAULT, binname);
2074 } 2083 }
2075 #endif 2084 #endif
2076 } 2085 }
2077 if(pathcopy)
2078 free(pathcopy);
2079 } 2086 }
2080 /* If that failed... just get the current directory */ 2087 /* If that failed... just get the current directory */
2081 if(!_dw_share_path[0] && !getcwd(_dw_share_path, PATH_MAX)) 2088 if(!_dw_share_path[0] && !getcwd(_dw_share_path, PATH_MAX))
2082 _dw_share_path[0] = '/'; 2089 _dw_share_path[0] = '/';
2090 }
2091
2092 /*
2093 * Initializes the Dynamic Windows engine.
2094 * Parameters:
2095 * newthread: True if this is the only thread.
2096 * False if there is already a message loop running.
2097 */
2098 int dw_init(int newthread, int argc, char *argv[])
2099 {
2100 /* Setup the private data directory */
2101 _dw_init_path(argc > 0 ? argv[0] : NULL);
2083 2102
2084 #if !GLIB_CHECK_VERSION(2,31,0) 2103 #if !GLIB_CHECK_VERSION(2,31,0)
2085 g_thread_init(NULL); 2104 g_thread_init(NULL);
2086 #endif 2105 #endif
2087 2106