2011-12-08 16:01:47 +01:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/wait.h>
|
2013-12-12 14:27:56 +01:00
|
|
|
#include <sys/syslimits.h>
|
2011-12-08 16:01:47 +01:00
|
|
|
#include <fcntl.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
2013-04-16 18:04:46 +02:00
|
|
|
int max_error = 5;
|
|
|
|
#include "common.h"
|
|
|
|
|
2011-12-08 16:01:47 +01:00
|
|
|
|
|
|
|
void dangling_slink(int sub_test, char const slink_to[PATH_MAX]);
|
|
|
|
|
|
|
|
void dangling_slink(int sub_test, char const slink_to[PATH_MAX])
|
|
|
|
{
|
|
|
|
pid_t child;
|
|
|
|
|
|
|
|
subtest = sub_test;
|
|
|
|
|
|
|
|
child = fork();
|
|
|
|
if (child == (pid_t) -1) {
|
|
|
|
e(1);
|
|
|
|
return;
|
|
|
|
} else if (child == (pid_t) 0) {
|
|
|
|
/* I'm the child. Create a dangling symlink with an absolute path */
|
|
|
|
int fd;
|
|
|
|
char buf[4];
|
|
|
|
|
|
|
|
|
|
|
|
/* We don't want to actually write to '/', so instead we pretend */
|
|
|
|
if (chroot(".") != 0) e(2);
|
|
|
|
|
|
|
|
/* Create file 'slink_to' with contents "bar" */
|
|
|
|
if ((fd = open(slink_to, O_CREAT|O_WRONLY)) == -1) e(3);
|
|
|
|
if (write(fd, "bar", strlen("bar")) != strlen("bar")) e(4);
|
|
|
|
close(fd);
|
|
|
|
|
|
|
|
if (symlink(slink_to, "a") == -1) e(5); /* Create the symlink */
|
|
|
|
if (rename(slink_to, "c") == -1) e(6); /* Make it a dangling symlink */
|
|
|
|
|
|
|
|
/* Write "foo" to symlink; this should recreate file 'slink_to' with
|
|
|
|
* contents "foo" */
|
|
|
|
if ((fd = open("a", O_CREAT|O_WRONLY)) == -1) e(7);
|
|
|
|
if (write(fd, "foo", strlen("foo")) != strlen("foo")) e(8);
|
|
|
|
close(fd);
|
|
|
|
|
|
|
|
/* Verify 'a' and 'slink_to' contain "foo" */
|
|
|
|
memset(buf, '\0', sizeof(buf));
|
|
|
|
if ((fd = open("a", O_RDONLY)) == -1) e(9);
|
|
|
|
if (read(fd, buf, 3) != 3) e(10);
|
|
|
|
if (strncmp(buf, "foo", strlen("foo"))) e(11);
|
|
|
|
close(fd);
|
|
|
|
memset(buf, '\0', sizeof(buf));
|
|
|
|
if ((fd = open(slink_to, O_RDONLY)) == -1) e(12);
|
|
|
|
if (read(fd, buf, 3) != 3) e(13);
|
|
|
|
if (strncmp(buf, "foo", strlen("foo"))) e(14);
|
|
|
|
close(fd);
|
|
|
|
|
|
|
|
/* Verify 'c' contains 'bar' */
|
|
|
|
memset(buf, '\0', sizeof(buf));
|
|
|
|
if ((fd = open("c", O_RDONLY)) == -1) e(15);
|
|
|
|
if (read(fd, buf, 3) != 3) e(16);
|
|
|
|
if (strncmp(buf, "bar", strlen("bar"))) e(17);
|
|
|
|
close(fd);
|
|
|
|
|
|
|
|
/* Cleanup created files */
|
|
|
|
if (unlink(slink_to) == -1) e(18);
|
|
|
|
if (unlink("a") == -1) e(19);
|
|
|
|
if (unlink("c") == -1) e(20);
|
|
|
|
|
|
|
|
exit(EXIT_SUCCESS);
|
|
|
|
} else {
|
|
|
|
int status;
|
|
|
|
if (wait(&status) == -1) e(7);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
start(61);
|
|
|
|
dangling_slink(1, "/abs"); /* Create dangling symlink with absolute path */
|
|
|
|
dangling_slink(2, "rel"); /* Create dangling symlink with relative path */
|
|
|
|
quit();
|
|
|
|
return(-1); /* Unreachable */
|
|
|
|
}
|
|
|
|
|