/* $Id: shbuferr.c,v 1.3 2002/05/02 16:16:30 poettering Exp $ * * This file is part of libshbuf. * * asd 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. * * asd 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. */ #include #include #include #include #include #include #include "shbuferr.h" static pthread_once_t _shbuf_err_once = PTHREAD_ONCE_INIT; static pthread_key_t _shbuf_err_key; typedef struct { shbuf_error error; char* text; } _error_struct; static void _free(void *p) { _error_struct *e = (_error_struct*) p; assert(e); free(e->text); free(e); } static void _init() { pthread_key_create(&_shbuf_err_key, _free); } static _error_struct* _get_err_ptr() { _error_struct *v; pthread_once(&_shbuf_err_once, _init); if (!(v = pthread_getspecific(_shbuf_err_key))) { v = malloc(sizeof(_error_struct)); assert(v); v->error = SHBUF_NOERROR; v->text = 0; pthread_setspecific(_shbuf_err_key, v); } return v; } void shbuf_set_errno(shbuf_error e) { _get_err_ptr()->error = e; } shbuf_error shbuf_get_errno() { return _get_err_ptr()->error; } char *shbuf_strerror(shbuf_error e, int en) { char *v; switch(e) { case SHBUF_NOERROR: v = "Success"; break; case SHBUF_BUSY: v = "Buffer is busy."; break; case SHBUF_NOTINNOTIFYMODE: v = "shbuf object is not in notify mode."; break; case SHBUF_COULDNOTCREATEMSGQ: v = "Could not create message queue."; break; case SHBUF_COULDNOTMAPBUFFERSHM: v = "Could not map buffer shared memory block."; break; case SHBUF_COULDNOTCREATEBUFFERSHM: v = "Could not create buffer shared memory block."; break; case SHBUF_COULDNOTRESETSEM: v = "Could not reset semaphore."; break; case SHBUF_COULDNOTCREATESEM: v = "Could not create semaphore."; break; case SHBUF_COULDNOTMAPCONTROLSHM: v = "Could not map control shared memory block."; break; case SHBUF_COULDNOTCREATECONTROLSHM: v = "Could not create control shared memory block."; break; case SHBUF_COULDNOTOPENMSGQ: v = "Could not open message queue."; break; case SHBUF_COULDNOTOPENCONTROLSHM: v = "Could not open control shared memory block."; break; case SHBUF_COULDNOTOPENBUFFERSHM: v = "Could not open buffer shared memory block."; break; case SHBUF_COULDNOTOPENSEM: v = "Could not open semaphore."; break; case SHBUF_MSGSNDFAILED: v = "msgsnd() failed."; break; case SHBUF_SELECTFAILED: v = "select() failed."; break; case SHBUF_READFAILED: v = "read() failed."; break; case SHBUF_ACCESSMODEFAILED: v = "Could not set access mode."; break; case SHBUF_COULDNOTCREATEPIPE: v = "pipe() failed."; break; case SHBUF_COULDNOTCREATETHREAD: v = "Could not create thread."; break; case SHBUF_LOCKFAILED: v = "Semaphore lock failed."; break; case SHBUF_UNLOCKFAILED: v = "Semaphore unlock failed."; break; case SHBUF_INCOMPATIBLEBUFFER: v = "Incompatible shbuf object"; break; default: v = "Unknown error" ; break; } if (e < SHBUF_SYSTEM_ERROR_BASE) return v; else { char tmp[256], *f; _error_struct *s = _get_err_ptr(); if ((f = strerror_r(en, tmp, sizeof(tmp))) == 0) snprintf((f = tmp), sizeof(tmp), "strerror_r() failed for %i.", en); assert(s); if (s->text) free(s->text); s->text = malloc(strlen(v)+strlen(f)+3+1); sprintf(s->text, "%s (%s)", v, f); return s->text; } } char *shbuf_strerror2() { return shbuf_strerror(shbuf_get_errno(), errno); } void shbuf_perror(char *p) { fprintf(stderr, "%s: %s\n", p, shbuf_strerror2()); }