load argv[1] as script and remove default paths
This commit is contained in:
@@ -7,6 +7,7 @@ riverguile \- scheme powered scripting layer for river
|
|||||||
.
|
.
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.SY riverguile
|
.SY riverguile
|
||||||
|
path-to-script
|
||||||
.YS
|
.YS
|
||||||
.
|
.
|
||||||
.
|
.
|
||||||
@@ -17,20 +18,29 @@ Scripting layer for the
|
|||||||
Wayland server.
|
Wayland server.
|
||||||
Allows the user to send commands to the Wayland server (probably river) and
|
Allows the user to send commands to the Wayland server (probably river) and
|
||||||
install handlers for events from a scheme script.
|
install handlers for events from a scheme script.
|
||||||
|
The sheme implementation is provided by
|
||||||
|
.BR guile (1).
|
||||||
.P
|
.P
|
||||||
By default, riverguile will exit after the script has been loaded and evaluated.
|
The canonical way to use riverguile is as an interpreter for the river init
|
||||||
If certain handlers are installed it will run continously.
|
script.
|
||||||
|
To do so place the following expression at the very top of your init script:
|
||||||
.P
|
.P
|
||||||
Uppon launch, riverguile tries to load the script from the following paths
|
.RS
|
||||||
in the given order:
|
.EX
|
||||||
.IP \(bu 2
|
#!/bin/env riverguile
|
||||||
\fBlayout.scm\fR
|
!#
|
||||||
.IP \(bu 2
|
.EE
|
||||||
\fB$XDG_CONFIG_HOME/river/layout.scm\fR
|
.RE
|
||||||
.IP \(bu 2
|
.P
|
||||||
\fB$HOME/.config/river/layout.scm\fR
|
Do not leave out the second line, as the octothorpe plus exlamation-mark
|
||||||
.IP \(bu 2
|
combination indicates a multi-line comment in scheme.
|
||||||
\fB/etc/riverguile/layout.scm\fR
|
Do not forget to mark your init script as executable.
|
||||||
|
Your custom scheme code to configure the river session may follow after these
|
||||||
|
two lines.
|
||||||
|
.P
|
||||||
|
By default, riverguile will exit after the script has been loaded.
|
||||||
|
However if certain handlers are installed it will run continously to provide
|
||||||
|
that functionality.
|
||||||
.
|
.
|
||||||
.
|
.
|
||||||
.SH COMMANDS
|
.SH COMMANDS
|
||||||
|
|||||||
@@ -255,79 +255,69 @@ static char *formatted_buffer (const char *fmt, ...)
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *get_script_path (void)
|
static char *get_script_path (char *relative_path)
|
||||||
{
|
{
|
||||||
struct {
|
assert(relative_path != NULL);
|
||||||
const char *fmt;
|
|
||||||
bool needs_env;
|
|
||||||
const char *env;
|
|
||||||
} paths[] = {
|
|
||||||
{ .fmt = "layout.scm", .needs_env = false, .env = NULL },
|
|
||||||
{ .fmt = "%s/riverguile/layout.scm", .needs_env = true, .env = getenv("XDG_CONFIG_HOME") },
|
|
||||||
{ .fmt = "%s/river/layout.scm", .needs_env = true, .env = getenv("XDG_CONFIG_HOME") },
|
|
||||||
{ .fmt = "%s/.config/riverguile/layout.scm", .needs_env = true, .env = getenv("HOME") },
|
|
||||||
{ .fmt = "%s/.config/river/layout.scm", .needs_env = true, .env = getenv("HOME") },
|
|
||||||
{ .fmt = "/etc/riverguile/layout.scm", .needs_env = false, .env = NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
char *path = NULL;
|
char *path = NULL;
|
||||||
for (size_t i = 0; i < (sizeof(paths) / sizeof(paths[0])); i++)
|
if ( relative_path[0] == '/' )
|
||||||
|
path = formatted_buffer("%s", relative_path);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if ( path != NULL )
|
/* When scm_primitive_load_path() receives a relative path, it
|
||||||
|
* tries to look it up in the guile module path. So we must
|
||||||
|
* always provide it an absolute path.
|
||||||
|
*/
|
||||||
|
char buffer[4 * 1024];
|
||||||
|
char *cwd = getcwd(buffer, 4 * 1024);
|
||||||
|
if ( cwd == NULL )
|
||||||
{
|
{
|
||||||
free(path);
|
fprintf(stderr, "ERROR: getcwd: %s\n", strerror(errno));
|
||||||
path = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Path needs env var, but it is not set. */
|
|
||||||
if ( paths[i].needs_env && paths[i].env == NULL )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
path = formatted_buffer(paths[i].fmt, paths[i].env);
|
|
||||||
if ( path == NULL )
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* Does the path exist? */
|
|
||||||
if ( access(path, F_OK) != 0 )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Is it readable? */
|
|
||||||
if ( access(path, R_OK) != 0 )
|
|
||||||
{
|
|
||||||
fprintf(stderr, "ERROR: Script '%s' exists, but is not readable.\n", path);
|
|
||||||
free(path);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return path;
|
path = formatted_buffer("%s/%s", cwd, relative_path);
|
||||||
|
}
|
||||||
|
if ( path == NULL )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if ( access(path, R_OK) != 0 )
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: Script '%s' is not readable.\n", path);
|
||||||
|
free(path);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( path != NULL )
|
return path;
|
||||||
free(path);
|
|
||||||
|
|
||||||
fputs("ERROR: No script found.\n", stderr);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
if ( argc != 2
|
||||||
|
|| strcmp(argv[1], "--help") == 0
|
||||||
|
|| strcmp(argv[1], "-h") == 0
|
||||||
|
|| strcmp(argv[1], "-?") == 0 )
|
||||||
|
{
|
||||||
|
fprintf(stderr, "USAGE: %s path-to-script\n", argv[0]);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
fputs("INFO: Welcome to riverguile!\n", stderr);
|
fputs("INFO: Welcome to riverguile!\n", stderr);
|
||||||
|
|
||||||
signal(SIGSEGV, handle_error);
|
signal(SIGSEGV, handle_error);
|
||||||
signal(SIGFPE, handle_error);
|
signal(SIGFPE, handle_error);
|
||||||
signal(SIGINT, handle_interrupt);
|
signal(SIGINT, handle_interrupt);
|
||||||
|
|
||||||
wl_list_init(&context.outputs);
|
context.path = get_script_path(argv[1]);
|
||||||
wl_list_init(&context.seats);
|
|
||||||
|
|
||||||
// TODO use argv[1] if present
|
|
||||||
context.path = get_script_path();
|
|
||||||
if ( context.path == NULL )
|
if ( context.path == NULL )
|
||||||
{
|
{
|
||||||
context.ret = EXIT_FAILURE;
|
context.ret = EXIT_FAILURE;
|
||||||
goto early_exit;
|
goto early_exit;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "INFO: Found script: %s\n", context.path);
|
fprintf(stderr, "INFO: Using script: %s\n", context.path);
|
||||||
|
|
||||||
|
wl_list_init(&context.outputs);
|
||||||
|
wl_list_init(&context.seats);
|
||||||
|
|
||||||
/* We query the display name here instead of letting wl_display_connect()
|
/* We query the display name here instead of letting wl_display_connect()
|
||||||
* figure it out itself, because libwayland (for legacy reasons) falls
|
* figure it out itself, because libwayland (for legacy reasons) falls
|
||||||
|
|||||||
Reference in New Issue
Block a user