[LTP] [PATCH 3/4] ipc/msgget02.c: reconstruct && convert to new API

Cyril Hrubis chrubis@suse.cz
Wed Nov 23 15:13:51 CET 2016


Hi!
> diff --git a/testcases/kernel/syscalls/ipc/msgget/msgget02.c b/testcases/kernel/syscalls/ipc/msgget/msgget02.c
> index be9bc61..85104e8 100644
> --- a/testcases/kernel/syscalls/ipc/msgget/msgget02.c
> +++ b/testcases/kernel/syscalls/ipc/msgget/msgget02.c
> @@ -1,176 +1,119 @@
>  /*
> + * 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.
>   */
>  
>  /*
> - * NAME
> - *	msgget02.c
> + * NAME: msgget02.c
>   *
>   * DESCRIPTION
> - *	msgget02 - test for EEXIST and ENOENT errors
> - *
> - * ALGORITHM
> - *	create a message queue
> - *	loop if that option was specified
> - *	try to recreate the same queue - test #1
> - *	try to access a queue that doesn't exist - tests #2 & #3
> - *	check the errno value
> - *	  issue a PASS message if we get EEXIST or ENOENT depening on test
> - *	otherwise, the tests fails
> - *	  issue a FAIL message
> - *	  break any remaining tests
> - *	  call cleanup
> - *
> - * USAGE:  <for command-line>
> - *  msgget02 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
> - *     where,  -c n : Run n copies concurrently.
> - *             -e   : Turn on errno logging.
> - *	       -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
> + * 1) msgget(2) fails if a message queue exists for key and msgflg
> + *    specified both IPC_CREAT and IPC_EXCL.
> + * 2) msgget(2) fails if no message queue exists for key and msgflg
> + *    did not specify IPC_CREAT.
> + * 3) msgget(2) fails if a message queue exists for key, but the
> + *    calling process does not have permission to access the queue,
> + *    and does not have the CAP_IPC_OWNER capability.
>   *
> - *      28/03/2008 Renaud Lottiaux (Renaud.Lottiaux@kerlabs.com)
> - *      - Fix concurrency issue. The second key used for this test was
> - *        sometime conflicting with the key from another task.
> - *        Generate a valid second key through getipckey to avoid conflicts.
> - *
> - * RESTRICTIONS
> - *	none
>   */
>  
> -#include "test.h"
> +#include <sys/types.h>
> +#include <sys/ipc.h>
> +#include <sys/msg.h>
> +#include <pwd.h>
>  
> -#include "ipcmsg.h"
> +#include "tst_ipcmsg.h"
> +#include "tst_test.h"
>  
> -char *TCID = "msgget02";
> -int TST_TOTAL = 3;
> +static key_t msgkey1;
> +static int msg_q_1 = -1;
>  
> -struct test_case_t {
> -	int error;
> -	int msgkey;
> +static struct tcase {
> +	int *key;
>  	int flags;
> -} TC[] = {
> -	{
> -	EEXIST, 0, IPC_CREAT | IPC_EXCL}, {
> -	ENOENT, 1, IPC_PRIVATE}, {
> -	ENOENT, 1, IPC_EXCL}
> +	int exp_err;
> +} tcases[] = {
> +	{&msgkey, IPC_CREAT | IPC_EXCL, EEXIST},
> +	{&msgkey1, IPC_PRIVATE, ENOENT},
> +	{&msgkey1, IPC_EXCL, ENOENT},
> +	{&msgkey, MSG_RD, EACCES},
> +	{&msgkey, MSG_WR, EACCES},
> +	{&msgkey, MSG_RD | MSG_WR, EACCES}
>  };
>  
> -key_t msgkey1;
> -int msg_q_1 = -1;		/* The message queue id created in setup */
> -
> -int main(int ac, char **av)
> +static void verify_msgget(struct tcase *tc)
>  {
> -	int lc;
> -	int i;
> -	key_t key;
> -
> -	tst_parse_opts(ac, av, NULL, NULL);
> -
> -	setup();		/* global setup */
> +	TEST(msgget(*tc->key, tc->flags));
>  
> -	/* 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 < TST_TOTAL; i++) {
> -
> -			if (TC[i].msgkey == 0)
> -				key = msgkey;
> -			else
> -				key = msgkey1;
> -
> -			TEST(msgget(key, TC[i].flags));
> +	if (TEST_RETURN != -1) {
> +		tst_res(TFAIL, "msgget() succeeded unexpectedly");
> +		return;
> +	}
>  
> -			if (TEST_RETURN != -1) {
> -				tst_resm(TFAIL, "msgget() call succeeded "
> -					 "on expected fail");
> -				continue;
> -			}
> +	if (TEST_ERRNO == tc->exp_err)
> +		tst_res(TPASS | TTERRNO, "msgget() failed as expected");
> +	else
> +		tst_res(TFAIL | TTERRNO, "msgget() failed unexpectedly,"
> +			" expected %s", tst_strerrno(tc->exp_err));
> +}
>  
> -			switch (TEST_ERRNO) {
> -			case ENOENT:
> -			 /*FALLTHROUGH*/ case EEXIST:
> -				if (TEST_ERRNO == TC[i].error) {
> -					tst_resm(TPASS, "expected failure - "
> -						 "errno = %d : %s", TEST_ERRNO,
> -						 strerror(TEST_ERRNO));
> -					break;
> -				}
> -			/*FALLTHROUGH*/ default:
> -				tst_resm(TFAIL, "call failed with an "
> -					 "unexpected error - %d : %s",
> -					 TEST_ERRNO, strerror(TEST_ERRNO));
> -				break;
> -			}
> +static void verify_access(unsigned int n)
               ^
	       The function name is confusing, we do not test access()
	       call here. I would have just called this do_test() or
	       something.

> +{
> +	pid_t pid;
> +	uid_t uid;
> +	struct passwd *pw;
> +	struct tcase *tc = &tcases[n];
> +
> +	if (tc->exp_err != EACCES) {

Switching on the expected errno is kind of confusing. I would rather see
as_nobody bitflag in the tcases structure that is set to 1 for this
particular case.

> +		verify_msgget(tc);
> +	} else {
> +		pw = SAFE_GETPWNAM("nobody");
> +		uid = pw->pw_uid;

This should be done in the test setup()

> +		pid = SAFE_FORK();
> +		if (pid) {
> +			SAFE_WAITPID(pid, NULL, 0);

If you do not want to check the child return value here you should
rather call tst_reap_children() that will do that for you.

> +		} else {
> +			SAFE_SETUID(uid);
> +			verify_msgget(tc);

Missing exit(0) here?

>  		}
>  	}
> -
> -	cleanup();
> -
> -	tst_exit();
>  }
>  
> -/*
> - * setup() - performs all the ONE TIME setup for this test.
> - */
> -void setup(void)
> +static void setup(void)
>  {
> -
> -	tst_sig(NOFORK, DEF_HANDLER, 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();
> -
>  	msgkey = getipckey();
>  	msgkey1 = getipckey();
>  
> -	/* now we have a key, so let's create a message queue */
> -	if ((msg_q_1 = msgget(msgkey, IPC_CREAT | IPC_EXCL)) == -1) {
> -		system("ipcs > /tmp/toto");
> -		system("ps -aux >> /tmp/toto");
> -		tst_brkm(TBROK, cleanup, "Can't create message queue");
> -	}
> +	msg_q_1 = msgget(msgkey, IPC_CREAT | IPC_EXCL);
> +	if (msg_q_1 == -1)
> +		tst_brk(TBROK, "Can't create message queue");
>  }

-- 
Cyril Hrubis
chrubis@suse.cz


More information about the ltp mailing list