Main Page   Data Structures   File List   Data Fields   Globals   Examples  

shbuftest.c

A simple testing and example program for libshbuf.

/* $Id: shbuftest.c,v 1.4 2003/09/09 22:14:58 poettering Exp $
 *
 * This file is part of libshbuf. 
 *
 * libshbuf is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 *
 * libshbuf is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with libshbuf; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 */

/*
 * shbuftest - a simple testing and example program for libshbuf
 *
 * Usage:
 *
 *    Just run "shbuftest" for a shared buffer provider. Than run
 *    "shbuftest 4711" with 4711 replaced be the key the server told
 *    you it uses. You may than enter some data via keyboard to the
 *    client and on pressing RETURN the text will appear immediately
 *    on the server's output.
 */

#include <stdio.h>
#include <signal.h>
#include <assert.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>

#include "shbuf.h"
#include "shbuferr.h"

#define BUFSIZE 1024

// Flag that indicates requested process termination
static volatile int quit = 0;

// Signal function
static void _sigint(int s) {
#ifdef DEBUG    
    char *t = "SIGINT\n";
    int _errno;

    _errno = errno;
    write(2, t, strlen(t));
    errno = _errno;
#endif

    quit = 1;
}

// This gets run when the program is started without any command line arguments
static int _provider() {
    shbuf *sb;
        
    if (!(sb = shbuf_create(0, BUFSIZE))) {
        shbuf_perror("Could not create shbuf");
        return -1;
    }

    if (shbuf_notify_enable(sb, 1) != 0) {
        shbuf_perror("Could not enable notification system");
        return -2;
    }
        
    if (shbuf_access(sb, 0700) != 0) {
        shbuf_perror("Could not set access mode");
        return -3;
    }

    fprintf(stderr, "Listening on shbuf key %i.\n", shbuf_get_key(sb));

    while(!quit) {
        const unsigned char *p;
        unsigned long l;
        ssize_t r;

        if (!(p = shbuf_get_read_pointer(sb, &l))) {
            if (shbuf_wait(sb) < 0)
                break;
            
            continue;
        }

        if (p == (unsigned char*) -1)
            break;

        r = write(1, p, l);

        if (r == -1 && errno == EINTR)
            continue;
        
        if (r <= 0)
            break;

        if (shbuf_inc_read_pointer(sb, r) < 0)
            break;
        
        if (shbuf_notify(sb) < 0)
            break;
    }

    shbuf_access(sb, 0);
    shbuf_notify_enable(sb, 0);
    shbuf_free(sb);

    fprintf(stderr, "Exiting cleanly.\n");
    
    return 0;
}

// This gets run when the program is run with a shbuf key as command line argument
static int _client(key_t key) {
    shbuf *sb;
        
    if (!(sb = shbuf_open(key))) {
        shbuf_perror("Could not open shbuf");
        return -1;
    }
    
    if (shbuf_notify_enable(sb, 1) != 0) { 
        shbuf_perror("Could not enable notification."); 
        return -2; 
    } 
    
    fprintf(stderr, "Opened shbuf key %i.\n", shbuf_get_key(sb));

    while(!quit && shbuf_connected(sb) == 1) {
        unsigned char *p;
        unsigned long l;
        ssize_t r;

        if (!(p = shbuf_get_write_pointer(sb, &l))) {
            if (shbuf_wait(sb) < 0)
                break;
            
            continue;
        }

        if (p == (unsigned char*) -1)
            break;

        if ((r = read(0, p, l)) == -1 && errno == EINTR)
            continue;
        
        if (r <= 0)
            break;

        if (shbuf_inc_write_pointer(sb, r) < 0)
            break;
        
        if (shbuf_notify(sb) < 0)
            break;
    }

    shbuf_notify_enable(sb, 0);
    shbuf_free(sb);

    fprintf(stderr, "Exiting cleanly.\n");
    
    return 0;
}

int main(int argc, char *argv[]) {

    signal(SIGPIPE, _sigint);
    signal(SIGINT, _sigint);
    signal(SIGTERM, _sigint);
    signal(SIGHUP, _sigint);

    siginterrupt(SIGPIPE, 1);
    siginterrupt(SIGINT, 1);
    siginterrupt(SIGTERM, 1);
    siginterrupt(SIGHUP, 1);
    
    if (argc <= 1)
        return _provider();

    return _client((key_t) atoi(argv[1]));
}

Generated on Thu Sep 11 18:52:21 2003 for libshbuf by doxygen1.2.18