ptcwd_test_11269991.c [plain text]
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/syscall.h>
#include <sys/errno.h>
#include <sys/stat.h>
#include <sys/param.h>
#ifndef SYS___pthread_chdir
#define SYS___pthread_chdir 348
#endif
#ifndef SYS___pthread_fchdir
#define SYS___pthread_fchdir 349
#endif
#define WORKDIR "/private/tmp/ptwork"
#define WORKDIR1 WORKDIR "/one"
#define WORKDIR2 WORKDIR "/two"
int
pthread_chdir_np(char *path)
{
return syscall(SYS___pthread_chdir, path);
}
int
pthread_fchdir_np(int fd)
{
return syscall(SYS___pthread_fchdir, fd);
}
char *
pthread_getcwd_np(char *buf, size_t size)
{
int fd_cwd;
if (buf == NULL)
return (NULL);
if ((fd_cwd = open(".", O_RDONLY)) == -1)
return (NULL);
if (pthread_fchdir_np( -1) == -1) {
close (fd_cwd);
return (NULL);
}
if (pthread_fchdir_np(fd_cwd) == -1) {
close(fd_cwd);
errno = EBADF;
return (NULL);
}
close(fd_cwd);
return getcwd(buf, size);
}
int
main(int ac, char *av[])
{
char buf[MAXPATHLEN];
char *p;
if (pthread_fchdir_np( -1) != -1) {
fprintf(stderr, "FAIL: Started out on PT CWD\n");
exit(1);
}
umask(0);
if (mkdir(WORKDIR, 0777) == -1 && errno != EEXIST) {
perror("FAIL: mkdir: " WORKDIR);
exit(2);
}
printf("workdir \"" WORKDIR "\" created\n");
if (mkdir(WORKDIR1, 0777) == -1 && errno != EEXIST) {
perror("FAIL: mkdir: " WORKDIR1);
exit(2);
}
printf("workdir \"" WORKDIR1 "\" created\n");
if (mkdir(WORKDIR2, 0777) == -1 && errno != EEXIST) {
perror("FAIL: mkdir: " WORKDIR2);
exit(2);
}
printf("workdir \"" WORKDIR2 "\" created\n");
if (chdir(WORKDIR1) == -1) {
perror("FAIL: chdir: \"" WORKDIR1 "\" failed\n");
exit(3);
}
printf("process current working directory changed to \"" WORKDIR1 "\"...\n");
printf("verifying; getcwd says: \"%s\"\n", getcwd(buf, MAXPATHLEN));
if (strcmp(WORKDIR1, buf)) {
fprintf(stderr, "FAIL: \"%s\" != \"%s\"\n", WORKDIR1, buf);
exit(3);
}
printf("verified.\n");
if ((p = pthread_getcwd_np(buf, MAXPATHLEN)) != NULL) {
fprintf(stderr, "FAIL: pthread_getcwd_np should fail, got \"%s\" instead\n", p);
exit(4);
}
printf("Good so far: pthread_getcwd_np() got no answer (correct)\n");
if (pthread_chdir_np(WORKDIR2) == -1) {
perror("FAIL: pthread_chdir_np: " WORKDIR2);
exit(5);
}
printf("Set per thread current working directory to \"" WORKDIR2"\"\n");
printf("verifying; getcwd says: \"%s\"\n", getcwd(buf, MAXPATHLEN));
if (strcmp(WORKDIR2, buf)) {
fprintf(stderr, "FAIL: \"%s\" != \"%s\"\n", WORKDIR2, buf);
exit(3);
}
printf("verified.\n");
if ((p = pthread_getcwd_np(buf, MAXPATHLEN)) == NULL) {
perror("FAIL: pthread_getcwd_np");
exit(6);
}
printf("verifying... pthread_getcwd_np says \"%s\"\n", p);
if (strcmp(WORKDIR2, buf)) {
fprintf(stderr, "FAIL: \"%s\" != \"%s\"\n", WORKDIR2, buf);
exit(7);
}
printf("verified.\n");
printf("verifying our old cwd still exists by going of PT CWD...\n");
if (pthread_fchdir_np(-1) != 0) {
perror("FAIL: pthread_fchdir_np");
exit(8);
}
printf("off... but are we really off?\n");
printf("Check by verifying that pthread_getcwd_np now fails\n");
if ((p = pthread_getcwd_np(buf, MAXPATHLEN)) != NULL) {
fprintf(stderr, "FAIL: pthread_getcwd_np should fail, got \"%s\" instead\n", p);
exit(9);
}
printf("verified.\n");
printf("One last check: see that getcwd says \"" WORKDIR1 "\" again\n");
printf("verifying; getcwd says: \"%s\"\n", getcwd(buf, MAXPATHLEN));
if (strcmp(WORKDIR1, buf)) {
fprintf(stderr, "FAIL: \"%s\" != \"%s\"\n", WORKDIR1, buf);
exit(10);
}
printf("verified.\n");
printf("\nPASS: testing was successful\n");
exit(0);
}