main.c
author viric@llimona
Fri, 14 Sep 2007 23:59:56 +0200
changeset 20 f40950acfa03
parent 15 0acf8c3c4fe0
permissions -rw-r--r--
Added tag v0.9.1 for changeset 12de2cd767f2
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
12
6a372f8b4b8a Ignore, license and version.
viric@llimona
parents: 9
diff changeset
     1
/*
6a372f8b4b8a Ignore, license and version.
viric@llimona
parents: 9
diff changeset
     2
    stdin mix - a mixer/multiplexer for stdin to processes
6a372f8b4b8a Ignore, license and version.
viric@llimona
parents: 9
diff changeset
     3
    Copyright (C) 2007  LluĂ­s Batlle i Rossell
6a372f8b4b8a Ignore, license and version.
viric@llimona
parents: 9
diff changeset
     4
6a372f8b4b8a Ignore, license and version.
viric@llimona
parents: 9
diff changeset
     5
    Please find the license in the provided COPYING file.
6a372f8b4b8a Ignore, license and version.
viric@llimona
parents: 9
diff changeset
     6
*/
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
     7
#include <stdio.h>
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
     8
#include <stdlib.h>
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
     9
#include <sys/types.h>
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    10
#include <unistd.h>
5
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
    11
#include <errno.h>
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    12
3
909bca647298 Renaming now correct.
viric@llimona
parents: 2
diff changeset
    13
#include "main.h"
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    14
14
286b248e402a Adding better error messages and a README.
viric@llimona
parents: 12
diff changeset
    15
static const char version[] = "0.9.1";
12
6a372f8b4b8a Ignore, license and version.
viric@llimona
parents: 9
diff changeset
    16
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    17
static int max(int a, int b)
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    18
{
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    19
    if (a > b)
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    20
        return a;
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    21
    return b;
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    22
}
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    23
15
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
    24
static int fork_app(int *opipe /*[3]*/, char * const command[])
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    25
{
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    26
    int p_input[2]; /* from mpg321 to us */
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    27
    int p_output[2]; /* from us to mpg321 */
15
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
    28
    int p_error[2]; /* from mpg321 to us, its stderr */
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    29
    int pid;
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    30
    int res;
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    31
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    32
    pipe(p_input);
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    33
    pipe(p_output);
15
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
    34
    pipe(p_error);
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    35
    opipe[0] = p_input[0]; /* For us to read */
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    36
    opipe[1] = p_output[1]; /* For us to write */
15
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
    37
    opipe[2] = p_error[0]; /* For us to read */
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    38
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    39
    pid = fork();
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    40
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    41
    switch(pid)
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    42
    {
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    43
        case 0: /* child */
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    44
            close(p_input[0]);
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    45
            res = dup2(p_input[1], 1);
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    46
            if (res == -1) perror("Dup2 1");
15
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
    47
            close(p_error[0]);
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
    48
            res = dup2(p_error[1], 2);
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    49
            if (res == -1) perror("Dup2 2");
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    50
            close(p_input[1]);
15
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
    51
            close(p_error[1]);
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
    52
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    53
            close(p_output[1]);
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    54
            res = dup2(p_output[0], 0);
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    55
            if (res == -1) perror("Dup2 3");
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    56
            close(p_output[0]);
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    57
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    58
            execvp(command[0], command);
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    59
14
286b248e402a Adding better error messages and a README.
viric@llimona
parents: 12
diff changeset
    60
            error("Cannot execlp %s", command[0]);
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    61
        case -1:
14
286b248e402a Adding better error messages and a README.
viric@llimona
parents: 12
diff changeset
    62
            error("Failed fork");
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    63
        default: /* parent */
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    64
            close(p_input[1]);
15
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
    65
            close(p_error[1]);
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    66
            close(p_output[0]);
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    67
    }
7
af8d59476914 Added signal passing.
viric@llimona
parents: 6
diff changeset
    68
af8d59476914 Added signal passing.
viric@llimona
parents: 6
diff changeset
    69
    return pid;
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    70
}
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    71
9
d688e3670487 statics and consts.
viric@llimona
parents: 7
diff changeset
    72
static int forward_app_data(int in, int out)
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    73
{
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    74
    char buf[100];
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    75
    int res;
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    76
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    77
    res = read(in, buf, sizeof(buf));
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    78
    if (res > 0)
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    79
        write(out, buf, res);
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    80
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    81
    return res;
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    82
}
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    83
9
d688e3670487 statics and consts.
viric@llimona
parents: 7
diff changeset
    84
