WIP luac C translation

TODO wait for server to send script exit value
This commit is contained in:
2026-05-17 23:57:42 +01:00
parent e3bf89dcdf
commit 7fdcc89ec1
+144
View File
@@ -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 */
}