From: Cyril H. <su...@li...> - 2013-05-24 13:21:24
|
The branch, master, has been updated via ee47b99be3086043f981ca82343dede3c19c8c67 (commit) via 7ea4978ee0499761f9a7438fd0f924cff7f29f98 (commit) from 7053c3bf279750da4e9e4bb14006fc0edafccd3e (commit) - Log ----------------------------------------------------------------- commit ee47b99be3086043f981ca82343dede3c19c8c67 Author: DAN LI <li...@cn...> Date: Fri May 24 17:50:07 2013 +0800 shmctl/shmctl01.c: Test features IPC_INFO, SHM_STAT, SHM_LOCK and SHM_UNLOCK. Additional tests for features IPC_INFO, SHM_STAT, SHM_LOCK and SHM_UNLOCK. Signed-off-by: DAN LI <li...@cn...> Reviewed-by: Jan Stancek <jst...@re...> Signed-off-by: Wanlong Gao <gao...@cn...> commit 7ea4978ee0499761f9a7438fd0f924cff7f29f98 Author: DAN LI <li...@cn...> Date: Thu May 23 16:35:57 2013 +0800 shmctl/shmctl01.c: cleanup 1. Remove useless comments 2. Revise code to follow ltp-code-style Signed-off-by: DAN LI <li...@cn...> Reviewed-by: Jan Stancek <jst...@re...> Signed-off-by: Wanlong Gao <gao...@cn...> ----------------------------------------------------------------------- Summary of changes: testcases/kernel/syscalls/ipc/shmctl/shmctl01.c | 298 ++++++++++++----------- 1 files changed, 150 insertions(+), 148 deletions(-) diff --git a/testcases/kernel/syscalls/ipc/shmctl/shmctl01.c b/testcases/kernel/syscalls/ipc/shmctl/shmctl01.c index 4a1b064..cba1a1d 100644 --- a/testcases/kernel/syscalls/ipc/shmctl/shmctl01.c +++ b/testcases/kernel/syscalls/ipc/shmctl/shmctl01.c @@ -1,20 +1,19 @@ /* + * Copyright (c) International Business Machines Corp., 2001 * - * Copyright (c) International Business Machines Corp., 2001 + * 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 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. * - * 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 + * 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 */ /* @@ -35,91 +34,90 @@ * otherwise, * if doing functionality testing * call the correct test function - * if the conditions are correct, + * if the conditions are correct, * issue a PASS message * otherwise * issue a FAIL message * otherwise * issue a PASS message * call cleanup - * - * USAGE: <for command-line> - * shmctl01 [-c n] [-f] [-i n] [-I x] [-P x] [-t] - * where, -c n : Run n copies concurrently. - * -f : Turn off functionality Testing. - * -i n : Execute test n times. - * -I x : Execute test for x seconds. - * -P x : Pause for x seconds between iterations. - * -t : Turn on syscall timing. - * - * HISTORY - * 03/2001 - Written by Wayne Boyer - * 02/04/2008 Renaud Lottiaux (Ren...@ke...) - * - Fix concurrency issue. Replace the sleep used for synchronization - * with the new pipe based synchronization functions. - * - * RESTRICTIONS - * none */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif #include "ipcshm.h" #include "libtestsuite.h" char *TCID = "shmctl01"; -int shm_id_1 = -1; -struct shmid_ds buf; -long save_time; +static int shm_id_1 = -1; +static int shm_index; +static struct shmid_ds buf; +static struct shminfo info; +static long save_time; #define FIRST 0 #define SECOND 1 -int stat_time; /* set to either FIRST or SECOND for IPC_STAT tests */ +static int stat_time; -void *set_shared; +static void *set_shared; #define N_ATTACH 4 -pid_t pid_arr[N_ATTACH]; -int sync_pipes[2]; - -/* - * These are the various setup and check functions for the commands - * that we are checking. - */ +static pid_t pid_arr[N_ATTACH]; +static int sync_pipes[2]; /* Setup, cleanup and check routines for IPC_STAT */ -void stat_setup(void), func_stat(void); -void stat_cleanup(void); +static void stat_setup(void), func_istat(int ret); +static void stat_cleanup(void); /* Setup and check routines for IPC_SET */ -void set_setup(void), func_set(void); +static void set_setup(void), func_set(int ret); + +/* Check routine for IPC_INFO */ +static void func_info(int ret); + +/* Check routine for SHM_STAT */ +static void func_sstat(int ret); + +/* Check routine for SHM_LOCK */ +static void func_lock(int ret); + +/* Check routine for SHM_UNLOCK */ +static void func_unlock(int ret); /* Check routine for IPC_RMID */ -void func_rmid(void); +static void func_rmid(int ret); /* Child function */ -void do_child(void); - -struct test_case_t { - int cmd; /* the command to test */ - void (*func_test) (); /* the test function */ - void (*func_setup) (); /* the setup function if necessary */ +static void do_child(void); + +static struct test_case_t { + int *shmid; + int cmd; + struct shmid_ds *arg; + void (*func_test) (int); + void (*func_setup) (void); } TC[] = { - - { - IPC_STAT, func_stat, stat_setup}, + {&shm_id_1, IPC_STAT, &buf, func_istat, stat_setup}, #ifndef UCLINUX - /* The second test is not applicable to uClinux; shared memory segments - are detached on exec(), so cannot be passed to uClinux children. */ - { - IPC_STAT, func_stat, stat_setup}, + /* + * The second test is not applicable to uClinux; + * shared memory segments are detached on exec(), + * so cannot be passed to uClinux children. + */ + {&shm_id_1, IPC_STAT, &buf, func_istat, stat_setup}, #endif - { - IPC_SET, func_set, set_setup}, { - IPC_RMID, func_rmid, NULL} + {&shm_id_1, IPC_SET, &buf, func_set, set_setup}, + {&shm_id_1, IPC_INFO, (struct shmid_ds *) &info, func_info, NULL}, + {&shm_index, SHM_STAT, &buf, func_sstat, NULL}, + {&shm_id_1, SHM_LOCK, NULL, func_lock, NULL}, + {&shm_id_1, SHM_UNLOCK, NULL, func_unlock, NULL}, + {&shm_id_1, IPC_RMID, NULL, func_rmid, NULL}, }; -int TST_TOTAL = (sizeof(TC) / sizeof(*TC)); +static int TST_TOTAL = ARRAY_SIZE(TC); #define NEWMODE 0066 @@ -128,31 +126,27 @@ int TST_TOTAL = (sizeof(TC) / sizeof(*TC)); static char *argv0; #endif -static int stat_i; /* Shared between do_child and stat_setup */ +static int stat_i; -int main(int ac, char **av) +int main(int argc, char *argv[]) { int lc; char *msg; int i; - void check_functionality(void); - if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) + msg = parse_opts(argc, argv, NULL, NULL); + if (msg != NULL) tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); #ifdef UCLINUX - argv0 = av[0]; + argv0 = argv[0]; maybe_run_child(do_child, "ddd", &stat_i, &stat_time, &shm_id_1); #endif - setup(); /* global setup */ - - /* The following loop checks looping state if -i option given */ + setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { - /* reset tst_count in case we are looping */ tst_count = 0; - /* initialize stat_time */ stat_time = FIRST; /* @@ -160,28 +154,22 @@ int main(int ac, char **av) * permissions. Do this here instead of in setup() * so that looping (-i) will work correctly. */ - if ((shm_id_1 = shmget(shmkey, SHM_SIZE, IPC_CREAT | IPC_EXCL | - SHM_RW)) == -1) { + shm_id_1 = shmget(shmkey, SHM_SIZE, + IPC_CREAT | IPC_EXCL | SHM_RW); + if (shm_id_1 == -1) tst_brkm(TBROK, cleanup, "couldn't create the shared" " memory segment"); - } - /* loop through the test cases */ for (i = 0; i < TST_TOTAL; i++) { /* * if needed, set up any required conditions by * calling the appropriate setup function */ - if (TC[i].func_setup != NULL) { + if (TC[i].func_setup != NULL) (*TC[i].func_setup) (); - } - - /* - * Use TEST macro to make the call - */ - TEST(shmctl(shm_id_1, TC[i].cmd, &buf)); + TEST(shmctl(*(TC[i].shmid), TC[i].cmd, TC[i].arg)); if (TEST_RETURN == -1) { tst_resm(TFAIL, "%s call failed - errno " @@ -190,7 +178,7 @@ int main(int ac, char **av) continue; } if (STD_FUNCTIONAL_TEST) { - (*TC[i].func_test) (); + (*TC[i].func_test) (TEST_RETURN); } else { tst_resm(TPASS, "call succeeded"); @@ -217,7 +205,7 @@ int main(int ac, char **av) * this seperate routine to avoid code duplication in * stat_setup() below. */ -void *set_shmat() +void *set_shmat(void) { void *rval; @@ -241,7 +229,7 @@ void *set_shmat() * Make things interesting by forking some children * that will either attach or inherit the shared memory. */ -void stat_setup() +void stat_setup(void) { void *set_shmat(); pid_t pid; @@ -252,34 +240,32 @@ void stat_setup() * the children inherit the memory. */ - if (stat_time == SECOND) { + if (stat_time == SECOND) /* * use the global "set_shared" variable here so that * it can be removed in the stat_func() routine. */ set_shared = set_shmat(); - } tst_flush(); for (stat_i = 0; stat_i < N_ATTACH; stat_i++) { if (sync_pipe_create(sync_pipes, PIPE_NAME) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_create failed"); - if ((pid = FORK_OR_VFORK()) == -1) { + pid = FORK_OR_VFORK(); + if (pid == -1) tst_brkm(TBROK, cleanup, "could not fork"); - } - if (pid == 0) { /* child */ + if (pid == 0) { #ifdef UCLINUX if (self_exec(argv0, "ddd", stat_i, stat_time, - shm_id_1) < 0) { + shm_id_1) < 0) tst_brkm(TBROK, cleanup, "could not self_exec"); - } #else do_child(); #endif - } else { /* parent */ + } else { /* save the child's pid for cleanup later */ pid_arr[stat_i] = pid; if (sync_pipe_wait(sync_pipes) == -1) @@ -295,12 +281,8 @@ void stat_setup() sleep(1); } -/* - * do_child - */ -void do_child() +void do_child(void) { - int rval; void *test; #ifdef UCLINUX @@ -308,11 +290,10 @@ void do_child() tst_brkm(TBROK, cleanup, "sync_pipe_create failed"); #endif - if (stat_time == FIRST) { + if (stat_time == FIRST) test = set_shmat(); - } else { + else test = set_shared; - } if (sync_pipe_notify(sync_pipes) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_notify failed"); @@ -323,25 +304,24 @@ void do_child() #endif tst_brkm(TBROK, cleanup, "sync_pipe_close failed"); - /* do an assignement for fun */ memcpy(test, &stat_i, sizeof(stat_i)); /* pause until we get a signal from stat_cleanup() */ - rval = pause(); + pause(); /* now we're back - detach the memory and exit */ - if (shmdt(test) == -1) { + if (shmdt(test) == -1) tst_resm(TBROK, "shmdt() failed - %d", errno); - } + tst_exit(); } /* - * func_stat() - check the functionality of the IPC_STAT command with shmctl() + * func_istat() - check the functionality of the IPC_STAT command with shmctl() * by looking at the pid of the creator, the segement size, * the number of attaches and the mode. */ -void func_stat() +void func_istat(int ret) { int fail = 0; pid_t pid; @@ -373,7 +353,8 @@ void func_stat() } /* use MODE_MASK to make sure we are comparing the last 9 bits */ - if (!fail && (buf.shm_perm.mode & MODE_MASK) != ((SHM_RW) & MODE_MASK)) { + if (!fail && (buf.shm_perm.mode & MODE_MASK) != + ((SHM_RW) & MODE_MASK)) { tst_resm(TFAIL, "segment mode is incorrect"); fail = 1; } @@ -383,9 +364,8 @@ void func_stat() /* save the change time for use in the next test */ save_time = buf.shm_ctime; - if (fail) { + if (fail) return; - } tst_resm(TPASS, "pid, size, # of attaches and mode are correct " "- pass #%d", stat_time); @@ -396,22 +376,20 @@ void func_stat() * have the parent make dessert, er, um, make that remove * the shared memory that is no longer needed. */ -void stat_cleanup() +void stat_cleanup(void) { int i; /* wake up the childern so they can detach the memory and exit */ for (i = 0; i < N_ATTACH; i++) { - if (kill(pid_arr[i], SIGUSR1) == -1) { + if (kill(pid_arr[i], SIGUSR1) == -1) tst_brkm(TBROK, cleanup, "kill failed"); - } } /* remove the parent's shared memory the second time through */ if (stat_time == SECOND) { - if (shmdt(set_shared) == -1) { + if (shmdt(set_shared) == -1) tst_resm(TINFO, "shmdt() failed"); - } } for (i = 0; i < N_ATTACH; i++) { @@ -425,7 +403,7 @@ void stat_cleanup() /* * set_setup() - set up for the IPC_SET command with shmctl() */ -void set_setup() +void set_setup(void) { /* set up a new mode for the shared memory segment */ buf.shm_perm.mode = SHM_RW | NEWMODE; @@ -437,7 +415,7 @@ void set_setup() /* * func_set() - check the functionality of the IPC_SET command with shmctl() */ -void func_set() +void func_set(int ret) { int fail = 0; @@ -447,7 +425,8 @@ void func_set() return; } - if ((buf.shm_perm.mode & MODE_MASK) != ((SHM_RW | NEWMODE) & MODE_MASK)) { + if ((buf.shm_perm.mode & MODE_MASK) != + ((SHM_RW | NEWMODE) & MODE_MASK)) { tst_resm(TFAIL, "new mode is incorrect"); fail = 1; } @@ -457,28 +436,68 @@ void func_set() fail = 1; } - if (fail) { + if (fail) return; - } tst_resm(TPASS, "new mode and change time are correct"); } +static void func_info(int ret) +{ + if (info.shmmin != 1) + tst_resm(TFAIL, "value of shmmin is incorrect"); + else + tst_resm(TPASS, "get correct shared memory limits"); +} + +static void func_sstat(int ret) +{ + if (ret >= 0) + tst_resm(TPASS, "get correct shared memory id"); + else + tst_resm(TFAIL, "shared memory id is incorrect"); +} + +static void func_lock(int ret) +{ + if (shmctl(shm_id_1, IPC_STAT, &buf) == -1) { + tst_resm(TBROK, "stat failed in func_lock()"); + return; + } + + if (buf.shm_perm.mode & SHM_LOCKED) + tst_resm(TPASS, "SHM_LOCK is set"); + else + tst_resm(TFAIL, "SHM_LOCK is cleared"); +} + +static void func_unlock(int ret) +{ + if (shmctl(shm_id_1, IPC_STAT, &buf) == -1) { + tst_resm(TBROK, "stat failed in func_unlock()"); + return; + } + + if (buf.shm_perm.mode & SHM_LOCKED) + tst_resm(TFAIL, "SHM_LOCK is set"); + else + tst_resm(TPASS, "SHM_LOCK is cleared"); +} + + /* * func_rmid() - check the functionality of the IPC_RMID command with shmctl() */ -void func_rmid() +void func_rmid(int ret) { /* Do another shmctl() - we should get EINVAL */ - if (shmctl(shm_id_1, IPC_STAT, &buf) != -1) { + if (shmctl(shm_id_1, IPC_STAT, &buf) != -1) tst_brkm(TBROK, cleanup, "shmctl succeeded on expected fail"); - } - if (errno != EINVAL) { + if (errno != EINVAL) tst_resm(TFAIL, "returned unexpected errno %d", errno); - } else { + else tst_resm(TPASS, "shared memory appears to be removed"); - } shm_id_1 = -1; } @@ -486,7 +505,7 @@ void func_rmid() /* * sighandler() - handle signals, in this case SIGUSR1 is the only one expected */ -void sighandler(sig) +void sighandler(int sig) { if (sig != SIGUSR1) tst_resm(TBROK, "received unexpected signal %d", sig); @@ -494,37 +513,20 @@ void sighandler(sig) void setup(void) { - tst_sig(FORK, sighandler, cleanup); TEST_PAUSE; - /* - * Create a temporary directory and cd into it. - * This helps to ensure that a unique msgkey is created. - * See ../lib/libipc.c for more information. - */ tst_tmpdir(); - /* get an IPC resource key */ shmkey = getipckey(); } -/* - * cleanup() - performs all the ONE TIME cleanup for this test at completion - * or premature exit. - */ void cleanup(void) { - /* if it exists, remove the shared memory segment */ rm_shm(shm_id_1); tst_rmdir(); - /* - * print timing stats if that option was specified. - * print errno log if that option was specified. - */ TEST_CLEANUP; - } hooks/post-receive -- ltp |