a209c3ae12
This patch fixes most of current reasons to generate compiler warnings. The changes consist of: - adding missing casts - hiding or unhiding function declarations - including headers where missing - add __UNCONST when assigning a const char * to a char * - adding missing return statements - changing some types from unsigned to signed, as the code seems to want signed ints - converting old-style function definitions to current style (i.e., void func(param1, param2) short param1, param2; {...} to void func (short param1, short param2) {...}) - making the compiler silent about signed vs unsigned comparisons. We have too many of those in the new libc to fix. A number of bugs in the test set were fixed. These bugs were never triggered with our old libc. Consequently, these tests are now forced to link with the new libc or they will generate errors (in particular tests 43 and 55). Most changes in NetBSD libc are limited to moving aroudn "#ifndef __minix" or stuff related to Minix-specific things (code in sys-minix or gen/minix).
341 lines
6.1 KiB
C
341 lines
6.1 KiB
C
/* test 5 */
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/wait.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <signal.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#define ITERATIONS 2
|
|
#define MAX_ERROR 3
|
|
|
|
int subtest;
|
|
int zero[1024];
|
|
int sigmap[5] = {9, 10, 11};
|
|
|
|
#include "common.c"
|
|
|
|
_PROTOTYPE(int main, (int argc, char *argv[]));
|
|
_PROTOTYPE(void test5a, (void));
|
|
_PROTOTYPE(void parent, (int childpid));
|
|
_PROTOTYPE(void child, (int parpid));
|
|
_PROTOTYPE(void func1, (int s));
|
|
_PROTOTYPE(void func8, (int s));
|
|
_PROTOTYPE(void func10, (int s));
|
|
_PROTOTYPE(void func11, (int s));
|
|
_PROTOTYPE(void test5b, (void));
|
|
_PROTOTYPE(void test5c, (void));
|
|
_PROTOTYPE(void test5d, (void));
|
|
_PROTOTYPE(void test5e, (void));
|
|
_PROTOTYPE(void test5f, (void));
|
|
_PROTOTYPE(void test5g, (void));
|
|
_PROTOTYPE(void funcalrm, (int s));
|
|
_PROTOTYPE(void test5h, (void));
|
|
_PROTOTYPE(void test5i, (void));
|
|
_PROTOTYPE(void ex, (void));
|
|
|
|
_VOLATILE int childsigs, parsigs, alarms;
|
|
|
|
int main(argc, argv)
|
|
int argc;
|
|
char *argv[];
|
|
{
|
|
int i, m = 0x7777;
|
|
|
|
start(5);
|
|
|
|
for (i = 0; i < ITERATIONS; i++) {
|
|
if (m & 0001) test5a();
|
|
if (m & 0002) test5b();
|
|
if (m & 0004) test5c();
|
|
if (m & 0010) test5d();
|
|
if (m & 0020) test5e();
|
|
if (m & 0040) test5f();
|
|
if (m & 0100) test5g();
|
|
if (m & 0200) test5h();
|
|
if (m & 0400) test5i();
|
|
}
|
|
quit();
|
|
return(-1); /* impossible */
|
|
}
|
|
|
|
void test5a()
|
|
{
|
|
int parpid, childpid, flag, *zp;
|
|
|
|
subtest = 0;
|
|
flag = 0;
|
|
for (zp = &zero[0]; zp < &zero[1024]; zp++)
|
|
if (*zp != 0) flag = 1;
|
|
if (flag) e(0); /* check if bss is cleared to 0 */
|
|
if (signal(1, func1) == SIG_ERR) e(1);
|
|
if (signal(10, func10) == SIG_ERR) e(2);
|
|
parpid = getpid();
|
|
if ((childpid = fork()) != 0) {
|
|
if (childpid < 0) ex();
|
|
parent(childpid);
|
|
} else {
|
|
child(parpid);
|
|
}
|
|
if (signal(1, SIG_DFL) == SIG_ERR) e(4);
|
|
if (signal(10, SIG_DFL) == SIG_ERR) e(5);
|
|
}
|
|
|
|
void parent(childpid)
|
|
int childpid;
|
|
{
|
|
int i, pid;
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
if (kill(childpid, 1) < 0) e(6);
|
|
while (parsigs == 0);
|
|
parsigs--;
|
|
}
|
|
if ( (pid = wait(&i)) < 0) e(7);
|
|
if (i != 256 * 6) e(8);
|
|
}
|
|
|
|
void child(parpid)
|
|
int parpid;
|
|
{
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
while (childsigs == 0);
|
|
childsigs--;
|
|
if (kill(parpid, 10) < 0) e(9);
|
|
}
|
|
exit(6);
|
|
}
|
|
|
|
void func1(s)
|
|
int s; /* for ANSI */
|
|
{
|
|
if (signal(1, func1) == SIG_ERR) e(10);
|
|
childsigs++;
|
|
}
|
|
|
|
void func8(s)
|
|
int s;
|
|
{
|
|
}
|
|
|
|
void func10(s)
|
|
int s; /* for ANSI */
|
|
{
|
|
if (signal(10, func10) == SIG_ERR) e(11);
|
|
parsigs++;
|
|
}
|
|
|
|
void func11(s)
|
|
int s; /* for ANSI */
|
|
{
|
|
e(38);
|
|
}
|
|
|
|
void test5b()
|
|
{
|
|
int cpid, n, pid;
|
|
|
|
subtest = 1;
|
|
if ((pid = fork()) != 0) {
|
|
if (pid < 0) ex();
|
|
if ((pid = fork()) != 0) {
|
|
if (pid < 0) ex();
|
|
if ((cpid = fork()) != 0) {
|
|
if (cpid < 0) ex();
|
|
if (kill(cpid, 9) < 0) e(12);
|
|
if (wait(&n) < 0) e(13);
|
|
if (wait(&n) < 0) e(14);
|
|
if (wait(&n) < 0) e(15);
|
|
} else {
|
|
pause();
|
|
while (1);
|
|
}
|
|
} else {
|
|
exit(0);
|
|
}
|
|
} else {
|
|
exit(0);
|
|
}
|
|
}
|
|
|
|
void test5c()
|
|
{
|
|
int n, i, pid, wpid;
|
|
|
|
/* Test exit status codes for processes killed by signals. */
|
|
subtest = 3;
|
|
for (i = 0; i < 2; i++) {
|
|
if ((pid = fork()) != 0) {
|
|
if (pid < 0) ex();
|
|
sleep(2); /* wait for child to pause */
|
|
if (kill(pid, sigmap[i]) < 0) {
|
|
e(20);
|
|
exit(1);
|
|
}
|
|
if ((wpid = wait(&n)) < 0) e(21);
|
|
if ((n & 077) != sigmap[i]) e(22);
|
|
if (pid != wpid) e(23);
|
|
} else {
|
|
pause();
|
|
exit(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
void test5d()
|
|
{
|
|
/* Test alarm */
|
|
|
|
int i;
|
|
|
|
subtest = 4;
|
|
alarms = 0;
|
|
for (i = 0; i < 8; i++) {
|
|
signal(SIGALRM, funcalrm);
|
|
alarm(1);
|
|
pause();
|
|
if (alarms != i + 1) e(24);
|
|
}
|
|
}
|
|
|
|
void test5e()
|
|
{
|
|
/* When a signal knocks a processes out of WAIT or PAUSE, it is supposed to
|
|
* get EINTR as error status. Check that.
|
|
*/
|
|
int n, j;
|
|
|
|
subtest = 5;
|
|
if (signal(8, func8) == SIG_ERR) e(25);
|
|
if ((n = fork()) != 0) {
|
|
/* Parent must delay to give child a chance to pause. */
|
|
if (n < 0) ex();
|
|
sleep(1);
|
|
if (kill(n, 8) < 0) e(26);
|
|
if (wait(&n) < 0) e(27);
|
|
if (signal(8, SIG_DFL) == SIG_ERR) e(28);
|
|
} else {
|
|
j = pause();
|
|
if (errno != EINTR && -errno != EINTR) e(29);
|
|
exit(0);
|
|
}
|
|
}
|
|
|
|
void test5f()
|
|
{
|
|
int i, j, k, n;
|
|
|
|
subtest = 6;
|
|
if (getuid() != 0) return;
|
|
n = fork();
|
|
if (n < 0) ex();
|
|
if (n) {
|
|
wait(&i);
|
|
i = (i >> 8) & 0377;
|
|
if (i != (n & 0377)) e(30);
|
|
} else {
|
|
i = getgid();
|
|
j = getegid();
|
|
k = (i + j + 7) & 0377;
|
|
if (setgid(k) < 0) e(31);
|
|
if (getgid() != k) e(32);
|
|
if (getegid() != k) e(33);
|
|
i = getuid();
|
|
j = geteuid();
|
|
k = (i + j + 1) & 0377;
|
|
if (setuid(k) < 0) e(34);
|
|
if (getuid() != k) e(35);
|
|
if (geteuid() != k) e(36);
|
|
i = getpid() & 0377;
|
|
if (wait(&j) != -1) e(37);
|
|
exit(i);
|
|
}
|
|
}
|
|
|
|
void test5g()
|
|
{
|
|
int n;
|
|
|
|
subtest = 7;
|
|
signal(11, func11);
|
|
signal(11, SIG_IGN);
|
|
n = getpid();
|
|
if (kill(n, 11) != 0) e(1);
|
|
signal(11, SIG_DFL);
|
|
}
|
|
|
|
void funcalrm(s)
|
|
int s; /* for ANSI */
|
|
{
|
|
alarms++;
|
|
}
|
|
|
|
void test5h()
|
|
{
|
|
/* When a signal knocks a processes out of PIPE, it is supposed to
|
|
* get EINTR as error status. Check that.
|
|
*/
|
|
int n, j, fd[2];
|
|
|
|
subtest = 8;
|
|
unlink("XXX.test5");
|
|
if (signal(8, func8) == SIG_ERR) e(1);
|
|
pipe(fd);
|
|
if ((n = fork()) != 0) {
|
|
/* Parent must delay to give child a chance to pause. */
|
|
if (n < 0) ex();
|
|
while (access("XXX.test5", 0) != 0) /* just wait */ ;
|
|
sleep(1);
|
|
unlink("XXX.test5");
|
|
if (kill(n, 8) < 0) e(2);
|
|
if (wait(&n) < 0) e(3);
|
|
if (signal(8, SIG_DFL) == SIG_ERR) e(4);
|
|
if (close(fd[0]) != 0) e(5);
|
|
if (close(fd[1]) != 0) e(6);
|
|
} else {
|
|
if (creat("XXX.test5", 0777) < 0) e(7);
|
|
j = read(fd[0], (char *) &n, 1);
|
|
if (errno != EINTR) e(8);
|
|
exit(0);
|
|
}
|
|
}
|
|
|
|
void test5i()
|
|
{
|
|
int fd[2], pid, buf[10], n;
|
|
|
|
subtest = 9;
|
|
pipe(fd);
|
|
unlink("XXXxxxXXX");
|
|
|
|
if ((pid = fork()) != 0) {
|
|
/* Parent */
|
|
/* Wait until child has started and has created the XXXxxxXXX file. */
|
|
while (access("XXXxxxXXX", 0) != 0) /* loop */ ;
|
|
sleep(1);
|
|
if (kill(pid, SIGKILL) != 0) e(1);
|
|
if (wait(&n) < 0) e(2);
|
|
if (close(fd[0]) != 0) e(3);
|
|
if (close(fd[1]) != 0) e(4);
|
|
} else {
|
|
if (creat("XXXxxxXXX", 0777) < 0) e(5);
|
|
read(fd[0], (char *) buf, 1);
|
|
e(5); /* should be killed by signal and not get here */
|
|
}
|
|
unlink("XXXxxxXXX");
|
|
}
|
|
|
|
void ex()
|
|
{
|
|
int e = errno;
|
|
printf("Fork failed: %s (%d)\n", strerror(e), e);
|
|
exit(1);
|
|
}
|
|
|