Something bare.
authorviric@llimona
Fri, 14 Sep 2007 20:48:13 +0200
changeset 0 3bbacfe6797a
child 1 473a340551e3
Something bare.
Makefile
dicta.c
dicta.h
error.c
usocket.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile	Fri Sep 14 20:48:13 2007 +0200
@@ -0,0 +1,1 @@
+dicta: dicta.o usocket.o error.o
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dicta.c	Fri Sep 14 20:48:13 2007 +0200
@@ -0,0 +1,127 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "dicta.h"
+
+static int max(int a, int b)
+{
+    if (a > b)
+        return a;
+    return b;
+}
+
+void fork_app(int *opipe, char * const command[])
+{
+    int p_input[2]; /* from mpg321 to us */
+    int p_output[2]; /* from us to mpg321 */
+    int pid;
+    int res;
+
+    pipe(p_input);
+    pipe(p_output);
+    opipe[0] = p_input[0]; /* For us to read */
+    opipe[1] = p_output[1]; /* For us to write */
+
+    pid = fork();
+
+    switch(pid)
+    {
+        case 0: /* child */
+            close(p_input[0]);
+            res = dup2(p_input[1], 1);
+            if (res == -1) perror("Dup2 1");
+            res = dup2(p_input[1], 2);
+            if (res == -1) perror("Dup2 2");
+            close(p_input[1]);
+            close(p_output[1]);
+            res = dup2(p_output[0], 0);
+            if (res == -1) perror("Dup2 3");
+            close(p_output[0]);
+
+            execvp(command[0], command);
+
+            perror("Cannot execlp mpg321");
+            exit(-1);
+        case -1:
+            perror("Failed fork");
+            exit(-1);
+        default: /* parent */
+            close(p_input[1]);
+            close(p_output[0]);
+    }
+}
+
+int forward_app_data(int in, int out)
+{
+    char buf[100];
+    int res;
+
+    res = read(in, buf, sizeof(buf));
+    if (res > 0)
+        write(out, buf, res);
+
+    return res;
+}
+
+void loop(const int *child_pipe, int lsocket)
+{
+    char buf[100];
+    fd_set read_set;
+    int child_read, child_write;
+    int maxfd;
+    int opened_socket;
+    int stdin_opened;
+
+    child_read = child_pipe[0];
+    child_write = child_pipe[1];
+
+    stdin_opened = 1;
+    do
+    {
+        FD_ZERO(&read_set);
+
+        if (stdin_opened)
+            FD_SET(0, &read_set);
+        FD_SET(child_read, &read_set);
+
+        maxfd = child_read;
+
+        select(maxfd + 1, &read_set, 0, 0, 0);
+
+        if (FD_ISSET(child_read, &read_set))
+        {
+            int res;
+            res = forward_app_data(child_read, 1);
+            if (res == 0)
+                break;
+        }
+        if (FD_ISSET(0, &read_set))
+        {
+            int res;
+            res = forward_app_data(0, child_write);
+            if (res == 0)
+            {
+                close(child_write);
+                stdin_opened = 0;
+            }
+        }
+    } while(1);
+}
+
+int main(int argn, char **argv)
+{
+    int p[2];
+    int lsocket;
+
+    fork_app(p, &argv[1]);
+
+    lsocket = serve_socket();
+
+    loop(p, lsocket);
+
+    remove_socket(lsocket);
+
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dicta.h	Fri Sep 14 20:48:13 2007 +0200
@@ -0,0 +1,7 @@
+
+/* error.c */
+void error(const char *msg);
+
+/* usocket.c */
+int serve_socket();
+void remove_socket(int ls);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/error.c	Fri Sep 14 20:48:13 2007 +0200
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "dicta.h"
+
+void error(const char *msg)
+{
+    perror(msg);
+    exit(-1);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usocket.c	Fri Sep 14 20:48:13 2007 +0200
@@ -0,0 +1,54 @@
+#include <stdlib.h>
+#include <sys/un.h>
+#include <sys/socket.h>
+
+#include "dicta.h"
+
+static char socket_path[256];
+static char default_path_prefix[] = "/tmp/socket-stdin.";
+
+static void get_path()
+{
+    char *new;
+    
+    new = getenv("STDIN_SOCKET");
+    if (new == 0)
+    {
+        char num[20];
+        snprintf(socket_path, sizeof(socket_path), "%s%i",
+                default_path_prefix, (int) getuid());
+    } else
+        strncpy(socket_path, new, sizeof(socket_path));
+}
+
+int serve_socket()
+{
+    int ls;
+    struct sockaddr_un addr;
+    int res;
+
+    get_path();
+
+    ls = socket(AF_UNIX, SOCK_STREAM, 0);
+    if (ls == -1)
+        error("Cannot create the unix listen socket in the server.");
+
+    addr.sun_family = AF_UNIX;
+    strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
+
+    res = bind(ls, (struct sockaddr *) & addr, sizeof(addr));
+    if (res == -1)
+        error("Error binding.");
+
+    res = listen(ls, 10);
+    if (res == -1)
+        error("Error listening.");
+
+    return ls;
+}
+
+void remove_socket(int ls)
+{
+    close(ls);
+    unlink(socket_path);
+}