/* $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])); }