// samlib.cc // Miscellaneous handy functions // 26-01-1996: creation include <net/cs/samlib.h> include <errno.h> include <fcntl.h> include <stdarg.h> include <stdio.h> include <stdlib.h> include <string.h> include <termios.h> include <unistd.h> include <sys/fcntl.h> include <sys/ioctl.h> include <sys/time.h> include <sys/types.h> include <netinet/in.h> const char* log_file_name = "error.log"; bool log_active = false; static bool log_opened = false; static FILE* fd_log = NULL; bool data_available(int fd) { fd_set readfds; timeval tv; FD_ZERO(&readfds); FD_SET(fd, &readfds); tv.tv_sec = 0; tv.tv_usec = 0; return select(fd+1, &readfds, NULL, NULL, &tv) == 1; } int read_nonblock(int fd, char* buf, int maxbytes) { int flags, oldflags, rc; flags = fcntl(fd, F_GETFL); if (flags == -1) { fprintf(stderr, "read_nonblock : fcntl F_GETFL failed\n"); return -1; } oldflags = flags; flags |= O_NONBLOCK; if (fcntl(fd, F_SETFL, flags) == -1) { fprintf(stderr, "read_nonblock : fcntl F_SETFL failed\n"); return false; } rc = ::read(fd, buf, maxbytes); if (fcntl(fd, F_SETFL, oldflags) == -1) { fprintf(stderr, "read_nonblock : fcntl F_SETFL 2 faild\n"); } return rc; } void warn(const char* str, ...) { va_list v; va_start(v, str); vfprintf(stderr, str, v); fprintf(stderr, "\n"); } void halt(const char* str, ...) { va_list v; fprintf(stderr, "\n"); va_start(v, str); vfprintf(stderr, str, v); fprintf(stderr, "\n"); exit (1); } byte* safe_alloc (size_t size, const char* func_name) { byte* p = NULL; if ((p = (byte*) malloc(size)) == NULL) { if (func_name != NULL) halt("(%s) safe_alloc: Couldn't allocate %lu bytes", func_name, size); else halt("safe_alloc: Couldn't allocate %lu bytes", func_name, size); } // DEBUG if (func_name != NULL) write_to_log ("(%s) safe_alloc : %u bytes allocated, ptr = %p", func_name, size, p); else write_to_log ("safe_alloc : %u bytes allocated, ptr = %p", size, p); return p; } void safe_free (byte*& p, const char* func_name) { if (func_name != NULL) write_to_log("(%s) freeing ptr %p", func_name, p); else write_to_log("freeing ptr %p", p); free(p); p = NULL; } void write_to_log (const char* logstr, ...) { va_list v; if (!log_active) return; if (!log_opened) { if ((fd_log = fopen (log_file_name, "wb")) == NULL) halt ("Couldn't open logfile"); log_opened = true; } va_start (v, logstr); vfprintf (fd_log, logstr, v); fprintf (fd_log, "\n"); } int read_package(int fd, char* buf, int maxnrbytes) { char mybuf[256]; long received = 0; int total_received = 0; int nsize, hsize; if (read(fd, &nsize, sizeof(nsize)) != sizeof(nsize)) { warn("read_package : couldn't read size (%s)\n", strerror(errno)); return -1; } hsize = ntohl(nsize); while (total_received < hsize) { if (total_received < maxnrbytes) { int max_receive = MIN(hsize - total_received, maxnrbytes - total_received); received = read(fd, buf + total_received, max_receive); } else { int max_receive = MIN(hsize - total_received, (int)sizeof(mybuf)); received = read(fd, mybuf, max_receive); } if (received <= 0) { warn("read_package : couldn't read data (%s)\n", strerror(errno)); return -1; } total_received += received; } return MIN(total_received, maxnrbytes); } // method used is not the most efficient, but it is the safest way since // most messages are written atomicly int write_package(int fd, const char* buf, int nrbytes) { char* mybuf; int sent = 0, total_sent = 0; ulong nsize = htonl(nrbytes); if ((mybuf = (char*)malloc(nrbytes + sizeof(nsize))) == NULL) return -1; memcpy(mybuf, &nsize, sizeof(nsize)); memcpy(mybuf + sizeof(nsize), buf, nrbytes); nrbytes += sizeof(nsize); while (total_sent < nrbytes) { sent = write(fd, mybuf, nrbytes - total_sent); if (sent <= 0) { warn("write_package : couldn't write data (%s)\n", strerror(errno)); free(mybuf); return -1; } total_sent += sent; } free(mybuf); return total_sent - sizeof(nsize); // return only amount of data sent } static struct termios graph_termio; /* graphics mode termio parameters */ static struct termios text_termio; /* text mode termio parameters */ void unbuffer_stdin() { /* save text mode termio parameters */ ioctl(0, TCGETS, &graph_termio); text_termio = graph_termio; /* change termio parameters to allow our own I/O processing */ graph_termio.c_iflag &= ~(BRKINT|PARMRK|INPCK|IUCLC|IXON|IXOFF); graph_termio.c_iflag |= (IGNBRK|IGNPAR); graph_termio.c_oflag &= ~(ONOCR); graph_termio.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|NOFLSH); graph_termio.c_lflag |= (ISIG); /* enable interrupt */ graph_termio.c_cc[VMIN] = 1; graph_termio.c_cc[VTIME] = 0; graph_termio.c_cc[VSUSP] = 0; /* disable suspend */ /* set graphics mode termio parameters */ ioctl(0, TCSETSW, &graph_termio); } void restore_stdin() { ioctl(0, TCSETSW, &text_termio); } void unbuffer_stdout() { setvbuf(stdout, NULL, _IONBF, 0); }
Hush Online Technology
hush@cs.vu.nl
09/09/98 |
![]() |
![]() |