awesome-client: remove socket code
Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
f79cd42c33
commit
7dbb02adf3
|
@ -66,7 +66,6 @@ set(AWE_SRCS
|
|||
${SOURCE_DIR}/swindow.c
|
||||
${SOURCE_DIR}/common/buffer.c
|
||||
${SOURCE_DIR}/common/atoms.c
|
||||
${SOURCE_DIR}/common/socket.c
|
||||
${SOURCE_DIR}/common/util.c
|
||||
${SOURCE_DIR}/common/version.c
|
||||
${SOURCE_DIR}/common/xembed.c
|
||||
|
@ -78,12 +77,6 @@ set(AWE_SRCS
|
|||
${SOURCE_DIR}/widgets/systray.c
|
||||
${SOURCE_DIR}/widgets/imagebox.c)
|
||||
|
||||
set(AWE_CLIENT_SRCS
|
||||
${SOURCE_DIR}/awesome-client.c
|
||||
${SOURCE_DIR}/common/socket.c
|
||||
${SOURCE_DIR}/common/util.c
|
||||
${SOURCE_DIR}/common/version.c)
|
||||
|
||||
set(AWE_MAN_SRCS
|
||||
${SOURCE_DIR}/awesome.1.txt
|
||||
${SOURCE_DIR}/awsetbg.1.txt
|
||||
|
@ -94,10 +87,6 @@ add_executable(${PROJECT_AWE_NAME}
|
|||
${AWE_SRCS}
|
||||
${BUILD_DIR}/common/tokenize.c)
|
||||
|
||||
add_executable(${PROJECT_AWECLIENT_NAME}
|
||||
${AWE_CLIENT_SRCS}
|
||||
${BUILD_DIR}/common/tokenize.c)
|
||||
|
||||
set_target_properties(${PROJECT_AWE_NAME}
|
||||
PROPERTIES
|
||||
LINK_FLAGS -export-dynamic)
|
||||
|
@ -107,10 +96,6 @@ target_link_libraries(${PROJECT_AWE_NAME}
|
|||
${AWESOME_REQUIRED_LIBRARIES}
|
||||
${AWESOME_OPTIONAL_LIBRARIES})
|
||||
|
||||
target_link_libraries(${PROJECT_AWECLIENT_NAME}
|
||||
${AWESOME_COMMON_REQUIRED_LIBRARIES}
|
||||
${AWESOMECLIENT_LIBRARIES})
|
||||
|
||||
# {{{ Generated sources
|
||||
add_custom_command(
|
||||
COMMAND ${SOURCE_DIR}/build-utils/widgetgen.sh
|
||||
|
@ -171,7 +156,6 @@ add_custom_target(generated_sources
|
|||
file(MAKE_DIRECTORY ${BUILD_DIR}/themes/default)
|
||||
file(MAKE_DIRECTORY ${BUILD_DIR}/themes/sky)
|
||||
add_dependencies(${PROJECT_AWE_NAME} generated_sources)
|
||||
add_dependencies(${PROJECT_AWECLIENT_NAME} generated_sources)
|
||||
# }}}
|
||||
|
||||
# {{{ Version stamp
|
||||
|
@ -183,7 +167,6 @@ if(BUILD_FROM_GIT)
|
|||
WORKING_DIRECTORY ${SOURCE_DIR})
|
||||
|
||||
add_dependencies(${PROJECT_AWE_NAME} version_stamp)
|
||||
add_dependencies(${PROJECT_AWECLIENT_NAME} version_stamp)
|
||||
endif()
|
||||
# }}}
|
||||
|
||||
|
@ -302,8 +285,9 @@ endif()
|
|||
# }}}
|
||||
|
||||
# {{{ Installation
|
||||
install(TARGETS ${PROJECT_AWE_NAME} ${PROJECT_AWECLIENT_NAME} RUNTIME DESTINATION bin)
|
||||
install(TARGETS ${PROJECT_AWE_NAME} RUNTIME DESTINATION bin)
|
||||
install(FILES "utils/awsetbg" DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||
install(FILES "utils/awesome-client" DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||
install(DIRECTORY ${BUILD_DIR}/lib DESTINATION ${AWESOME_DATA_PATH})
|
||||
install(FILES ${AWE_CONF_FILE_DEFAULT} DESTINATION ${AWESOME_SYSCONFDIR}
|
||||
RENAME ${AWE_CONF_FILE})
|
||||
|
|
2
Makefile
2
Makefile
|
@ -7,7 +7,7 @@ else
|
|||
ECHO=@:
|
||||
endif
|
||||
|
||||
TARGETS=awesome awesome-client
|
||||
TARGETS=awesome
|
||||
BUILDLN=build
|
||||
|
||||
all: $(TARGETS) $(BUILDLN) ;
|
||||
|
|
267
awesome-client.c
267
awesome-client.c
|
@ -1,267 +0,0 @@
|
|||
/*
|
||||
* awesome-client.c - awesome client, communicate with socket
|
||||
*
|
||||
* Copyright © 2007-2008 Julien Danjou <julien@danjou.info>
|
||||
* Copyright © 2007 daniel@brinkers.de
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
|
||||
#include "common/socket.h"
|
||||
#include "common/version.h"
|
||||
#include "common/util.h"
|
||||
|
||||
/* GNU/Hurd workaround */
|
||||
#ifndef MSG_NOSIGNAL
|
||||
#define MSG_NOSIGNAL 0
|
||||
#endif
|
||||
|
||||
struct sockaddr_un *addr;
|
||||
int csfd;
|
||||
|
||||
/** Initialize the client and server socket connections.
|
||||
* If something goes wrong, preserves errno.
|
||||
* \return 0 if everything worked, 1 otherwise.
|
||||
*/
|
||||
static bool
|
||||
sockets_init(void)
|
||||
{
|
||||
if((csfd = socket_getclient()) < 0)
|
||||
return false;
|
||||
|
||||
if(!(addr = socket_open(csfd, SOCKET_MODE_CONNECT)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Close the client and server socket connections.
|
||||
*/
|
||||
static void
|
||||
sockets_close(void)
|
||||
{
|
||||
close(csfd);
|
||||
p_delete(&addr);
|
||||
}
|
||||
|
||||
/** Reconnect sockets.
|
||||
*/
|
||||
static void
|
||||
sockets_reconnect(void)
|
||||
{
|
||||
warn("connection lost, reconnecting…");
|
||||
sockets_close();
|
||||
sockets_init();
|
||||
}
|
||||
|
||||
/** Send a message to awesome without handling retries.
|
||||
* \param msg The message.
|
||||
* \param msg_len The message length.
|
||||
* \return The errno of send().
|
||||
*/
|
||||
static int
|
||||
send_msg_raw(const char *msg, ssize_t msg_len)
|
||||
{
|
||||
#ifndef __FreeBSD__
|
||||
return send(csfd, msg, msg_len, MSG_NOSIGNAL | MSG_EOR);
|
||||
#else
|
||||
return send(csfd, msg, msg_len, MSG_NOSIGNAL | MSG_EOF);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Send a message to awesome.
|
||||
* \param msg The message.
|
||||
* \param msg_len The message length.
|
||||
* \return The errno of send().
|
||||
*/
|
||||
static int
|
||||
send_msg(const char *msg, ssize_t msg_len)
|
||||
{
|
||||
int try = 10;
|
||||
|
||||
while(try && send_msg_raw(msg, msg_len) == -1)
|
||||
{
|
||||
switch(errno)
|
||||
{
|
||||
case EPIPE:
|
||||
case ENOTCONN:
|
||||
case ECONNRESET:
|
||||
sockets_reconnect();
|
||||
try--;
|
||||
break;
|
||||
case ENOENT:
|
||||
warn("can't write to %s", addr->sun_path);
|
||||
return errno;
|
||||
default:
|
||||
warn("error sending packet: %s", strerror(errno));
|
||||
return errno;
|
||||
}
|
||||
usleep(100000);
|
||||
}
|
||||
if(!try)
|
||||
{
|
||||
warn("giving up.");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/** Recieve a message from awesome.
|
||||
*/
|
||||
static void
|
||||
recv_msg(void)
|
||||
{
|
||||
ssize_t r;
|
||||
char buf[1024];
|
||||
int try = 10;
|
||||
|
||||
while(try)
|
||||
{
|
||||
r = recv(csfd, buf, sizeof(buf) - 1, MSG_TRUNC | MSG_DONTWAIT);
|
||||
if(r < 0)
|
||||
{
|
||||
if(errno != EAGAIN)
|
||||
return warn("error recieving from UNIX domain socket: %s", strerror(errno));
|
||||
try--;
|
||||
}
|
||||
else
|
||||
break;
|
||||
usleep(100000);
|
||||
}
|
||||
|
||||
if(!try)
|
||||
sockets_reconnect();
|
||||
else if(r > 0)
|
||||
{
|
||||
buf[r] = '\0';
|
||||
puts(buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Print help and exit(2) with given exit_code.
|
||||
* \param exit_code The exit code.
|
||||
* \return Never return.
|
||||
*/
|
||||
static void __attribute__ ((noreturn))
|
||||
exit_help(int exit_code)
|
||||
{
|
||||
FILE *outfile = (exit_code == EXIT_SUCCESS) ? stdout : stderr;
|
||||
fprintf(outfile, "Usage: awesome-client [--version|--help]\n"
|
||||
"In normal operation, give no parameters and issue commands "
|
||||
"on standard input.\n");
|
||||
exit(exit_code);
|
||||
}
|
||||
|
||||
/** Main function of awesome-client.
|
||||
* \param argc Number of args.
|
||||
* \param argv Args array.
|
||||
* \return Value returned by send_msg().
|
||||
*/
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char buf[1024], *msg, *prompt, *display;
|
||||
int ret_value = EXIT_SUCCESS;
|
||||
ssize_t len, msg_len = 1;
|
||||
|
||||
if(argc == 2)
|
||||
{
|
||||
if(!a_strcmp("-v", argv[1]) || !a_strcmp("--version", argv[1]))
|
||||
eprint_version("awesome-client");
|
||||
else if(!a_strcmp("-h", argv[1]) || !a_strcmp("--help", argv[1]))
|
||||
exit_help(EXIT_SUCCESS);
|
||||
}
|
||||
else if(argc > 2)
|
||||
exit_help(EXIT_SUCCESS);
|
||||
|
||||
display = getenv("DISPLAY");
|
||||
|
||||
if(!sockets_init())
|
||||
{
|
||||
warn("can't connect to UNIX domain socket: %s", strerror(errno));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if(isatty(STDIN_FILENO))
|
||||
{
|
||||
a_asprintf(&prompt, "awesome@%s%% ", display ? display : "unknown");
|
||||
while((msg = readline(prompt)))
|
||||
if((msg_len = a_strlen(msg)))
|
||||
{
|
||||
int result;
|
||||
add_history (msg);
|
||||
p_realloc(&msg, msg_len + 2);
|
||||
msg[msg_len] = '\n';
|
||||
msg[msg_len + 1] = '\0';
|
||||
result = send_msg(msg, msg_len + 2);
|
||||
if(result == EXIT_SUCCESS)
|
||||
recv_msg();
|
||||
else if(result == EXIT_FAILURE)
|
||||
break;
|
||||
p_delete(&msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = p_new(char, 1);
|
||||
while(fgets(buf, sizeof(buf), stdin))
|
||||
{
|
||||
len = a_strlen(buf);
|
||||
if(len < 2 && msg_len > 1)
|
||||
{
|
||||
ret_value = send_msg(msg, msg_len);
|
||||
p_delete(&msg);
|
||||
if(ret_value != EXIT_SUCCESS)
|
||||
return ret_value;
|
||||
msg = p_new(char, 1);
|
||||
msg_len = 1;
|
||||
}
|
||||
else if(len > 1)
|
||||
{
|
||||
msg_len += len;
|
||||
p_realloc(&msg, msg_len);
|
||||
a_strncat(msg, msg_len, buf, len);
|
||||
}
|
||||
}
|
||||
if(msg_len > 1)
|
||||
{
|
||||
if((ret_value = send_msg(msg, msg_len)) == EXIT_SUCCESS)
|
||||
recv_msg();
|
||||
}
|
||||
p_delete(&msg);
|
||||
}
|
||||
|
||||
sockets_close();
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
|
@ -63,7 +63,6 @@ awesome_atexit(void)
|
|||
int screen_nbr, nscreens;
|
||||
|
||||
a_dbus_cleanup();
|
||||
luaA_cs_cleanup();
|
||||
|
||||
/* reparent systray windows, otherwise they may die with their master */
|
||||
for(int i = 0; i < globalconf.embedded.len; i++)
|
||||
|
@ -542,8 +541,6 @@ main(int argc, char **argv)
|
|||
xcb_ungrab_server(globalconf.connection);
|
||||
xcb_flush(globalconf.connection);
|
||||
|
||||
luaA_cs_init();
|
||||
|
||||
/* refresh everything before waiting events */
|
||||
awesome_refresh(globalconf.connection);
|
||||
|
||||
|
|
128
common/socket.c
128
common/socket.c
|
@ -1,128 +0,0 @@
|
|||
/*
|
||||
* socket.c - awesome client, communicate with socket, common functions
|
||||
*
|
||||
* Copyright © 2007-2008 Julien Danjou <julien@danjou.info>
|
||||
* Copyright © 2007 daniel@brinkers.de
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
#include "common/socket.h"
|
||||
#include "common/util.h"
|
||||
|
||||
#define CONTROL_UNIX_SOCKET_PATH ".awesome_ctl."
|
||||
|
||||
/** Open a communication socket with awesome.
|
||||
* \param csfd The socket file descriptor.
|
||||
* \param mode The open mode, either Bind or Connect.
|
||||
* \return sockaddr_un Struct ready to be used or NULL if a problem ocurred.
|
||||
*/
|
||||
struct sockaddr_un *
|
||||
socket_open(int csfd, const socket_mode_t mode)
|
||||
{
|
||||
char *host = NULL;
|
||||
int screenp = 0, displayp = 0;
|
||||
bool is_socket_opened = false;
|
||||
ssize_t path_len, len;
|
||||
struct sockaddr_un *addr;
|
||||
const char *fallback[] = { ":HOME", ":TMPDIR", "/tmp", NULL }, *directory;
|
||||
|
||||
addr = p_new(struct sockaddr_un, 1);
|
||||
addr->sun_family = AF_UNIX;
|
||||
|
||||
xcb_parse_display(NULL, &host, &displayp, &screenp);
|
||||
len = a_strlen(host);
|
||||
|
||||
for(int i = 0; fallback[i] && !is_socket_opened; i++)
|
||||
{
|
||||
if(fallback[i][0] == ':')
|
||||
{
|
||||
if(!(directory = getenv(fallback[i] + 1)))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
directory = fallback[i];
|
||||
|
||||
/* + 2 for / and . and \0 */
|
||||
path_len = snprintf(addr->sun_path, sizeof(addr->sun_path),
|
||||
"%s/" CONTROL_UNIX_SOCKET_PATH "%s%s%d",
|
||||
directory, len ? host : "", len ? "." : "",
|
||||
displayp);
|
||||
|
||||
if(path_len < ssizeof(addr->sun_path))
|
||||
switch(mode)
|
||||
{
|
||||
case SOCKET_MODE_BIND:
|
||||
/* Needed for some OSes like Solaris */
|
||||
#ifndef SUN_LEN
|
||||
#define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) + strlen ((ptr)->sun_path))
|
||||
#endif
|
||||
if(!bind(csfd, (const struct sockaddr *) addr, SUN_LEN(addr)))
|
||||
is_socket_opened = true;
|
||||
else if(errno == EADDRINUSE)
|
||||
{
|
||||
if(unlink(addr->sun_path))
|
||||
warn("error unlinking existing file: %s", strerror(errno));
|
||||
if(!bind(csfd, (const struct sockaddr *)addr, SUN_LEN(addr)))
|
||||
is_socket_opened = true;
|
||||
}
|
||||
break;
|
||||
case SOCKET_MODE_CONNECT:
|
||||
if(!connect(csfd, (const struct sockaddr *)addr, sizeof(struct sockaddr_un)))
|
||||
is_socket_opened = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
warn("error: path (using %s) of control UNIX domain socket is too long", directory);
|
||||
}
|
||||
|
||||
p_delete(&host);
|
||||
|
||||
if(!is_socket_opened)
|
||||
p_delete(&addr);
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
/** Get a AF_UNIX socket for communicating with awesome
|
||||
* \return the socket file descriptor
|
||||
*/
|
||||
int
|
||||
socket_getclient(void)
|
||||
{
|
||||
int csfd;
|
||||
#ifndef __FreeBSD__
|
||||
csfd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
|
||||
#else
|
||||
csfd = socket(PF_UNIX, SOCK_STREAM, 0);
|
||||
#endif
|
||||
|
||||
if(csfd < 0)
|
||||
warn("error opening UNIX domain socket: %s", strerror(errno));
|
||||
|
||||
fd_set_close_on_exec(csfd);
|
||||
|
||||
return csfd;
|
||||
}
|
||||
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
* socket.h - awesome socket client header
|
||||
*
|
||||
* Copyright © 2007-2008 Julien Danjou <julien@danjou.info>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef AWESOME_COMMON_SOCKET_H
|
||||
#define AWESOME_COMMON_SOCKET_H
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SOCKET_MODE_BIND,
|
||||
SOCKET_MODE_CONNECT
|
||||
} socket_mode_t;
|
||||
|
||||
struct sockaddr_un *socket_open(const int, const socket_mode_t);
|
||||
int socket_getclient(void);
|
||||
|
||||
#endif
|
||||
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
184
luaa.c
184
luaa.c
|
@ -21,12 +21,6 @@
|
|||
|
||||
#include "common/util.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <ev.h>
|
||||
|
||||
#include <lua.h>
|
||||
|
@ -50,7 +44,6 @@
|
|||
#include "mouse.h"
|
||||
#include "selection.h"
|
||||
#include "window.h"
|
||||
#include "common/socket.h"
|
||||
#include "common/xcursor.h"
|
||||
|
||||
extern awesome_t globalconf;
|
||||
|
@ -78,9 +71,6 @@ extern const struct luaL_reg awesome_wibox_meta[];
|
|||
extern const struct luaL_reg awesome_key_methods[];
|
||||
extern const struct luaL_reg awesome_key_meta[];
|
||||
|
||||
static struct sockaddr_un *addr;
|
||||
static ev_io csio = { .fd = -1 };
|
||||
|
||||
/** Get or set global key bindings.
|
||||
* This binding will be available when you'll press keys on root window.
|
||||
* \param L The Lua VM state.
|
||||
|
@ -917,180 +907,6 @@ bailout:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/** Parse a command.
|
||||
* \param cmd The buffer to parse.
|
||||
* \return the number of elements pushed on the stack by the last statement in cmd.
|
||||
* If there's an error, the message is pushed onto the stack and this returns 1.
|
||||
*/
|
||||
static int
|
||||
luaA_docmd(const char *cmd)
|
||||
{
|
||||
char *p;
|
||||
int newtop, oldtop = lua_gettop(globalconf.L);
|
||||
|
||||
while((p = strchr(cmd, '\n')))
|
||||
{
|
||||
newtop = lua_gettop(globalconf.L);
|
||||
lua_pop(globalconf.L, newtop - oldtop);
|
||||
oldtop = newtop;
|
||||
|
||||
*p = '\0';
|
||||
if(luaL_dostring(globalconf.L, cmd))
|
||||
{
|
||||
warn("error executing Lua code: %s", lua_tostring(globalconf.L, -1));
|
||||
return 1;
|
||||
}
|
||||
cmd = p + 1;
|
||||
}
|
||||
return lua_gettop(globalconf.L) - oldtop;
|
||||
}
|
||||
|
||||
/** Pushes a Lua array containing the top n elements of the stack.
|
||||
* \param n The number of elements to put in the array.
|
||||
*/
|
||||
static void
|
||||
luaA_array(int n)
|
||||
{
|
||||
int i;
|
||||
lua_createtable(globalconf.L, n, 0);
|
||||
lua_insert(globalconf.L, -n - 1);
|
||||
|
||||
for (i = n; i > 0; i--)
|
||||
lua_rawseti(globalconf.L, -i - 1, i);
|
||||
}
|
||||
|
||||
/** Maps the top n elements of the stack to the result of
|
||||
* applying a function to that element.
|
||||
* \param n The number of elements to map.
|
||||
* \luastack
|
||||
* \lparam The function to map the elements by. This should be
|
||||
* at position -(n + 1).
|
||||
*/
|
||||
static void
|
||||
luaA_map(int n)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
lua_pushvalue(globalconf.L, -n - 1); /* copy of the function */
|
||||
lua_pushvalue(globalconf.L, -n - 1); /* value to map */
|
||||
lua_pcall(globalconf.L, 1, 1, 0); /* call function */
|
||||
lua_remove(globalconf.L, -n - 1); /* remove old value */
|
||||
}
|
||||
lua_remove(globalconf.L, -n - 1); /* remove function */
|
||||
}
|
||||
|
||||
static void luaA_conn_cleanup(EV_P_ ev_io *w)
|
||||
{
|
||||
ev_ref(EV_DEFAULT_UC);
|
||||
ev_io_stop(EV_DEFAULT_UC_ w);
|
||||
if(close(w->fd))
|
||||
warn("error closing UNIX domain socket: %s", strerror(errno));
|
||||
p_delete(&w);
|
||||
}
|
||||
|
||||
static void
|
||||
luaA_cb(EV_P_ ev_io *w, int revents)
|
||||
{
|
||||
char buf[1024];
|
||||
int r, els;
|
||||
const char *s;
|
||||
size_t len;
|
||||
|
||||
switch(r = recv(w->fd, buf, sizeof(buf)-1, MSG_TRUNC))
|
||||
{
|
||||
case -1:
|
||||
warn("error reading UNIX domain socket: %s", strerror(errno));
|
||||
case 0: /* 0 bytes are only transferred when the connection is closed */
|
||||
luaA_conn_cleanup(EV_DEFAULT_UC_ w);
|
||||
break;
|
||||
default:
|
||||
if(r >= ssizeof(buf))
|
||||
break;
|
||||
buf[r] = '\0';
|
||||
lua_getglobal(globalconf.L, "table");
|
||||
lua_getfield(globalconf.L, -1, "concat");
|
||||
lua_remove(globalconf.L, -2); /* remove table */
|
||||
|
||||
lua_getglobal(globalconf.L, "tostring");
|
||||
els = luaA_docmd(buf);
|
||||
luaA_map(els); /* map results to strings */
|
||||
luaA_array(els); /* put strings in an array */
|
||||
|
||||
lua_pushstring(globalconf.L, "\t");
|
||||
lua_pcall(globalconf.L, 2, 1, 0); /* concatenate results with tabs */
|
||||
|
||||
s = lua_tolstring(globalconf.L, -1, &len);
|
||||
|
||||
/* ignore ENOENT because the client may not read */
|
||||
if(send(w->fd, s, len, MSG_DONTWAIT) == -1)
|
||||
switch(errno)
|
||||
{
|
||||
case ENOENT:
|
||||
case EAGAIN:
|
||||
break;
|
||||
default:
|
||||
warn("can't send back to client via domain socket: %s", strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
lua_pop(globalconf.L, 1); /* pop the string */
|
||||
}
|
||||
awesome_refresh(globalconf.connection);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
luaA_conn_cb(EV_P_ ev_io *w, int revents)
|
||||
{
|
||||
ev_io *csio_conn = p_new(ev_io, 1);
|
||||
int csfd = accept(w->fd, NULL, NULL);
|
||||
|
||||
if(csfd < 0)
|
||||
return;
|
||||
|
||||
fd_set_close_on_exec(csfd);
|
||||
|
||||
ev_io_init(csio_conn, &luaA_cb, csfd, EV_READ);
|
||||
ev_io_start(EV_DEFAULT_UC_ csio_conn);
|
||||
ev_unref(EV_DEFAULT_UC);
|
||||
}
|
||||
|
||||
void
|
||||
luaA_cs_init(void)
|
||||
{
|
||||
int csfd = socket_getclient();
|
||||
|
||||
if(csfd < 0 || fcntl(csfd, F_SETFD, FD_CLOEXEC) == -1)
|
||||
return;
|
||||
|
||||
if(!(addr = socket_open(csfd, SOCKET_MODE_BIND)))
|
||||
{
|
||||
warn("error binding UNIX domain socket: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
listen(csfd, 10);
|
||||
ev_io_init(&csio, &luaA_conn_cb, csfd, EV_READ);
|
||||
ev_io_start(EV_DEFAULT_UC_ &csio);
|
||||
ev_unref(EV_DEFAULT_UC);
|
||||
}
|
||||
|
||||
void
|
||||
luaA_cs_cleanup(void)
|
||||
{
|
||||
if(csio.fd < 0)
|
||||
return;
|
||||
ev_ref(EV_DEFAULT_UC);
|
||||
ev_io_stop(EV_DEFAULT_UC_ &csio);
|
||||
if(close(csio.fd))
|
||||
warn("error closing UNIX domain socket: %s", strerror(errno));
|
||||
if(unlink(addr->sun_path))
|
||||
warn("error unlinking UNIX domain socket: %s", strerror(errno));
|
||||
p_delete(&addr);
|
||||
csio.fd = -1;
|
||||
}
|
||||
|
||||
void
|
||||
luaA_on_timer(EV_P_ ev_timer *w, int revents)
|
||||
{
|
||||
|
|
2
luaa.h
2
luaa.h
|
@ -385,8 +385,6 @@ luaA_pushpadding(lua_State *L, padding_t *padding)
|
|||
|
||||
void luaA_init(xdgHandle);
|
||||
bool luaA_parserc(xdgHandle, const char *, bool);
|
||||
void luaA_cs_init(void);
|
||||
void luaA_cs_cleanup(void);
|
||||
void luaA_on_timer(EV_P_ ev_timer *, int);
|
||||
int luaA_pushcolor(lua_State *, const xcolor_t *);
|
||||
bool luaA_hasitem(lua_State *, const void *);
|
||||
|
|
Loading…
Reference in New Issue