diff options
Diffstat (limited to 'tools/testing/selftests/proc/proc-tid0.c')
| -rw-r--r-- | tools/testing/selftests/proc/proc-tid0.c | 81 | 
1 files changed, 81 insertions, 0 deletions
diff --git a/tools/testing/selftests/proc/proc-tid0.c b/tools/testing/selftests/proc/proc-tid0.c new file mode 100644 index 000000000000..58c1d7c90a8e --- /dev/null +++ b/tools/testing/selftests/proc/proc-tid0.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2021 Alexey Dobriyan <[email protected]> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +// Test that /proc/*/task never contains "0". +#include <sys/types.h> +#include <dirent.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <pthread.h> + +static pid_t pid = -1; + +static void atexit_hook(void) +{ +	if (pid > 0) { +		kill(pid, SIGKILL); +	} +} + +static void *f(void *_) +{ +	return NULL; +} + +static void sigalrm(int _) +{ +	exit(0); +} + +int main(void) +{ +	pid = fork(); +	if (pid == 0) { +		/* child */ +		while (1) { +			pthread_t pth; +			pthread_create(&pth, NULL, f, NULL); +			pthread_join(pth, NULL); +		} +	} else if (pid > 0) { +		/* parent */ +		atexit(atexit_hook); + +		char buf[64]; +		snprintf(buf, sizeof(buf), "/proc/%u/task", pid); + +		signal(SIGALRM, sigalrm); +		alarm(1); + +		while (1) { +			DIR *d = opendir(buf); +			struct dirent *de; +			while ((de = readdir(d))) { +				if (strcmp(de->d_name, "0") == 0) { +					exit(1); +				} +			} +			closedir(d); +		} + +		return 0; +	} else { +		perror("fork"); +		return 1; +	} +}  |