reimplement glib functions

This commit is contained in:
slonkazoid 2024-09-11 22:56:53 +03:00
parent 5740bcb961
commit 4f90f08491
No known key found for this signature in database
6 changed files with 126 additions and 6 deletions

10
include/env.h Normal file
View file

@ -0,0 +1,10 @@
#ifndef _SWAY_ENV_H
#define _SWAY_ENV_H
void env_free(char **envp);
char **env_get_envp();
char **env_setenv(char **envp, char *name, char *value);
#endif

View file

@ -1,7 +1,7 @@
#define _POSIX_C_SOURCE 200809L #define _POSIX_C_SOURCE 200809L
#include <stdlib.h> #include <stdlib.h>
#include <glib.h>
#include "sway/commands.h" #include "sway/commands.h"
#include "env.h"
extern char **child_envp; extern char **child_envp;
@ -13,7 +13,7 @@ struct cmd_results *cmd_env(int argc, char **argv) {
// g_environ_setenv never returns NULL // g_environ_setenv never returns NULL
// https://github.com/GNOME/glib/blob/8810cf7a/glib/genviron.c#L129 // https://github.com/GNOME/glib/blob/8810cf7a/glib/genviron.c#L129
child_envp = g_environ_setenv(child_envp, argv[0], argv[1], 1); child_envp = env_setenv(child_envp, argv[0], argv[1]);
return cmd_results_new(CMD_SUCCESS, NULL); return cmd_results_new(CMD_SUCCESS, NULL);
} }

View file

@ -4,7 +4,6 @@
#include <sys/wait.h> #include <sys/wait.h>
#include <unistd.h> #include <unistd.h>
#include <signal.h> #include <signal.h>
#include <glib.h>
#include "sway/commands.h" #include "sway/commands.h"
#include "sway/config.h" #include "sway/config.h"
#include "sway/server.h" #include "sway/server.h"

110
sway/env.c Normal file
View file

@ -0,0 +1,110 @@
#define _POSIX_C_SOURCE 200809L
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern char **environ;
int _env_var_name_eq(char *env_name, char *cmp) {
size_t i = 0;
int reached_eq;
while (1) {
char current_char = env_name[i];
char cmp_char = cmp[i];
int is_eq = current_char == '=';
int is_null = current_char == '\0';
if (is_eq) reached_eq = 1;
if (is_null && !reached_eq) return 0;
if (is_eq && cmp_char == '\0') return 1;
if (is_eq || cmp_char == '\0') return 0;
if (current_char != cmp_char) return 0;
i++;
}
}
typedef struct {
char *ptr;
size_t idx;
} _env_info;
_env_info _env_get(char **envp, char *name) {
char *strp;
size_t i = 0;
while ((strp = envp[i]) != NULL) {
if (_env_var_name_eq(strp, name)) return (_env_info){strp, i};
i++;
}
return (_env_info){NULL, 0};
}
size_t _env_len(char **envp) {
char *strp;
size_t i = 0;
while ((strp = envp[i]) != NULL) {
i++;
}
return i;
}
char **_env_clone(char **envp, size_t reserve) {
char **new_envp = calloc(_env_len(envp) + 1 + reserve, sizeof(char *));
char *strp;
size_t i = 0;
while ((strp = envp[i]) != NULL) {
size_t n = strlen(strp) + 1;
char *new_strp = malloc(n);
memcpy(new_strp, strp, n);
new_envp[i] = new_strp;
i++;
}
return new_envp;
}
void env_free(char **envp) {
char *strp;
size_t i = 0;
while ((strp = envp[i]) != NULL) {
free(strp);
i++;
}
free(envp);
}
// copy the global environment array into a newly-allocated one
// you are responsible for deallocating it after use
char **env_get_envp() { return _env_clone(environ, 0); }
// use env_get_envp() to acquire an envp
// might clone and deallocate the given envp
char **env_setenv(char **envp, char *name, char *value) {
size_t name_len = strlen(name);
size_t value_len = strlen(value);
char *newp = malloc(name_len + value_len + 2);
memcpy(newp, name, name_len);
memcpy(newp + name_len + 1, value, value_len);
newp[name_len] = '=';
newp[name_len + value_len + 1] = '\0';
_env_info existing = _env_get(envp, name);
if (existing.ptr != NULL) {
free(existing.ptr);
envp[existing.idx] = newp;
return envp;
} else {
char **new_envp = _env_clone(envp, 1);
new_envp[_env_len(envp)] = newp;
env_free(envp);
return new_envp;
}
}

View file

@ -1,6 +1,5 @@
#include <getopt.h> #include <getopt.h>
#include <pango/pangocairo.h> #include <pango/pangocairo.h>
#include <glib.h>
#include <signal.h> #include <signal.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
@ -25,6 +24,7 @@
#include "log.h" #include "log.h"
#include "stringop.h" #include "stringop.h"
#include "util.h" #include "util.h"
#include "env.h"
static bool terminate_request = false; static bool terminate_request = false;
static int exit_value = 0; static int exit_value = 0;
@ -350,8 +350,8 @@ int main(int argc, char **argv) {
ipc_init(&server); ipc_init(&server);
setenv("WAYLAND_DISPLAY", server.socket, true); setenv("WAYLAND_DISPLAY", server.socket, true);
// g_get_environ creates a newly-allocated environment buffer // env_get_envp creates a newly-allocated environment buffer
child_envp = g_get_environ(); child_envp = env_get_envp();
if (!load_main_config(config_path, false, false)) { if (!load_main_config(config_path, false, false)) {
sway_terminate(EXIT_FAILURE); sway_terminate(EXIT_FAILURE);
goto shutdown; goto shutdown;

View file

@ -3,6 +3,7 @@ sway_sources = files(
'config.c', 'config.c',
'criteria.c', 'criteria.c',
'decoration.c', 'decoration.c',
'env.c',
'ipc-json.c', 'ipc-json.c',
'ipc-server.c', 'ipc-server.c',
'lock.c', 'lock.c',