Something bare.
--- /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);
+}