static void loop(const int *child_pipe, int lsocket)
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    85
{
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    86
    char buf[100];
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    87
    fd_set read_set;
15
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
    88
    int child_read, child_write, child_read_error;
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    89
    int maxfd;
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    90
    int opened_socket;
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    91
    int stdin_opened;
15
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
    92
    int child_read_opened, child_read_error_opened;
5
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
    93
    int res;
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    94
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    95
    child_read = child_pipe[0];
15
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
    96
    child_read_error = child_pipe[2];
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    97
    child_write = child_pipe[1];
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    98
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
    99
    stdin_opened = 1;
1
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   100
    opened_socket = -1; /* no socket opened */
15
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   101
    child_read_opened = 1;
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   102
    child_read_error_opened = 1;
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   103
    do
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   104
    {
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   105
        FD_ZERO(&read_set);
15
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   106
        maxfd = 0;
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   107
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   108
        if (stdin_opened)
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   109
            FD_SET(0, &read_set);
15
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   110
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   111
        if (child_read_opened)
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   112
        {
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   113
            FD_SET(child_read, &read_set);
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   114
            maxfd = max(maxfd, child_read);
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   115
        }
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   116
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   117
        if (child_read_error_opened)
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   118
        {
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   119
            FD_SET(child_read_error, &read_set);
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   120
            maxfd = max(maxfd, child_read_error);
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   121
        }
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   122
1
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   123
        if (opened_socket >= 0)
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   124
        {
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   125
            FD_SET(opened_socket, &read_set);
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   126
            maxfd = max(maxfd, opened_socket);
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   127
        }
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   128
        else
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   129
        {
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   130
            /* We only accept if we don't have any
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   131
             * connetion opened. */
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   132
            FD_SET(lsocket, &read_set);
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   133
            maxfd = max(maxfd, lsocket);
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   134
        }
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   135
1
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   136
        /* Will block */
5
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   137
        res = select(maxfd + 1, &read_set, 0, 0, 0);
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   138
        if (res == -1)
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   139
        {
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   140
            if (errno == EINTR)
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   141
                continue;
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   142
            else
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   143
                error("Error in select()");
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   144
        }
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   145
15
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   146
        if (child_read_opened && FD_ISSET(child_read, &read_set))
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   147
        {
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   148
            res = forward_app_data(child_read, 1);
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   149
            if (res == 0)
15
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   150
            {
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   151
                close(1);
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   152
                child_read_opened = 0;
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   153
                if (child_read_error_opened == 0)
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   154
                    break;
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   155
            }
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   156
        }
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   157
        if (child_read_error_opened && FD_ISSET(child_read_error, &read_set))
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   158
        {
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   159
            res = forward_app_data(child_read_error, 2);
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   160
            if (res == 0)
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   161
            {
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   162
                close(2);
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   163
                child_read_error_opened = 0;
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   164
                if (child_read_opened == 0)
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   165
                    break;
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   166
            }
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   167
        }
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   168
        if (FD_ISSET(0, &read_set))
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   169
        {
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   170
            res = forward_app_data(0, child_write);
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   171
            if (res == 0)
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   172
            {
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   173
                close(child_write);
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   174
                stdin_opened = 0;
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   175
            }
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   176
        }
1
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   177
        if (opened_socket >= 0 && FD_ISSET(opened_socket, &read_set))
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   178
        {
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   179
            res = forward_app_data(opened_socket, child_write);
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   180
            if (res == 0)
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   181
            {
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   182
                close(opened_socket);
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   183
                opened_socket = -1; /* no socket open */
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   184
            }
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   185
        }
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   186
        if (opened_socket == -1 && FD_ISSET(lsocket, &read_set))
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   187
        {
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   188
            opened_socket = accept_connection(lsocket);
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   189
        }
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   190
    } while(1);
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   191
}
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   192
9
d688e3670487 statics and consts.
viric@llimona
parents: 7
diff changeset
   193
