/* * * 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 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 */ /* * NAME * semctl01.c * * DESCRIPTION * semctl01 - test the 10 possible semctl() commands * * ALGORITHM * create a semaphore set with read and alter permissions * loop if that option was specified * loop through the test cases * do any setup required for the test case * make the semctl() call using the TEST() macro * check the return code * if failure, issue a FAIL message. * otherwise, * if doing functionality testing * call the appropriate test function * if correct, * issue a PASS message * otherwise * issue a FAIL message * call cleanup * * USAGE: * semctl01 [-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 * * RESTRICTIONS * none */ #include "ipcsem.h" char *TCID = "semctl01"; int TST_TOTAL = 10; extern int Tst_count; int sem_id_1 = -1; /* a semaphore set with read and alter permissions */ /* * These are the various setup and check functions for the 10 different * commands that are available for the semctl() call. */ void func_stat(int); void set_setup(int), func_set(int); void func_gall(int); void cnt_setup(int), func_cnt(int); void pid_setup(int), func_pid(int); void gval_setup(int), func_gval(int); void sall_setup(int), func_sall(int); void func_sval(int); void func_rmid(int); void child_cnt(void); void child_pid(void); struct semid_ds buf; unsigned short array[PSEMS]; struct sembuf sops; #define INCVAL 2 /* a semaphore increment value */ #define NEWMODE 066 #define NCHILD 5 #define SEM2 2 /* semaphore to use for GETPID and GETVAL */ #define SEM4 4 /* semaphore to use for GETNCNT and GETZCNT */ #define ONE 1 #define SEMUN_CAST (union semun) int pid_arr[NCHILD]; #ifdef UCLINUX static char *argv0; #endif struct test_case_t { int semnum; /* the primitive semaphore to use */ int cmd; /* the command to test */ void (*func_test)(int); /* the test function */ union semun arg; void (*func_setup)(int); /* the setup function if necessary */ } TC[10]; void setup_test_cases(void) { int i; i = -1; /* {0, IPC_STAT, func_stat, &buf, NULL}, */ i++; TC[i].semnum = 0; TC[i].cmd = IPC_STAT; TC[i].func_test = func_stat; TC[i].arg.buf = &buf; TC[i].func_setup = NULL; /* {0, IPC_SET, func_set, &buf, set_setup}, */ i++; TC[i].semnum = 0; TC[i].cmd = IPC_SET; TC[i].func_test = func_set; TC[i].arg.buf = &buf; TC[i].func_setup = set_setup; /* {0, GETALL, func_gall, array, NULL}, */ i++; TC[i].semnum = 0; TC[i].cmd = GETALL; TC[i].func_test = func_gall; TC[i].arg.array = array; TC[i].func_setup = NULL; /* {SEM4, GETNCNT, func_cnt, SEMUN_CAST &buf, cnt_setup}, */ i++; TC[i].semnum = SEM4; TC[i].cmd = GETNCNT; TC[i].func_test = func_cnt; TC[i].arg.buf = &buf; TC[i].func_setup = cnt_setup; /* {SEM2, GETPID, func_pid, SEMUN_CAST &buf, pid_setup}, */ i++; TC[i].semnum = SEM2; TC[i].cmd = GETPID; TC[i].func_test = func_pid; TC[i].arg.buf = &buf; TC[i].func_setup = pid_setup; /* {SEM2, GETVAL, func_gval, SEMUN_CAST &buf, NULL}, */ i++; TC[i].semnum = SEM2; TC[i].cmd = GETVAL; TC[i].func_test = func_gval; TC[i].arg.buf = &buf; TC[i].func_setup = NULL; /* {SEM4, GETZCNT, func_cnt, SEMUN_CAST &buf, cnt_setup}, */ i++; TC[i].semnum = SEM4; TC[i].cmd = GETZCNT; TC[i].func_test = func_cnt; TC[i].arg.buf = &buf; TC[i].func_setup = cnt_setup; /* {0, SETALL, func_sall, SEMUN_CAST array, sall_setup}, */ i++; TC[i].semnum = 0; TC[i].cmd = SETALL; TC[i].func_test = func_sall; TC[i].arg.array = array; TC[i].func_setup = sall_setup; /* {SEM4, SETVAL, func_sval, SEMUN_CAST INCVAL, NULL}, */ i++; TC[i].semnum = SEM4; TC[i].cmd = SETVAL; TC[i].func_test = func_sval; TC[i].arg.val = INCVAL; TC[i].func_setup = NULL; /* {0, IPC_RMID, func_rmid, SEMUN_CAST &buf, NULL} */ i++; TC[i].semnum = 0; TC[i].cmd = IPC_RMID; TC[i].func_test = func_rmid; TC[i].arg.buf = &buf; TC[i].func_setup = NULL; } int main(int ac, char **av) { int lc; /* loop counter */ char *msg; /* message returned from parse_opts */ int i, j; /* parse standard options */ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg); } #ifdef UCLINUX argv0 = av[0]; maybe_run_child(&child_pid, "nd", 1, &sem_id_1); maybe_run_child(&child_cnt, "ndd", 2, &sem_id_1, &sops.sem_op); #endif setup(); /* global setup */ /* The following loop checks looping state if -i option given */ for (lc = 0; TEST_LOOPING(lc); lc++) { /* reset Tst_count in case we are looping */ Tst_count = 0; /* loop through the test cases */ for (i=0; i