WIP luac C translation
TODO wait for server to send script exit value
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <lualib.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
// copied from OpenBSD
|
||||
// https://github.com/openbsd/src/blob/master/lib/libc/string/strlcpy.c
|
||||
|
||||
/*
|
||||
* Copy string src to buffer dst of size dsize. At most dsize-1
|
||||
* chars will be copied. Always NUL terminates (unless dsize == 0).
|
||||
* Returns strlen(src); if retval >= dsize, truncation occurred.
|
||||
*/
|
||||
size_t strlcpy(char *dst, const char *src, size_t dsize)
|
||||
{
|
||||
const char *osrc = src;
|
||||
size_t nleft = dsize;
|
||||
|
||||
/* Copy as many bytes as will fit. */
|
||||
if (nleft != 0) {
|
||||
while (--nleft != 0) {
|
||||
if ((*dst++ = *src++) == '\0')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Not enough room in dst, add NUL and traverse rest of src. */
|
||||
if (nleft == 0) {
|
||||
if (dsize != 0)
|
||||
*dst = '\0'; /* NUL-terminate dst */
|
||||
while (*src++)
|
||||
;
|
||||
}
|
||||
|
||||
return(src - osrc - 1); /* count does not include NUL */
|
||||
}
|
||||
|
||||
int open_socket(char * pathname){
|
||||
|
||||
struct sockaddr_un addr;
|
||||
addr.sun_family = AF_UNIX;
|
||||
addr.sun_path[0] = '\0'; /* abstract path */
|
||||
strncpy(&addr.sun_path[1], pathname, sizeof(addr.sun_path) - 2);
|
||||
|
||||
int fd = socket(AF_LOCAL, SOCK_DGRAM, PF_LOCAL);
|
||||
if(fd < 0) {
|
||||
perror("socket");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if((bind(fd, (struct sockaddr *) &addr, sizeof addr)) < 0) {
|
||||
perror("bind");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
int encode_args(char * buf, int len, int argc, char ** argv) {
|
||||
|
||||
char * buf_end = buf + len;
|
||||
char * p = buf;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
p += strlcpy(p, argv[i], buf_end - p);
|
||||
if(p >= buf_end) {
|
||||
fprintf(stderr, "comand line too long\n");
|
||||
exit(1);
|
||||
}
|
||||
p++;
|
||||
}
|
||||
return p - buf;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
#ifdef TEST
|
||||
char *test_args[] = // { "luac", "john", "paul is dead", "ringo" };
|
||||
{ "luac", "hello.lua" };
|
||||
write(1, encode_args(25, 2, test_args), 25);
|
||||
char *test2_args[] = { // this is too long
|
||||
"luac", "0123456789", "0123456789", "012"
|
||||
};
|
||||
write(1, encode_args(25, 4, test2_args), 25);
|
||||
exit(0);
|
||||
#endif
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s pathname.lua\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char * iobuf = (char *) calloc(1024, sizeof(char));
|
||||
if(!iobuf) return 1;
|
||||
int iobuf_len = encode_args(iobuf, 1024, argc, argv);
|
||||
|
||||
int maxnamelen=sizeof (((struct sockaddr_un *) 0)->sun_path);
|
||||
char *sockname = calloc(maxnamelen, 1);
|
||||
pid_t mypid = getpid();
|
||||
memcpy(sockname, (void *) &mypid, sizeof mypid);
|
||||
memcpy(sockname + sizeof mypid, iobuf, maxnamelen - sizeof mypid);
|
||||
|
||||
struct sockaddr_un peer_addr = { AF_UNIX, "/tmp/mysock" };
|
||||
int socket = open_socket(sockname);
|
||||
connect(socket, (struct sockaddr *) &peer_addr, sizeof peer_addr);
|
||||
|
||||
struct msghdr msg = { 0 };
|
||||
struct cmsghdr *cmsg;
|
||||
int myfds[] = {0,1,2};
|
||||
struct iovec iov = {
|
||||
.iov_base = iobuf,
|
||||
.iov_len = iobuf_len
|
||||
};
|
||||
union { /* Ancillary data buffer, wrapped in a union
|
||||
in order to ensure it is suitably aligned */
|
||||
char buf[CMSG_SPACE(sizeof(myfds))];
|
||||
struct cmsghdr align;
|
||||
} u;
|
||||
|
||||
msg.msg_iov = &iov;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control = u.buf;
|
||||
msg.msg_controllen = sizeof(u.buf);
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
cmsg->cmsg_level = SOL_SOCKET;
|
||||
cmsg->cmsg_type = SCM_RIGHTS;
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(myfds));
|
||||
memcpy(CMSG_DATA(cmsg), myfds, sizeof(myfds));
|
||||
|
||||
int bytes = sendmsg(socket, &msg, 0);
|
||||
if(bytes <= 0) {
|
||||
perror("sendmsg");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* FIXME: wait for bytes on socket signifying return value */
|
||||
}
|
||||
Reference in New Issue
Block a user