static int server(int argn, char * const argv[])
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   194
{
15
0acf8c3c4fe0 Good routing of app's stderr.
viric@llimona
parents: 14
diff changeset
   195
    int p[3];
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   196
    int lsocket;
7
af8d59476914 Added signal passing.
viric@llimona
parents: 6
diff changeset
   197
    int child;
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   198
7
af8d59476914 Added signal passing.
viric@llimona
parents: 6
diff changeset
   199
    child = fork_app(p, &argv[1]);
af8d59476914 Added signal passing.
viric@llimona
parents: 6
diff changeset
   200
af8d59476914 Added signal passing.
viric@llimona
parents: 6
diff changeset
   201
    install_signal_forwarders(child);
0
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   202
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   203
    lsocket = serve_socket();
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   204
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   205
    loop(p, lsocket);
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   206
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   207
    remove_socket(lsocket);
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   208
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   209
    return 0;
3bbacfe6797a Something bare.
viric@llimona
parents:
diff changeset
   210
}
1
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   211
9
d688e3670487 statics and consts.
viric@llimona
parents: 7
diff changeset
   212
static int client()
1
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   213
{
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   214
    int cs;
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   215
    int res;
5
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   216
    fd_set read_set;
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   217
    int maxfd;
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   218
1
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   219
    cs = connect_socket();
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   220
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   221
    do
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   222
    {
5
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   223
        FD_ZERO(&read_set);
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   224
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   225
        FD_SET(cs, &read_set); /* For reading other side's close() */
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   226
        maxfd = cs;
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   227
        FD_SET(0, &read_set); /* stdin */
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   228
        maxfd = max(maxfd, cs);
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   229
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   230
        res = select(maxfd + 1, &read_set, 0, 0, 0);
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   231
        if (res == -1)
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   232
        {
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   233
            if (errno == EINTR)
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   234
                continue;
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   235
            else
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   236
                error("Error in select()");
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   237
        }
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   238
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   239
        if (FD_ISSET(cs, &read_set))
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   240
        {
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   241
            /* assuming close() on the other side, even
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   242
             * without read(). */
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   243
            break;
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   244
        }
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   245
        if (FD_ISSET(0, &read_set))
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   246
        {
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   247
            res = forward_app_data(0, cs);
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   248
            if (res == 0) /* EOF */
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   249
                break;
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   250
        }
5ed1654fe407 Better client.
viric@llimona
parents: 3
diff changeset
   251
    } while (1);
1
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   252
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   253
    close(cs);
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   254
    return 0;
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   255
}
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   256
6
4fe857c0b12a Help message.
viric@llimona
parents: 5
diff changeset
   257
static int showhelp(const char *pname)
4fe857c0b12a Help message.
viric@llimona
parents: 5
diff changeset
   258
{
12
6a372f8b4b8a Ignore, license and version.
viric@llimona
parents: 9
diff changeset
   259
    printf("sdtdin-mix v%s - Copyright (C) 2007  Lluis Batlle i Rossell\n",
6a372f8b4b8a Ignore, license and version.
viric@llimona
parents: 9
diff changeset
   260
            version);
6
4fe857c0b12a Help message.
viric@llimona
parents: 5
diff changeset
   261
    printf("usage: %s [appcommand] [param1] [param2] ...\n", pname);
4fe857c0b12a Help message.
viric@llimona
parents: 5
diff changeset
   262
    printf(" If you give _appcommand_, it starts the application and\n");
4fe857c0b12a Help message.
viric@llimona
parents: 5
diff changeset
   263
    printf(" a stdin server on $SM_SOCKET or /tmp/socket-sm.UID.\n");
4fe857c0b12a Help message.
viric@llimona
parents: 5
diff changeset
   264
    printf(" If not given, it starts a stdin client for the same socket.\n");
4fe857c0b12a Help message.
viric@llimona
parents: 5
diff changeset
   265
    return 0;
4fe857c0b12a Help message.
viric@llimona
parents: 5
diff changeset
   266
}
4fe857c0b12a Help message.
viric@llimona
parents: 5
diff changeset
   267
9
d688e3670487 statics and consts.
viric@llimona
parents: 7
diff changeset
   268
int main(int argn, char * const * argv)
1
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   269
{
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   270
    int res;
6
4fe857c0b12a Help message.
viric@llimona
parents: 5
diff changeset
   271
    if (argn > 1 && strcmp(argv[1], "-h") == 0)
4fe857c0b12a Help message.
viric@llimona
parents: 5
diff changeset
   272
        res = showhelp(argv[0]);
4fe857c0b12a Help message.
viric@llimona
parents: 5
diff changeset
   273
    else if (argn > 1)
1
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   274
        res = server(argn, argv);
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   275
    else
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   276
        res = client();
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   277
    return res;
473a340551e3 Basic functionality.
viric@llimona
parents: 0
diff changeset
   278
}