/* Check: a unit test framework for C Copyright (C) 2001, Arien Malec This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #ifdef STDC_HEADERS #include #include #include #endif #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_IPC_H # include #endif #ifdef HAVE_SYS_MSG_H # include #endif #include "list.h" #include "error.h" #include "check.h" #include "check_impl.h" #include "check_msg.h" #ifndef USE_FORKWAITMSG static LastLocMsg *nofork_lastlocmsg; static FailureMsg *nofork_failuremsg; #endif enum { LASTLOCMSG = 1, FAILUREMSG = 2 }; static LastLocMsg *create_last_loc_msg (const char *file, int line); static FailureMsg *create_failure_msg (const char *msg); static FailureMsg *create_failure_msg (const char *msg) { FailureMsg *m = emalloc (sizeof(FailureMsg)); m->message_type = (long int) FAILUREMSG; strncpy(m->msg, msg, CMAXMSG); return m; } static LastLocMsg *create_last_loc_msg (const char *file, int line) { LastLocMsg *m = emalloc (sizeof(LastLocMsg)); m->message_type = (long int) LASTLOCMSG; #ifdef HAVE_SNPRINTF snprintf(m->msg, CMAXMSG, "%s\n%d", file, line); #else sprintf(m->msg, "%s\n%d", file, line); #endif return m; } char *last_loc_file (LastLocMsg *msg) { int i; char *rmsg = emalloc (CMAXMSG); /* caller responsible for freeing */ char *mmsg = msg->msg; if (msg == NULL) return NULL; for (i = 0; mmsg[i] != '\n'; i++) { if (mmsg[i] == '\0') eprintf ("Badly formated last loc message"); rmsg[i] = mmsg[i]; } rmsg[i] = '\0'; return rmsg; } int last_loc_line (LastLocMsg *msg) { char *rmsg; if (msg == NULL) return -1; rmsg = msg->msg; while (*rmsg != '\n') { if (*rmsg == '\0') eprintf ("Badly formated last loc message"); rmsg++; } rmsg++; /*advance past \n */ return atoi (rmsg); } void send_last_loc_msg (int msqid, const char * file, int line) { #ifdef USE_FORKWAITMSG int rval; LastLocMsg *rmsg = create_last_loc_msg(file, line); rval = msgsnd(msqid, (void *) rmsg, CMAXMSG, IPC_NOWAIT); if (rval == -1) { eprintf ("send_last_loc_msg:Failed to send message, msqid = %d:",msqid); } free(rmsg); #else nofork_lastlocmsg = create_last_loc_msg(file, line); #endif } int create_msq (void) { #ifdef USE_FORKWAITMSG int msqid; msqid = msgget((key_t) 1, 0666 | IPC_CREAT); if (msqid == -1) eprintf ("Unable to create message queue:"); return msqid; #else return 0; #endif } void delete_msq (int msqid) { #ifdef USE_FORKWAITMSG if (msgctl (msqid, IPC_RMID, NULL) == -1) eprintf ("Failed to free message queue:"); #endif } void send_failure_msg (int msqid, const char *msg) { #ifdef USE_FORKWAITMSG int rval; FailureMsg *rmsg = create_failure_msg(msg); rval = msgsnd(msqid, (void *) rmsg, CMAXMSG, IPC_NOWAIT); if (rval == -1) eprintf ("send_failure_msg:Failed to send message:"); free(rmsg); #else nofork_failuremsg = create_failure_msg(msg); #endif } LastLocMsg *receive_last_loc_msg (int msqid) { #ifdef USE_FORKWAITMSG LastLocMsg *rmsg = emalloc(sizeof(LastLocMsg)); /* caller responsible for freeing */ while (1) { int rval; rval = msgrcv(msqid, (void *) rmsg, CMAXMSG, LASTLOCMSG, IPC_NOWAIT); if (rval == -1) { if (errno == ENOMSG) break; eprintf ("receive_last_loc_msg:Failed to receive message:"); } } return rmsg; #else LastLocMsg *rmsg = nofork_lastlocmsg; nofork_lastlocmsg = NULL; return rmsg; #endif } FailureMsg *receive_failure_msg (int msqid) { #ifdef USE_FORKWAITMSG FailureMsg *rmsg = emalloc(sizeof(FailureMsg)); int rval; rval = msgrcv(msqid, (void *) rmsg, CMAXMSG, FAILUREMSG, IPC_NOWAIT); if (rval == -1) { if (errno == ENOMSG) return NULL; eprintf ("receive_failure_msg:Failed to receive message:"); } return rmsg; #else FailureMsg *rmsg = nofork_failuremsg; nofork_failuremsg = NULL; return rmsg; #endif }