t_umask.c revision 311587
113547Sjulian/* $NetBSD: t_umask.c,v 1.1 2011/07/07 06:57:54 jruoho Exp $ */
213547Sjulian
335025Sjb/*-
413547Sjulian * Copyright (c) 2011 The NetBSD Foundation, Inc.
513547Sjulian * All rights reserved.
613547Sjulian *
713547Sjulian * This code is derived from software contributed to The NetBSD Foundation
813547Sjulian * by Jukka Ruohonen.
913547Sjulian *
1013547Sjulian * Redistribution and use in source and binary forms, with or without
1113547Sjulian * modification, are permitted provided that the following conditions
1213547Sjulian * are met:
1313547Sjulian * 1. Redistributions of source code must retain the above copyright
1413547Sjulian *    notice, this list of conditions and the following disclaimer.
1513547Sjulian * 2. Redistributions in binary form must reproduce the above copyright
1613547Sjulian *    notice, this list of conditions and the following disclaimer in the
1713547Sjulian *    documentation and/or other materials provided with the distribution.
1813547Sjulian *
1913547Sjulian * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2013547Sjulian * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2113547Sjulian * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2213547Sjulian * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2313547Sjulian * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2413547Sjulian * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2513547Sjulian * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2613547Sjulian * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2713547Sjulian * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2813547Sjulian * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2913547Sjulian * POSSIBILITY OF SUCH DAMAGE.
3013547Sjulian */
3113547Sjulian#include <sys/cdefs.h>
3213547Sjulian__RCSID("$NetBSD: t_umask.c,v 1.1 2011/07/07 06:57:54 jruoho Exp $");
3350473Speter
3413547Sjulian#include <sys/stat.h>
3513547Sjulian#include <sys/wait.h>
3613547Sjulian
3713547Sjulian#include <atf-c.h>
3813547Sjulian#include <fcntl.h>
3913547Sjulian#include <stdlib.h>
4013547Sjulian#include <string.h>
4113547Sjulian#include <unistd.h>
4213547Sjulian
4313547Sjulianstatic const char path[] = "umask";
4417706Sjulianstatic const mode_t mask[] = {
4517706Sjulian	S_IRWXU,
4644965Sjb	S_IRUSR,
4713547Sjulian	S_IWUSR,
4813547Sjulian	S_IXUSR,
4917706Sjulian	S_IRWXG,
5013547Sjulian	S_IRGRP,
5117706Sjulian	S_IWGRP,
5217706Sjulian	S_IXGRP,
5317706Sjulian	S_IRWXO,
5417706Sjulian	S_IROTH,
5513547Sjulian	S_IWOTH,
5613547Sjulian	S_IXOTH
5722315Sjulian};
5822315Sjulian
5922315SjulianATF_TC_WITH_CLEANUP(umask_fork);
6022315SjulianATF_TC_HEAD(umask_fork, tc)
6122315Sjulian{
6222315Sjulian	atf_tc_set_md_var(tc, "descr", "Check that umask(2) is inherited");
6322315Sjulian}
6422315Sjulian
6522315SjulianATF_TC_BODY(umask_fork, tc)
6622315Sjulian{
6722315Sjulian	mode_t mode;
6822315Sjulian	pid_t pid;
6922315Sjulian	size_t i;
7038919Salex	int sta;
7138919Salex
7238919Salex	for (i = 0; i < __arraycount(mask) - 1; i++) {
7338919Salex
7438919Salex		(void)umask(mask[i] | mask[i + 1]);
7538919Salex
7653812Salfred		pid = fork();
7753812Salfred
7853812Salfred		if (pid < 0)
7953812Salfred			continue;
8053812Salfred
8153812Salfred		if (pid == 0) {
8253812Salfred
8353812Salfred			mode = umask(mask[i]);
8453812Salfred
8517706Sjulian			if (mode != (mask[i] | mask[i + 1]))
8617706Sjulian				_exit(EXIT_FAILURE);
8717706Sjulian
8813547Sjulian			_exit(EXIT_SUCCESS);
8917706Sjulian		}
9017706Sjulian
9117706Sjulian		(void)wait(&sta);
9217706Sjulian
9317706Sjulian		if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
9417706Sjulian			goto fail;
9517706Sjulian	}
9638919Salex
9738919Salex	return;
9813547Sjulian
9913547Sjulianfail:
10017706Sjulian	(void)umask(S_IWGRP | S_IWOTH);
10117706Sjulian
10217706Sjulian	atf_tc_fail("umask(2) was not inherited");
10317706Sjulian}
10417706Sjulian
10513547SjulianATF_TC_CLEANUP(umask_fork, tc)
10617706Sjulian{
10717706Sjulian	(void)umask(S_IWGRP | S_IWOTH);
10817706Sjulian}
10917706Sjulian
11017706SjulianATF_TC_WITH_CLEANUP(umask_open);
11117706SjulianATF_TC_HEAD(umask_open, tc)
11217706Sjulian{
11317706Sjulian	atf_tc_set_md_var(tc, "descr", "A basic test of open(2) and umask(2)");
11438919Salex}
11538919Salex
11613547SjulianATF_TC_BODY(umask_open, tc)
11713547Sjulian{
11817706Sjulian	const char *str = NULL;
11917706Sjulian	struct stat st;
12017706Sjulian	size_t i;
12117706Sjulian	int fd;
12213547Sjulian
12317706Sjulian	for (i = 0; i < __arraycount(mask); i++) {
12493032Simp
12513547Sjulian		(void)umask(mask[i]);
12613547Sjulian
12713547Sjulian		fd = open(path, O_RDWR | O_CREAT, 0777);
12813547Sjulian
12913547Sjulian		if (fd < 0)
13017706Sjulian			continue;
13117706Sjulian
13213547Sjulian#ifdef	__FreeBSD__
13313547Sjulian		(void)close(fd);
13413547Sjulian#endif
13513547Sjulian		(void)memset(&st, 0, sizeof(struct stat));
13613547Sjulian
13713547Sjulian		if (stat(path, &st) != 0) {
13813547Sjulian			str = "failed to stat(2)";
13913547Sjulian			goto out;
14013547Sjulian		}
14113547Sjulian
14213547Sjulian		if ((st.st_mode & mask[i]) != 0) {
14317706Sjulian			str = "invalid umask(2)";
14413547Sjulian			goto out;
14513547Sjulian		}
14635025Sjb
14713547Sjulian		if (unlink(path) != 0) {
14835025Sjb			str = "failed to unlink(2)";
14935025Sjb			goto out;
15038919Salex		}
15135025Sjb
15235025Sjb	}
15335025Sjb
15435025Sjbout:
15522315Sjulian	(void)umask(S_IWGRP | S_IWOTH);
15613547Sjulian
15713547Sjulian	if (str != NULL)
15813547Sjulian		atf_tc_fail("%s", str);
15913547Sjulian}
16013547Sjulian
16144965SjbATF_TC_CLEANUP(umask_open, tc)
16244965Sjb{
16344965Sjb	(void)umask(S_IWGRP | S_IWOTH);
16444965Sjb	(void)unlink(path);
16544965Sjb}
16644965Sjb
16744965SjbATF_TC_WITH_CLEANUP(umask_previous);
16844965SjbATF_TC_HEAD(umask_previous, tc)
16944965Sjb{
17044965Sjb	atf_tc_set_md_var(tc, "descr", "Test the return value from umask(2)");
17144965Sjb}
17244965Sjb
17344965SjbATF_TC_BODY(umask_previous, tc)
17444965Sjb{
17544965Sjb	mode_t mode;
17644965Sjb	size_t i;
17719637Shsu
17844965Sjb	for (i = 0; i < __arraycount(mask); i++) {
17944965Sjb
18044965Sjb		mode = umask(mask[i]);
18119637Shsu		mode = umask(mask[i]);
18219637Shsu
18319637Shsu		if (mode != mask[i])
18444965Sjb			goto fail;
18544965Sjb	}
18641390Seivind
18741390Seivind	return;
18813547Sjulian
18913547Sjulianfail:
19013547Sjulian	(void)umask(S_IWGRP | S_IWOTH);
19113547Sjulian
19293032Simp	atf_tc_fail("umask(2) did not return the previous mask");
19393032Simp}
19493032Simp
19593032SimpATF_TC_CLEANUP(umask_previous, tc)
19693032Simp{
19793032Simp	(void)umask(S_IWGRP | S_IWOTH);
19893032Simp}
19993032Simp
20093032SimpATF_TP_ADD_TCS(tp)
20193032Simp{
20293032Simp
20393032Simp	ATF_TP_ADD_TC(tp, umask_fork);
20493032Simp	ATF_TP_ADD_TC(tp, umask_open);
20593032Simp	ATF_TP_ADD_TC(tp, umask_previous);
20644965Sjb
20744965Sjb	return atf_no_error();
20893032Simp}
20993032Simp