Hi, I test this case, and find "case14" is no return, (use arm32 platform and uclibc).
It is this function "mq_timedsend", and program keeps watting for the return. "sys_ret = mq_timedsend(fd, smsg, tc->len, tc->prio, p_ts);" please see the following code. Is this a test code's problem or uclibc's problem? Thanks, Xishi Qiu Here is the test code: /* * Crackerjack Project * * Copyright (C) 2007-2008, Hitachi, Ltd. * Author(s): Takahiro Yasui <[email protected]>, * Yumiko Sugita <[email protected]>, * Satoshi Fujiwara <[email protected]> * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * $Id:$ * */ #include <sys/syscall.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/wait.h> #include <getopt.h> #include <stdlib.h> #include <errno.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <mqueue.h> #include <time.h> #include <signal.h> #include <limits.h> #include "../../common.j.h/include_j_h.h" /* * Macros */ #define SYSCALL_NAME "mq_timedsend" /* * Global variables */ static int opt_debug; static char *progname; /* * Data Structure */ struct test_case { int ttype; int non_block; int len; unsigned prio; time_t sec; long nsec; int ret; int err; }; enum test_type { NORMAL, FD_NONE, FD_NOT_EXIST, FD_FILE, FULL_QUEUE, SEND_SIGINT, }; #define MAX_MSG 10 #define MAX_MSGSIZE 8192 /* Test cases * * test status of errors on man page * * EAGAIN v (would block) * EBADF v (not a valid descriptor) * EINTR v (interrupted by a signal) * EINVAL v (1. invalid 'msg_prio' or * 2. would block but timeout exists) * EMSGSIZE v ('msg_len' exceeds the message size of the queue) * ETIMEDOUT v (not block and timeout occured) */ static struct test_case tcase[] = { { // case00 .ttype = NORMAL, .len = 0, // also success when size equals zero .ret = 0, .err = 0, }, { // case01 .ttype = NORMAL, .len = 1, .ret = 0, .err = 0, }, { // case02 .ttype = NORMAL, .len = MAX_MSGSIZE, .ret = 0, .err = 0, }, { // case03 .ttype = NORMAL, .len = 1, .prio = 32767, // max priority .ret = 0, .err = 0, }, { // case04 .ttype = NORMAL, .len = MAX_MSGSIZE + 1, .ret = -1, .err = EMSGSIZE, }, { // case05 .ttype = FD_NONE, .len = 0, .ret = -1, .err = EBADF, }, { // case06 .ttype = FD_NOT_EXIST, .len = 0, .ret = -1, .err = EBADF, }, { // case07 .ttype = FD_FILE, .len = 0, .ret = -1, .err = EBADF, }, { // case08 .ttype = FULL_QUEUE, .non_block = 1, .len = 16, .ret = -1, .err = EAGAIN, }, { // case09 .ttype = NORMAL, .len = 1, .prio = 32768, // max priority + 1 .ret = -1, .err = EINVAL, }, { // case10 .ttype = FULL_QUEUE, .len = 16, .sec = -1, .nsec = 0, .ret = -1, .err = EINVAL, }, { // case11 .ttype = FULL_QUEUE, .len = 16, .sec = 0, .nsec = -1, .ret = -1, .err = EINVAL, }, { // case12 .ttype = FULL_QUEUE, .len = 16, .sec = 0, .nsec = 1000000000, .ret = -1, .err = EINVAL, }, { // case13 .ttype = FULL_QUEUE, .len = 16, .sec = 0, .nsec = 999999999, .ret = -1, .err = ETIMEDOUT, }, { // case14 .ttype = SEND_SIGINT, .len = 16, .ret = -1, .err = EINTR, }, }; /* * do_test() * * Input : TestCase Data * Return : RESULT_OK(0), RESULT_NG(1) * */ static int do_test(struct test_case *tc) { int sys_ret; int sys_errno; int result = RESULT_OK; int oflag; int i, rc, cmp_ok = 1, fd = -1; char smsg[MAX_MSGSIZE], rmsg[MAX_MSGSIZE]; struct timespec ts, *p_ts; pid_t pid = 0; unsigned prio; /* * When test ended with SIGTERM etc, mq discriptor is left remains. * So we delete it first. */ mq_unlink(QUEUE_NAME); switch (tc->ttype) { case FD_NOT_EXIST: fd = INT_MAX - 1; /* fallthrough */ case FD_NONE: break; case FD_FILE: fd = open("/", O_RDONLY); if (fd < 0) { EPRINTF("can't open \"/\".\n"); result = 1; goto EXIT; } break; default: /* * Open message queue */ oflag = O_CREAT|O_EXCL|O_RDWR; if (tc->non_block) oflag |= O_NONBLOCK; fd = mq_open(QUEUE_NAME, oflag, S_IRWXU, NULL); if (fd < 0) { EPRINTF("mq_open failed. %d %d\n", fd, errno); result = 1; goto EXIT; } if (tc->ttype == FULL_QUEUE || tc->ttype == SEND_SIGINT) { for (i = 0; i < MAX_MSG; i++) { rc = mq_timedsend(fd, smsg, tc->len, 0, NULL); if (rc < 0) { EPRINTF("mq_timedsend failed.\n"); result = 1; goto EXIT; } } if (tc->ttype == SEND_SIGINT) { pid = create_sig_proc(200000, SIGINT); if (pid < 0) { result = 1; goto EXIT; } } } break; } /* * Prepare send message */ for (i = 0; i < tc->len; i++) smsg[i] = i; /* * Set the timeout value */ ts.tv_sec = tc->sec; ts.tv_nsec = tc->nsec; p_ts = &ts; if (tc->sec == 0 && tc->nsec == 0) p_ts = NULL; /* * Execute system call */ errno = 0; sys_ret = mq_timedsend(fd, smsg, tc->len, tc->prio, p_ts); ————> // Here is no return sys_errno = errno; if (sys_ret < 0) goto TEST_END; /* * Receive echoed message and compare */ rc = mq_timedreceive(fd, rmsg, MAX_MSGSIZE, &prio, NULL); if (rc < 0) { EPRINTF("mq_timedreceive failed.\n"); result = 1; goto EXIT; } if (rc != tc->len || tc->prio != prio) cmp_ok = 0; else { for (i = 0; i < tc->len; i++) if (rmsg[i] != smsg[i]) { cmp_ok = 0; break; } } TEST_END: /* * Check results */ result |= (sys_errno != tc->err) || !cmp_ok; PRINT_RESULT_CMP(sys_ret >= 0, tc->ret, tc->err, sys_ret, sys_errno, cmp_ok); EXIT: if (fd >= 0) { close(fd); mq_unlink(QUEUE_NAME); } if (pid > 0) { int st; kill(pid, SIGTERM); wait(&st); } return result; } /* * sighandler() */ void sighandler(int sig) { if (sig == SIGINT) return; // NOTREACHED return; } /* * usage() */ static void usage(const char *progname) { EPRINTF("usage: %s [options]\n", progname); EPRINTF("This is a regression test program of %s system call.\n", SYSCALL_NAME); EPRINTF("options:\n"); EPRINTF(" -d --debug Show debug messages\n"); EPRINTF(" -h --help Show this message\n"); RPRINTF("NG\n"); exit(1); } /* * main() */ int main(int argc, char *argv[]) { int result = RESULT_OK; int c; int i; struct option long_options[] = { { "debug", no_argument, 0, 'd' }, { "help", no_argument, 0, 'h' }, { NULL, 0, NULL, 0 } }; progname = strchr(argv[0], '/'); progname = progname ? progname + 1 : argv[0]; while ((c = getopt_long(argc, argv, "dh", long_options, NULL)) != -1) { switch (c) { case 'd': opt_debug = 1; break; default: usage(progname); // NOTREACHED } } if (argc != optind) { EPRINTF("Options are not match.\n"); usage(progname); // NOTREACHED } /* * Execute test */ signal(SIGINT, sighandler); for (i = 0; i < (int)(sizeof(tcase) / sizeof(tcase[0])); i++) { int ret; PRINTF("(case%02d) START\n", i); ret = do_test(&tcase[i]); PRINTF("(case%02d) END => %s\n", i, (ret == 0) ? "OK" : "NG"); result |= ret; } /* * Check results */ switch(result) { case RESULT_OK: RPRINTF("OK\n"); break; default: RPRINTF("NG\n"); break; } return 0; } ... pid_t create_sig_proc(unsigned long usec, int sig) { pid_t pid, cpid; signal(SIGUSR2, sighandler_for_sig_proc); pid = getpid(); cpid = fork(); switch (cpid) { case 0: pause(); usleep(usec); kill(pid, sig); _exit(0); break; case -1: EPRINTF("fork failed.\n"); return cpid; default: sleep(10) ; /* workaround to run parent process before child */ kill(cpid, SIGUSR2); return cpid; } } _______________________________________________ uClibc mailing list [email protected] http://lists.busybox.net/mailman/listinfo/uclibc
