[9] | 1 | /* test25: open (), close () (p) Jan-Mark Wams. email: jms@cs.vu.nl */
|
---|
| 2 |
|
---|
| 3 | /* Not tested: O_NONBLOCK on special files, supporting it.
|
---|
| 4 | ** On a read-only file system, some error reports are to be expected.
|
---|
| 5 | */
|
---|
| 6 |
|
---|
| 7 | #include <sys/types.h>
|
---|
| 8 | #include <sys/stat.h>
|
---|
| 9 | #include <sys/wait.h>
|
---|
| 10 | #include <stdlib.h>
|
---|
| 11 | #include <unistd.h>
|
---|
| 12 | #include <string.h>
|
---|
| 13 | #include <fcntl.h>
|
---|
| 14 | #include <limits.h>
|
---|
| 15 | #include <errno.h>
|
---|
| 16 | #include <time.h>
|
---|
| 17 | #include <stdio.h>
|
---|
| 18 |
|
---|
| 19 | #define MAX_ERROR 4
|
---|
| 20 | #define ITERATIONS 2
|
---|
| 21 |
|
---|
| 22 | #define System(cmd) if (system(cmd) != 0) printf("``%s'' failed\n", cmd)
|
---|
| 23 | #define Chdir(dir) if (chdir(dir) != 0) printf("Can't goto %s\n", dir)
|
---|
| 24 | #define Stat(a,b) if (stat(a,b) != 0) printf("Can't stat %s\n", a)
|
---|
| 25 | #define Creat(f) if (close(creat(f,0777))!=0) printf("Can't creat %s\n",f)
|
---|
| 26 | #define Report(s,n) printf("Subtest %d" s,subtest,(n))
|
---|
| 27 |
|
---|
| 28 | int errct = 0;
|
---|
| 29 | int subtest = 1;
|
---|
| 30 | int superuser;
|
---|
| 31 | char MaxName[NAME_MAX + 1]; /* Name of maximum length */
|
---|
| 32 | char MaxPath[PATH_MAX]; /* Same for path */
|
---|
| 33 | char ToLongName[NAME_MAX + 2]; /* Name of maximum +1 length */
|
---|
| 34 | char ToLongPath[PATH_MAX + 1]; /* Same for path, both too long */
|
---|
| 35 |
|
---|
| 36 | _PROTOTYPE(void main, (int argc, char *argv[]));
|
---|
| 37 | _PROTOTYPE(void test25a, (void));
|
---|
| 38 | _PROTOTYPE(void test25b, (void));
|
---|
| 39 | _PROTOTYPE(void test25c, (void));
|
---|
| 40 | _PROTOTYPE(void test25d, (void));
|
---|
| 41 | _PROTOTYPE(void test25e, (void));
|
---|
| 42 | _PROTOTYPE(void makelongnames, (void));
|
---|
| 43 | _PROTOTYPE(void e, (int number));
|
---|
| 44 | _PROTOTYPE(void quit, (void));
|
---|
| 45 |
|
---|
| 46 | void main(argc, argv)
|
---|
| 47 | int argc;
|
---|
| 48 | char *argv[];
|
---|
| 49 | {
|
---|
| 50 | int i, m = 0xFFFF;
|
---|
| 51 |
|
---|
| 52 | sync();
|
---|
| 53 | if (geteuid() == 0 || getuid() == 0) {
|
---|
| 54 | printf("Test 25 cannot run as root; test aborted\n");
|
---|
| 55 | exit(1);
|
---|
| 56 | }
|
---|
| 57 |
|
---|
| 58 | if (argc == 2) m = atoi(argv[1]);
|
---|
| 59 | printf("Test 25 ");
|
---|
| 60 | fflush(stdout);
|
---|
| 61 | System("rm -rf DIR_25; mkdir DIR_25");
|
---|
| 62 | Chdir("DIR_25");
|
---|
| 63 | makelongnames();
|
---|
| 64 | superuser = (geteuid() == 0);
|
---|
| 65 |
|
---|
| 66 | /* Close all files, the parent might have opened. */
|
---|
| 67 | for (i = 3; i < 100; i++) close(i);
|
---|
| 68 |
|
---|
| 69 | for (i = 0; i < ITERATIONS; i++) {
|
---|
| 70 | if (m & 001) test25a();
|
---|
| 71 | if (m & 002) test25b();
|
---|
| 72 | if (m & 004) test25c();
|
---|
| 73 | if (m & 010) test25d();
|
---|
| 74 | if (m & 020) test25e();
|
---|
| 75 | }
|
---|
| 76 | quit();
|
---|
| 77 | }
|
---|
| 78 |
|
---|
| 79 | void test25a()
|
---|
| 80 | { /* Test fcntl flags. */
|
---|
| 81 | subtest = 1;
|
---|
| 82 |
|
---|
| 83 | #define EXCLUDE(a,b) (((a)^(b)) == ((a)|(b)))
|
---|
| 84 | #define ADDIT (O_APPEND | O_CREAT | O_EXCL | O_NONBLOCK | O_TRUNC)
|
---|
| 85 |
|
---|
| 86 | /* If this compiles all flags are defined but they have to be or-able. */
|
---|
| 87 | if (!(EXCLUDE(O_NONBLOCK, O_TRUNC))) e(1);
|
---|
| 88 | if (!(EXCLUDE(O_EXCL, O_NONBLOCK | O_TRUNC))) e(2);
|
---|
| 89 | if (!(EXCLUDE(O_CREAT, O_EXCL | O_NONBLOCK | O_TRUNC))) e(3);
|
---|
| 90 | if (!(EXCLUDE(O_APPEND, O_CREAT | O_EXCL | O_NONBLOCK | O_TRUNC))) e(4);
|
---|
| 91 | if (!(EXCLUDE(O_RDONLY, ADDIT))) e(5);
|
---|
| 92 | if (!(EXCLUDE(O_WRONLY, ADDIT))) e(6);
|
---|
| 93 | if (!(EXCLUDE(O_RDWR, ADDIT))) e(7);
|
---|
| 94 | }
|
---|
| 95 |
|
---|
| 96 | void test25b()
|
---|
| 97 | { /* Test normal operation. */
|
---|
| 98 |
|
---|
| 99 | #define BUF_SIZE 1024
|
---|
| 100 |
|
---|
| 101 | int fd1, fd2, fd3, fd4, fd5;
|
---|
| 102 | char buf[BUF_SIZE];
|
---|
| 103 | struct stat st1, st2, st3;
|
---|
| 104 | time_t time1, time2;
|
---|
| 105 | int stat_loc;
|
---|
| 106 |
|
---|
| 107 | subtest = 2;
|
---|
| 108 |
|
---|
| 109 | System("rm -rf ../DIR_25/*");
|
---|
| 110 |
|
---|
| 111 | System("echo Hello > he"); /* make test files */
|
---|
| 112 | System("echo Hello > ha"); /* size 6 bytes */
|
---|
| 113 | System("echo Hello > hi");
|
---|
| 114 | System("echo Hello > ho");
|
---|
| 115 |
|
---|
| 116 | /* Check path resolution. Check if lowest fds are returned */
|
---|
| 117 | if ((fd1 = open("he", O_RDONLY)) != 3) e(1);
|
---|
| 118 | if (read(fd1, buf, BUF_SIZE) != 6) e(2);
|
---|
| 119 | if ((fd2 = open("./ha", O_RDONLY)) != 4) e(3);
|
---|
| 120 | if ((fd3 = open("../DIR_25/he", O_RDWR)) != 5) e(4);
|
---|
| 121 | if ((fd4 = open("ho", O_WRONLY)) != 6) e(5);
|
---|
| 122 | if (close(fd4) != 0) e(6);
|
---|
| 123 | if (close(fd1) != 0) e(7);
|
---|
| 124 | if ((fd1 = open("./././ho", O_RDWR)) != 3) e(8);
|
---|
| 125 | if ((fd4 = open("../DIR_25/he", O_RDONLY)) != 6) e(9);
|
---|
| 126 | if (close(fd2) != 0) e(10);
|
---|
| 127 | if (close(fd3) != 0) e(11);
|
---|
| 128 | if ((fd2 = open("ha", O_RDONLY)) != 4) e(12);
|
---|
| 129 | if ((fd3 = open("/etc/passwd", O_RDONLY)) != 5) e(13);
|
---|
| 130 | if (close(fd4) != 0) e(14); /* close all */
|
---|
| 131 | if (close(fd1) != 0) e(15);
|
---|
| 132 | if (close(fd3) != 0) e(16);
|
---|
| 133 |
|
---|
| 134 | /* Check if processes share fd2, and if they have independent new fds */
|
---|
| 135 | System("rm -rf /tmp/sema.25");
|
---|
| 136 | switch (fork()) {
|
---|
| 137 | case -1: printf("Can't fork\n"); break;
|
---|
| 138 |
|
---|
| 139 | case 0:
|
---|
| 140 | if ((fd1 = open("he", O_WRONLY)) != 3) e(17);
|
---|
| 141 | if ((fd3 = open("../././DIR_25/ha", O_WRONLY)) != 5) e(18);
|
---|
| 142 | if ((fd4 = open("../DIR_25/hi", O_WRONLY)) != 6) e(19);
|
---|
| 143 | if ((fd5 = open("ho", O_WRONLY)) != 7) e(20);
|
---|
| 144 | system("while test ! -f /tmp/sema.25; do sleep 1; done"); /* parent */
|
---|
| 145 | if (read(fd2, buf, BUF_SIZE) != 3) e(21); /* gets Hel */
|
---|
| 146 | if (strncmp(buf, "lo\n", 3) != 0) e(22); /* we get lo */
|
---|
| 147 | if (close(fd1) != 0) e(23);
|
---|
| 148 | if (close(fd2) != 0) e(24);
|
---|
| 149 | if (close(fd3) != 0) e(25);
|
---|
| 150 | if (close(fd4) != 0) e(26);
|
---|
| 151 | if (close(fd5) != 0) e(27);
|
---|
| 152 | exit(0);
|
---|
| 153 |
|
---|
| 154 | default:
|
---|
| 155 | if ((fd1 = open("ha", O_RDONLY)) != 3) e(28);
|
---|
| 156 | if ((fd3 = open("./he", O_RDONLY)) != 5) e(29);
|
---|
| 157 | if ((fd4 = open("../DIR_25/hi", O_RDWR)) != 6) e(30);
|
---|
| 158 | if ((fd5 = open("ho", O_WRONLY)) != 7) e(31);
|
---|
| 159 | if (close(fd1) != 0) e(32);
|
---|
| 160 | if (read(fd2, buf, 3) != 3) e(33); /* get Hel */
|
---|
| 161 | Creat("/tmp/sema.25");
|
---|
| 162 | if (strncmp(buf, "Hel", 3) != 0) e(34);
|
---|
| 163 | if (close(fd2) != 0) e(35);
|
---|
| 164 | if (close(fd3) != 0) e(36);
|
---|
| 165 | if (close(fd4) != 0) e(37);
|
---|
| 166 | if (close(fd5) != 0) e(38);
|
---|
| 167 | if (wait(&stat_loc) == -1) e(39);
|
---|
| 168 | if (stat_loc != 0) e(40);
|
---|
| 169 | }
|
---|
| 170 | System("rm -f /tmp/sema.25");
|
---|
| 171 |
|
---|
| 172 | /* Check if the file status information is updated correctly */
|
---|
| 173 | Stat("hi", &st1); /* get info */
|
---|
| 174 | Stat("ha", &st2); /* of files */
|
---|
| 175 | time(&time1);
|
---|
| 176 | while (time1 >= time((time_t *)0))
|
---|
| 177 | ; /* wait a sec */
|
---|
| 178 | if ((fd1 = open("hi", O_RDONLY)) != 3) e(41); /* open files */
|
---|
| 179 | if ((fd2 = open("ha", O_WRONLY)) != 4) e(42);
|
---|
| 180 | if (read(fd1, buf, 1) != 1) e(43); /* read one */
|
---|
| 181 | if (close(fd1) != 0) e(44); /* close one */
|
---|
| 182 | Stat("hi", &st3); /* get info */
|
---|
| 183 | if (st1.st_uid != st3.st_uid) e(45);
|
---|
| 184 | if (st1.st_gid != st3.st_gid) e(46); /* should be same */
|
---|
| 185 | if (st1.st_mode != st3.st_mode) e(47);
|
---|
| 186 | if (st1.st_size != st3.st_size) e(48);
|
---|
| 187 | if (st1.st_nlink != st3.st_nlink) e(49);
|
---|
| 188 | if (st1.st_mtime != st3.st_mtime) e(50);
|
---|
| 189 | if (st1.st_ctime != st3.st_ctime) e(51);
|
---|
| 190 | #ifndef V1_FILESYSTEM
|
---|
| 191 | if (st1.st_atime >= st3.st_atime) e(52); /* except for atime. */
|
---|
| 192 | #endif
|
---|
| 193 | if (write(fd2, "Howdy\n", 6) != 6) e(53); /* Update c & mtime. */
|
---|
| 194 | if ((fd1 = open("ha", O_RDWR)) != 3) e(54);
|
---|
| 195 | if (read(fd1, buf, 6) != 6) e(55); /* Update atime. */
|
---|
| 196 | if (strncmp(buf, "Howdy\n", 6) != 0) e(56);
|
---|
| 197 | if (close(fd1) != 0) e(57);
|
---|
| 198 | Stat("ha", &st3);
|
---|
| 199 | if (st2.st_uid != st3.st_uid) e(58);
|
---|
| 200 | if (st2.st_gid != st3.st_gid) e(59); /* should be same */
|
---|
| 201 | if (st2.st_mode != st3.st_mode) e(60);
|
---|
| 202 | if (st2.st_nlink != st3.st_nlink) e(61);
|
---|
| 203 | if (st2.st_ctime >= st3.st_ctime) e(62);
|
---|
| 204 | #ifndef V1_FILESYSTEM
|
---|
| 205 | if (st2.st_atime >= st3.st_atime) e(63);
|
---|
| 206 | #endif
|
---|
| 207 | if (st2.st_mtime >= st3.st_mtime) e(64);
|
---|
| 208 | if (st2.st_size != st3.st_size) e(65);
|
---|
| 209 | if (close(fd2) != 0) e(66);
|
---|
| 210 |
|
---|
| 211 | /* Let's see if RDONLY files are read only. */
|
---|
| 212 | if ((fd1 = open("hi", O_RDONLY)) != 3) e(67);
|
---|
| 213 | if (write(fd1, " again", 7) != -1) e(68); /* we can't write */
|
---|
| 214 | if (errno != EBADF) e(69); /* a read only fd */
|
---|
| 215 | if (read(fd1, buf, 7) != 6) e(70); /* but we can read */
|
---|
| 216 | if (close(fd1) != 0) e(71);
|
---|
| 217 |
|
---|
| 218 | /* Let's see if WRONLY files are write only. */
|
---|
| 219 | if ((fd1 = open("hi", O_WRONLY)) != 3) e(72);
|
---|
| 220 | if (read(fd1, buf, 7) != -1) e(73); /* we can't read */
|
---|
| 221 | if (errno != EBADF) e(74); /* a write only fd */
|
---|
| 222 | if (write(fd1, "hELLO", 6) != 6) e(75); /* but we can write */
|
---|
| 223 | if (close(fd1) != 0) e(76);
|
---|
| 224 |
|
---|
| 225 | /* Let's see if files are closable only once. */
|
---|
| 226 | if (close(fd1) != -1) e(77);
|
---|
| 227 | if (errno != EBADF) e(78);
|
---|
| 228 |
|
---|
| 229 | /* Let's see how calling close() with bad fds is handled. */
|
---|
| 230 | if (close(10) != -1) e(79);
|
---|
| 231 | if (errno != EBADF) e(80);
|
---|
| 232 | if (close(111) != -1) e(81);
|
---|
| 233 | if (errno != EBADF) e(82);
|
---|
| 234 | if (close(-432) != -1) e(83);
|
---|
| 235 | if (errno != EBADF) e(84);
|
---|
| 236 |
|
---|
| 237 | /* Let's see if RDWR files are read & write able. */
|
---|
| 238 | if ((fd1 = open("hi", O_RDWR)) != 3) e(85);
|
---|
| 239 | if (read(fd1, buf, 6) != 6) e(86); /* we can read */
|
---|
| 240 | if (strncmp(buf, "hELLO", 6) != 0) e(87); /* and we can write */
|
---|
| 241 | if (write(fd1, "Hello", 6) != 6) e(88); /* a read write fd */
|
---|
| 242 | if (close(fd1) != 0) e(89);
|
---|
| 243 |
|
---|
| 244 | /* Check if APPENDed files are realy appended */
|
---|
| 245 | if ((fd1 = open("hi", O_RDWR | O_APPEND)) != 3) e(90); /* open hi */
|
---|
| 246 |
|
---|
| 247 | /* An open should set the file offset to 0. */
|
---|
| 248 | if (lseek(fd1, (off_t) 0, SEEK_CUR) != 0) e(91);
|
---|
| 249 |
|
---|
| 250 | /* Writing 0 bytes should not have an effect. */
|
---|
| 251 | if (write(fd1, "", 0) != 0) e(92);
|
---|
| 252 | if (lseek(fd1, (off_t) 0, SEEK_CUR) != 0) e(93); /* the end? */
|
---|
| 253 |
|
---|
| 254 | /* A seek befor a wirte should not matter with O_APPEND. */
|
---|
| 255 | Stat("hi", &st1);
|
---|
| 256 | if (lseek(fd1, (off_t) - 3, SEEK_END) != st1.st_size - 3) e(94);
|
---|
| 257 |
|
---|
| 258 | /* By writing 1 byte, we force the offset to the end of the file */
|
---|
| 259 | if (write(fd1, "1", 1) != 1) e(95);
|
---|
| 260 | Stat("hi", &st1);
|
---|
| 261 | if (lseek(fd1, (off_t) 0, SEEK_CUR) != st1.st_size) e(96);
|
---|
| 262 | if (write(fd1, "2", 1) != 1) e(97);
|
---|
| 263 | Stat("hi", &st1);
|
---|
| 264 | if (lseek(fd1, (off_t) 0, SEEK_CUR) != st1.st_size) e(98);
|
---|
| 265 | if (write(fd1, "3", 1) != 1) e(99);
|
---|
| 266 | Stat("hi", &st1);
|
---|
| 267 | if (lseek(fd1, (off_t) 0, SEEK_CUR) != st1.st_size) e(100);
|
---|
| 268 | if (lseek(fd1, (off_t) - 2, SEEK_CUR) <= 0) e(101);
|
---|
| 269 | if (write(fd1, "4", 1) != 1) e(102);
|
---|
| 270 |
|
---|
| 271 | /* Since the mode was O_APPEND, the offset should be reset to EOF */
|
---|
| 272 | Stat("hi", &st1);
|
---|
| 273 | if (lseek(fd1, (off_t) 0, SEEK_CUR) != st1.st_size) e(103);
|
---|
| 274 | if (lseek(fd1, (off_t) - 4, SEEK_CUR) != st1.st_size - 4) e(104);
|
---|
| 275 | if (read(fd1, buf, BUF_SIZE) != 4) e(105);
|
---|
| 276 | if (strncmp(buf, "1234", 4) != 0) e(106);
|
---|
| 277 | if (close(fd1) != 0) e(107);
|
---|
| 278 |
|
---|
| 279 | /* Check the effect of O_CREAT */
|
---|
| 280 | Stat("ho", &st1);
|
---|
| 281 | fd1 = open("ho", O_RDWR | O_CREAT, 0000);
|
---|
| 282 | if (fd1 != 3) e(108);
|
---|
| 283 | Stat("ho", &st2);
|
---|
| 284 | if (memcmp(&st1, &st2, sizeof(struct stat)) != 0) e(109);
|
---|
| 285 | if (read(fd1, buf, 6) != 6) e(110);
|
---|
| 286 | if (strncmp(buf, "Hello\n", 6) != 0) e(111);
|
---|
| 287 | if (write(fd1, "@", 1) != 1) e(112);
|
---|
| 288 | if (close(fd1) != 0) e(113);
|
---|
| 289 | (void) umask(0000);
|
---|
| 290 | fd1 = open("ho", O_RDWR | O_CREAT | O_EXCL, 0777);
|
---|
| 291 | if (fd1 != -1) e(114); /* ho exists */
|
---|
| 292 | System("rm -rf new");
|
---|
| 293 | time(&time1);
|
---|
| 294 | while (time1 >= time((time_t *)0))
|
---|
| 295 | ;
|
---|
| 296 | fd1 = open("new", O_RDWR | O_CREAT, 0716);
|
---|
| 297 | if (fd1 != 3) e(115); /* new file */
|
---|
| 298 | Stat("new", &st1);
|
---|
| 299 | time(&time2);
|
---|
| 300 | while (time2 >= time((time_t *)0))
|
---|
| 301 | ;
|
---|
| 302 | time(&time2);
|
---|
| 303 | if (st1.st_uid != geteuid()) e(116); /* try this as superuser. */
|
---|
| 304 | if (st1.st_gid != getegid()) e(117);
|
---|
| 305 | if ((st1.st_mode & 0777) != 0716) e(118);
|
---|
| 306 | if (st1.st_nlink != 1) e(119);
|
---|
| 307 | if (st1.st_mtime <= time1) e(120);
|
---|
| 308 | if (st1.st_mtime >= time2) e(121);
|
---|
| 309 | #ifndef V1_FILESYSTEM
|
---|
| 310 | if (st1.st_atime != st1.st_mtime) e(122);
|
---|
| 311 | #endif
|
---|
| 312 | if (st1.st_ctime != st1.st_mtime) e(123);
|
---|
| 313 | if (st1.st_size != 0) e(124);
|
---|
| 314 | if (write(fd1, "I'm new in town", 16) != 16) e(125);
|
---|
| 315 | if (lseek(fd1, (off_t) - 5, SEEK_CUR) != 11) e(126);
|
---|
| 316 | if (read(fd1, buf, 5) != 5) e(127);
|
---|
| 317 | if (strncmp(buf, "town", 5) != 0) e(128);
|
---|
| 318 | if (close(fd1) != 0) e(129);
|
---|
| 319 |
|
---|
| 320 | /* Let's test the O_TRUNC flag on this new file. */
|
---|
| 321 | time(&time1);
|
---|
| 322 | while (time1 >= time((time_t *)0));
|
---|
| 323 | if ((fd1 = open("new", O_RDWR | O_TRUNC)) != 3) e(130);
|
---|
| 324 | Stat("new", &st1);
|
---|
| 325 | time(&time2);
|
---|
| 326 | while (time2 >= time((time_t *)0));
|
---|
| 327 | time(&time2);
|
---|
| 328 | if ((st1.st_mode & 0777) != 0716) e(131);
|
---|
| 329 | if (st1.st_size != (size_t) 0) e(132); /* TRUNCed ? */
|
---|
| 330 | if (st1.st_mtime <= time1) e(133);
|
---|
| 331 | if (st1.st_mtime >= time2) e(134);
|
---|
| 332 | if (st1.st_ctime != st1.st_mtime) e(135);
|
---|
| 333 | if (close(fd1) != 0) e(136);
|
---|
| 334 |
|
---|
| 335 | /* Test if file permission bits and the file ownership are unchanged. */
|
---|
| 336 | /* So we will see if `O_CREAT' has no effect if the file exists. */
|
---|
| 337 | if (superuser) {
|
---|
| 338 | System("echo > bar; chmod 077 bar"); /* Make bar 077 */
|
---|
| 339 | System("chown daemon bar");
|
---|
| 340 | System("chgrp daemon bar"); /* Daemon's bar */
|
---|
| 341 | fd1 = open("bar", O_RDWR | O_CREAT | O_TRUNC, 0777); /* knock knock */
|
---|
| 342 | if (fd1 == -1) e(137);
|
---|
| 343 | if (write(fd1, "foo", 3) != 3) e(138); /* rewrite bar */
|
---|
| 344 | if (close(fd1) != 0) e(139);
|
---|
| 345 | Stat("bar", &st1);
|
---|
| 346 | if (st1.st_uid != 1) e(140); /* bar is still */
|
---|
| 347 | if (st1.st_gid != 1) e(141); /* owned by daemon */
|
---|
| 348 | if ((st1.st_mode & 0777) != 077) e(142); /* mode still is 077 */
|
---|
| 349 | if (st1.st_size != (size_t) 3) e(143); /* 3 bytes long */
|
---|
| 350 |
|
---|
| 351 | /* We do the whole thing again, but with O_WRONLY */
|
---|
| 352 | fd1 = open("bar", O_WRONLY | O_CREAT | O_TRUNC, 0777);
|
---|
| 353 | if (fd1 == -1) e(144);
|
---|
| 354 | if (write(fd1, "foobar", 6) != 6) e(145); /* rewrite bar */
|
---|
| 355 | if (close(fd1) != 0) e(146);
|
---|
| 356 | Stat("bar", &st1);
|
---|
| 357 | if (st1.st_uid != 1) e(147); /* bar is still */
|
---|
| 358 | if (st1.st_gid != 1) e(148); /* owned by daemon */
|
---|
| 359 | if ((st1.st_mode & 0777) != 077) e(149); /* mode still is 077 */
|
---|
| 360 | if (st1.st_size != (size_t) 6) e(150); /* 6 bytes long */
|
---|
| 361 | }
|
---|
| 362 | }
|
---|
| 363 |
|
---|
| 364 | void test25c()
|
---|
| 365 | { /* Test normal operation Part two. */
|
---|
| 366 | int fd1, fd2;
|
---|
| 367 | char buf[BUF_SIZE];
|
---|
| 368 | struct stat st;
|
---|
| 369 | int stat_loc;
|
---|
| 370 | static int iteration=0;
|
---|
| 371 |
|
---|
| 372 | subtest = 3;
|
---|
| 373 | iteration++;
|
---|
| 374 |
|
---|
| 375 | System("rm -rf ../DIR_25/*");
|
---|
| 376 |
|
---|
| 377 | /* Fifo file test here. */
|
---|
| 378 | if (mkfifo("fifo", 0777) != 0) e(1);
|
---|
| 379 | switch (fork()) {
|
---|
| 380 | case -1: printf("Can't fork\n"); break;
|
---|
| 381 | case 0:
|
---|
| 382 | alarm(20); /* Give child 20 seconds to live. */
|
---|
| 383 | if ((fd1 = open("fifo", O_RDONLY)) != 3) e(2);
|
---|
| 384 | if (read(fd1, buf, BUF_SIZE) != 23) e(3);
|
---|
| 385 | if (strncmp(buf, "1 2 3 testing testing\n", 23) != 0) e(4);
|
---|
| 386 | if (close(fd1) != 0) e(5);
|
---|
| 387 | exit(0);
|
---|
| 388 | default:
|
---|
| 389 | if ((fd1 = open("fifo", O_WRONLY)) != 3) e(6);
|
---|
| 390 | if (write(fd1, "1 2 3 testing testing\n", 23) != 23) e(7);
|
---|
| 391 | if (close(fd1) != 0) e(8);
|
---|
| 392 | if (wait(&stat_loc) == -1) e(9);
|
---|
| 393 | if (stat_loc != 0) e(10); /* The alarm went off? */
|
---|
| 394 | }
|
---|
| 395 |
|
---|
| 396 | /* Try opening for writing with O_NONBLOCK. */
|
---|
| 397 | fd1 = open("fifo", O_WRONLY | O_NONBLOCK);
|
---|
| 398 | if (fd1 != -1) e(11);
|
---|
| 399 | if (errno != ENXIO) e(12);
|
---|
| 400 | close(fd1);
|
---|
| 401 |
|
---|
| 402 | /* Try opening for writing with O_NONBLOCK and O_CREAT. */
|
---|
| 403 | fd1 = open("fifo", O_WRONLY | O_CREAT | O_NONBLOCK, 0777);
|
---|
| 404 | if (fd1 != -1) e(13);
|
---|
| 405 | if (errno != ENXIO) e(14);
|
---|
| 406 | close(fd1);
|
---|
| 407 |
|
---|
| 408 | /* Both the NONBLOCK and the EXCLusive give raise to error. */
|
---|
| 409 | fd1 = open("fifo", O_WRONLY | O_CREAT | O_EXCL | O_NONBLOCK, 0777);
|
---|
| 410 | if (fd1 != -1) e(15);
|
---|
| 411 | if (errno != EEXIST && errno != ENXIO) e(16);
|
---|
| 412 | close(fd1); /* Just in case. */
|
---|
| 413 |
|
---|
| 414 | /* Try opening for reading with O_NONBLOCK. */
|
---|
| 415 | fd1 = open("fifo", O_RDONLY | O_NONBLOCK);
|
---|
| 416 | if (fd1 != 3) e(17);
|
---|
| 417 | if (close(fd1) != 0) e(18);
|
---|
| 418 |
|
---|
| 419 | /* Nopt runs out of memory. ;-< We just cut out some valid code */
|
---|
| 420 | /* FIFO's should always append. (They have no file position.) */
|
---|
| 421 | switch (fork()) {
|
---|
| 422 | case -1: printf("Can't fork\n"); break;
|
---|
| 423 | case 0:
|
---|
| 424 | alarm(20); /* Give child 20 seconds to live. */
|
---|
| 425 | if ((fd1 = open("fifo", O_WRONLY)) != 3) e(19);
|
---|
| 426 | if ((fd2 = open("fifo", O_WRONLY)) != 4) e(20);
|
---|
| 427 | if (write(fd1, "I did see Elvis.\n", 18) != 18) e(21);
|
---|
| 428 | if (write(fd2, "I DID.\n", 8) != 8) e(22);
|
---|
| 429 | if (close(fd2) != 0) e(23);
|
---|
| 430 | if (close(fd1) != 0) e(24);
|
---|
| 431 | exit(0);
|
---|
| 432 | default:
|
---|
| 433 | if ((fd1 = open("fifo", O_RDONLY)) != 3) e(25);
|
---|
| 434 | if (read(fd1, buf, 18) != 18) e(26);
|
---|
| 435 | if (strncmp(buf, "I did see Elvis.\n", 18) != 0) e(27);
|
---|
| 436 | if (read(fd1, buf, BUF_SIZE) != 8) e(28);
|
---|
| 437 | if (strncmp(buf, "I DID.\n", 8) != 0) e(29);
|
---|
| 438 | if (close(fd1) != 0) e(30);
|
---|
| 439 | if (wait(&stat_loc) == -1) e(31);
|
---|
| 440 | if (stat_loc != 0) e(32); /* The alarm went off? */
|
---|
| 441 | }
|
---|
| 442 |
|
---|
| 443 | /* O_TRUNC should have no effect on FIFO files. */
|
---|
| 444 | switch (fork()) {
|
---|
| 445 | case -1: printf("Can't fork\n"); break;
|
---|
| 446 | case 0:
|
---|
| 447 | alarm(20); /* Give child 20 seconds to live. */
|
---|
| 448 | if ((fd1 = open("fifo", O_WRONLY)) != 3) e(33);
|
---|
| 449 | if (write(fd1, "I did see Elvis.\n", 18) != 18) e(34);
|
---|
| 450 | if ((fd2 = open("fifo", O_WRONLY | O_TRUNC)) != 4) e(35);
|
---|
| 451 | if (write(fd2, "I DID.\n", 8) != 8) e(36);
|
---|
| 452 | if (close(fd2) != 0) e(37);
|
---|
| 453 | if (close(fd1) != 0) e(38);
|
---|
| 454 | exit(0);
|
---|
| 455 | default:
|
---|
| 456 | if ((fd1 = open("fifo", O_RDONLY)) != 3) e(39);
|
---|
| 457 | if (read(fd1, buf, 18) != 18) e(40);
|
---|
| 458 | if (strncmp(buf, "I did see Elvis.\n", 18) != 0) e(41);
|
---|
| 459 | if (read(fd1, buf, BUF_SIZE) != 8) e(42);
|
---|
| 460 | if (strncmp(buf, "I DID.\n", 8) != 0) e(43);
|
---|
| 461 | if (close(fd1) != 0) e(44);
|
---|
| 462 | if (wait(&stat_loc) == -1) e(45);
|
---|
| 463 | if (stat_loc != 0) e(46); /* The alarm went off? */
|
---|
| 464 | }
|
---|
| 465 |
|
---|
| 466 | /* Closing the last fd should flush all data to the bitbucket. */
|
---|
| 467 | System("rm -rf /tmp/sema.25");
|
---|
| 468 | switch (fork()) {
|
---|
| 469 | case -1: printf("Can't fork\n"); break;
|
---|
| 470 |
|
---|
| 471 | case 0:
|
---|
| 472 | alarm(20); /* Give child 20 seconds to live. */
|
---|
| 473 | if ((fd1 = open("fifo", O_WRONLY)) != 3) e(47);
|
---|
| 474 | if (write(fd1, "I did see Elvis.\n", 18) != 18) e(48);
|
---|
| 475 | Creat("/tmp/sema.25");
|
---|
| 476 | sleep(2); /* give parent a chance to open */
|
---|
| 477 | /* this was sleep(1), but that's too short: child also sleeps(1) */
|
---|
| 478 | if (close(fd1) != 0) e(49);
|
---|
| 479 | exit(0);
|
---|
| 480 |
|
---|
| 481 | default:
|
---|
| 482 | if ((fd1 = open("fifo", O_RDONLY)) != 3) e(50);
|
---|
| 483 | /* Make `sure' write has closed. */
|
---|
| 484 | while (stat("/tmp/sema.25", &st) != 0) sleep(1);
|
---|
| 485 | if (close(fd1) != 0) e(51);
|
---|
| 486 | if ((fd1 = open("fifo", O_RDONLY | O_NONBLOCK)) != 3) e(52);
|
---|
| 487 | if (read(fd1, buf, BUF_SIZE) != 18) e(53);
|
---|
| 488 | if (close(fd1) != 0) e(54);
|
---|
| 489 | if (wait(&stat_loc) == -1) e(55);
|
---|
| 490 | if (stat_loc != 0) e(56); /* The alarm went off? */
|
---|
| 491 | }
|
---|
| 492 |
|
---|
| 493 | /* Let's try one too many. */
|
---|
| 494 | System("rm -rf /tmp/sema.25");
|
---|
| 495 | switch (fork()) {
|
---|
| 496 | case -1: printf("Can't fork\n"); break;
|
---|
| 497 | case 0:
|
---|
| 498 | alarm(20); /* Give child 20 seconds to live. */
|
---|
| 499 | if ((fd1 = open("fifo", O_WRONLY)) != 3) e(57);
|
---|
| 500 | if (write(fd1, "I did see Elvis.\n", 18) != 18) e(58);
|
---|
| 501 |
|
---|
| 502 | /* Keep open till second reader is opened. */
|
---|
| 503 | while (stat("/tmp/sema.25", &st) != 0) sleep(1);
|
---|
| 504 | if (close(fd1) != 0) e(59);
|
---|
| 505 | exit(0);
|
---|
| 506 | default:
|
---|
| 507 | if ((fd1 = open("fifo", O_RDONLY)) != 3) e(60);
|
---|
| 508 | if (read(fd1, buf, 2) != 2) e(61);
|
---|
| 509 | if (strncmp(buf, "I ", 2) != 0) e(62);
|
---|
| 510 | if (close(fd1) != 0) e(63);
|
---|
| 511 | if ((fd1 = open("fifo", O_RDONLY)) != 3) e(64);
|
---|
| 512 |
|
---|
| 513 | /* Signal second reader is open. */
|
---|
| 514 | Creat("/tmp/sema.25");
|
---|
| 515 | if (read(fd1, buf, 4) != 4) e(65);
|
---|
| 516 | if (strncmp(buf, "did ", 4) != 0) e(66);
|
---|
| 517 | if ((fd2 = open("fifo", O_RDONLY)) != 4) e(67);
|
---|
| 518 | if (read(fd2, buf, BUF_SIZE) != 12) e(68);
|
---|
| 519 | if (strncmp(buf, "see Elvis.\n", 12) != 0) e(69);
|
---|
| 520 | if (close(fd2) != 0) e(70);
|
---|
| 521 | if (close(fd1) != 0) e(71);
|
---|
| 522 | if (wait(&stat_loc) == -1) e(72);
|
---|
| 523 | if (stat_loc != 0) e(73); /* The alarm went off? */
|
---|
| 524 | }
|
---|
| 525 | System("rm -rf fifo /tmp/sema.25");
|
---|
| 526 |
|
---|
| 527 | /* O_TRUNC should have no effect on directroys. */
|
---|
| 528 | System("mkdir dir; touch dir/f1 dir/f2 dir/f3");
|
---|
| 529 | if ((fd1 = open("dir", O_WRONLY | O_TRUNC)) != -1) e(74);
|
---|
| 530 | if (errno != EISDIR) e(75);
|
---|
| 531 | close(fd1);
|
---|
| 532 |
|
---|
| 533 | /* Opening a directory for reading should be possible. */
|
---|
| 534 | if ((fd1 = open("dir", O_RDONLY)) != 3) e(76);
|
---|
| 535 | if (close(fd1) != 0) e(77);
|
---|
| 536 | if (unlink("dir/f1") != 0) e(78); /* Should still be there. */
|
---|
| 537 | if (unlink("dir/f2") != 0) e(79);
|
---|
| 538 | if (unlink("dir/f3") != 0) e(80);
|
---|
| 539 | if (rmdir("dir") != 0) e(81);
|
---|
| 540 |
|
---|
| 541 | if (!superuser) {
|
---|
| 542 | /* Test if O_CREAT is not usable to open files with the wrong mode */
|
---|
| 543 | (void) umask(0200); /* nono has no */
|
---|
| 544 | System("touch nono"); /* write bit */
|
---|
| 545 | (void) umask(0000);
|
---|
| 546 | fd1 = open("nono", O_RDWR | O_CREAT, 0777); /* try to open */
|
---|
| 547 | if (fd1 != -1) e(82);
|
---|
| 548 | if (errno != EACCES) e(83); /* but no access */
|
---|
| 549 | }
|
---|
| 550 | }
|
---|
| 551 |
|
---|
| 552 | void test25d()
|
---|
| 553 | {
|
---|
| 554 | int fd;
|
---|
| 555 |
|
---|
| 556 | subtest = 4;
|
---|
| 557 |
|
---|
| 558 | System("rm -rf ../DIR_25/*");
|
---|
| 559 |
|
---|
| 560 | /* Test maximal file name length. */
|
---|
| 561 | if ((fd = open(MaxName, O_RDWR | O_CREAT, 0777)) != 3) e(1);
|
---|
| 562 | if (close(fd) != 0) e(2);
|
---|
| 563 | MaxPath[strlen(MaxPath) - 2] = '/';
|
---|
| 564 | MaxPath[strlen(MaxPath) - 1] = 'a'; /* make ././.../a */
|
---|
| 565 | if ((fd = open(MaxPath, O_RDWR | O_CREAT, 0777)) != 3) e(3);
|
---|
| 566 | if (close(fd) != 0) e(4);
|
---|
| 567 | MaxPath[strlen(MaxPath) - 1] = '/'; /* make ././.../a */
|
---|
| 568 | }
|
---|
| 569 |
|
---|
| 570 | void test25e()
|
---|
| 571 | {
|
---|
| 572 | int fd;
|
---|
| 573 | char *noread = "noread"; /* Name for unreadable file. */
|
---|
| 574 | char *nowrite = "nowrite"; /* Same for unwritable. */
|
---|
| 575 | int stat_loc;
|
---|
| 576 |
|
---|
| 577 | subtest = 5;
|
---|
| 578 |
|
---|
| 579 | System("rm -rf ../DIR_25/*");
|
---|
| 580 |
|
---|
| 581 | mkdir("bar", 0777); /* make bar */
|
---|
| 582 |
|
---|
| 583 | /* Check if no access on part of path generates the correct error. */
|
---|
| 584 | System("chmod 677 bar"); /* rw-rwxrwx */
|
---|
| 585 | if (open("bar/nono", O_RDWR | O_CREAT, 0666) != -1) e(1);
|
---|
| 586 | if (errno != EACCES) e(2);
|
---|
| 587 |
|
---|
| 588 | /* Ditto for no write permission. */
|
---|
| 589 | System("chmod 577 bar"); /* r-xrwxrwx */
|
---|
| 590 | if (open("bar/nono", O_RDWR | O_CREAT, 0666) != -1) e(3);
|
---|
| 591 | if (errno != EACCES) e(4);
|
---|
| 592 |
|
---|
| 593 | /* Clean up bar. */
|
---|
| 594 | System("rm -rf bar");
|
---|
| 595 |
|
---|
| 596 | /* Improper flags set on existing file. */
|
---|
| 597 | System("touch noread; chmod 377 noread"); /* noread */
|
---|
| 598 | if (open(noread, O_RDONLY) != -1) e(5);
|
---|
| 599 | if (open(noread, O_RDWR) != -1) e(6);
|
---|
| 600 | if (open(noread, O_RDWR | O_CREAT, 0777) != -1) e(7);
|
---|
| 601 | if (open(noread, O_RDWR | O_CREAT | O_TRUNC, 0777) != -1) e(8);
|
---|
| 602 | if ((fd = open(noread, O_WRONLY)) != 3) e(9);
|
---|
| 603 | if (close(fd) != 0) e(10);
|
---|
| 604 | System("touch nowrite; chmod 577 nowrite"); /* nowrite */
|
---|
| 605 | if (open(nowrite, O_WRONLY) != -1) e(11);
|
---|
| 606 | if (open(nowrite, O_RDWR) != -1) e(12);
|
---|
| 607 | if (open(nowrite, O_RDWR | O_CREAT, 0777) != -1) e(13);
|
---|
| 608 | if (open(nowrite, O_RDWR | O_CREAT | O_TRUNC, 0777) != -1) e(14);
|
---|
| 609 | if ((fd = open(nowrite, O_RDONLY)) != 3) e(15);
|
---|
| 610 | if (close(fd) != 0) e(16);
|
---|
| 611 | if (superuser) {
|
---|
| 612 | /* If we can make a file ownd by some one else, test access again. */
|
---|
| 613 | System("chmod 733 noread");
|
---|
| 614 | System("chown bin noread");
|
---|
| 615 | System("chgrp system noread");
|
---|
| 616 | System("chmod 755 nowrite");
|
---|
| 617 | System("chown bin nowrite");
|
---|
| 618 | System("chgrp system nowrite");
|
---|
| 619 | switch (fork()) {
|
---|
| 620 | case -1: printf("Can't fork\n"); break;
|
---|
| 621 | case 0:
|
---|
| 622 | setuid(1);
|
---|
| 623 | setgid(1); /* become daemon */
|
---|
| 624 | if (open(noread, O_RDONLY) != -1) e(17);
|
---|
| 625 | if (open(noread, O_RDWR) != -1) e(18);
|
---|
| 626 | if (open(noread, O_RDWR | O_CREAT, 0777) != -1) e(19);
|
---|
| 627 | fd = open(noread, O_RDWR | O_CREAT | O_TRUNC, 0777);
|
---|
| 628 | if (fd != -1) e(20);
|
---|
| 629 | if ((fd = open(noread, O_WRONLY)) != 3) e(21);
|
---|
| 630 | if (close(fd) != 0) e(22);
|
---|
| 631 | if (open(nowrite, O_WRONLY) != -1) e(23);
|
---|
| 632 | if (open(nowrite, O_RDWR) != -1) e(24);
|
---|
| 633 | if (open(nowrite, O_RDWR | O_CREAT, 0777) != -1) e(25);
|
---|
| 634 | fd = open(nowrite, O_RDWR | O_CREAT | O_TRUNC, 0777);
|
---|
| 635 | if (fd != -1) e(26);
|
---|
| 636 | if ((fd = open(nowrite, O_RDONLY)) != 3) e(27);
|
---|
| 637 | if (close(fd) != 0) e(28);
|
---|
| 638 | exit(0);
|
---|
| 639 | default:
|
---|
| 640 | if (wait(&stat_loc) == -1) e(29);
|
---|
| 641 | }
|
---|
| 642 | }
|
---|
| 643 |
|
---|
| 644 | /* Clean up the noread and nowrite files. */
|
---|
| 645 | System("rm -rf noread nowrite");
|
---|
| 646 |
|
---|
| 647 | /* Test the O_EXCL flag. */
|
---|
| 648 | System("echo > exists");
|
---|
| 649 | if (open("exists", O_RDWR | O_CREAT | O_EXCL, 0777) != -1) e(30);
|
---|
| 650 | if (errno != EEXIST) e(31);
|
---|
| 651 | if (open("exists", O_RDONLY | O_CREAT | O_EXCL, 0777) != -1) e(32);
|
---|
| 652 | if (errno != EEXIST) e(33);
|
---|
| 653 | if (open("exists", O_WRONLY | O_CREAT | O_EXCL, 0777) != -1) e(34);
|
---|
| 654 | if (errno != EEXIST) e(35);
|
---|
| 655 | fd = open("exists", O_RDWR | O_CREAT | O_EXCL | O_TRUNC, 0777);
|
---|
| 656 | if (fd != -1) e(36);
|
---|
| 657 | if (errno != EEXIST) e(37);
|
---|
| 658 | fd = open("exists", O_RDONLY | O_CREAT | O_EXCL | O_TRUNC, 0777);
|
---|
| 659 | if (fd != -1) e(38);
|
---|
| 660 | if (errno != EEXIST) e(39);
|
---|
| 661 | fd = open("exists", O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, 0777);
|
---|
| 662 | if (fd != -1) e(40);
|
---|
| 663 | if (errno != EEXIST) e(41);
|
---|
| 664 |
|
---|
| 665 | /* Test ToLongName and ToLongPath */
|
---|
| 666 | if ((fd = open(ToLongName, O_RDWR | O_CREAT, 0777)) != 3) e(45);
|
---|
| 667 | if (close(fd) != 0) e(46);
|
---|
| 668 | ToLongPath[PATH_MAX - 2] = '/';
|
---|
| 669 | ToLongPath[PATH_MAX - 1] = 'a';
|
---|
| 670 | if ((fd = open(ToLongPath, O_RDWR | O_CREAT, 0777)) != -1) e(47);
|
---|
| 671 | if (errno != ENAMETOOLONG) e(48);
|
---|
| 672 | if (close(fd) != -1) e(49);
|
---|
| 673 | ToLongPath[PATH_MAX - 1] = '/';
|
---|
| 674 | }
|
---|
| 675 |
|
---|
| 676 | void makelongnames()
|
---|
| 677 | {
|
---|
| 678 | register int i;
|
---|
| 679 |
|
---|
| 680 | memset(MaxName, 'a', NAME_MAX);
|
---|
| 681 | MaxName[NAME_MAX] = '\0';
|
---|
| 682 | for (i = 0; i < PATH_MAX - 1; i++) { /* idem path */
|
---|
| 683 | MaxPath[i++] = '.';
|
---|
| 684 | MaxPath[i] = '/';
|
---|
| 685 | }
|
---|
| 686 | MaxPath[PATH_MAX - 1] = '\0';
|
---|
| 687 |
|
---|
| 688 | strcpy(ToLongName, MaxName); /* copy them Max to ToLong */
|
---|
| 689 | strcpy(ToLongPath, MaxPath);
|
---|
| 690 |
|
---|
| 691 | ToLongName[NAME_MAX] = 'a';
|
---|
| 692 | ToLongName[NAME_MAX + 1] = '\0'; /* extend ToLongName by one too many */
|
---|
| 693 | ToLongPath[PATH_MAX - 1] = '/';
|
---|
| 694 | ToLongPath[PATH_MAX] = '\0'; /* inc ToLongPath by one */
|
---|
| 695 | }
|
---|
| 696 |
|
---|
| 697 | void e(n)
|
---|
| 698 | int n;
|
---|
| 699 | {
|
---|
| 700 | int err_num = errno; /* Save in case printf clobbers it. */
|
---|
| 701 |
|
---|
| 702 | printf("Subtest %d, error %d errno=%d: ", subtest, n, errno);
|
---|
| 703 | errno = err_num;
|
---|
| 704 | perror("");
|
---|
| 705 | if (errct++ > MAX_ERROR) {
|
---|
| 706 | printf("Too many errors; test aborted\n");
|
---|
| 707 | chdir("..");
|
---|
| 708 | system("rm -rf DIR*");
|
---|
| 709 | exit(1);
|
---|
| 710 | }
|
---|
| 711 | errno = 0;
|
---|
| 712 | }
|
---|
| 713 |
|
---|
| 714 | void quit()
|
---|
| 715 | {
|
---|
| 716 | Chdir("..");
|
---|
| 717 | System("rm -rf DIR_25");
|
---|
| 718 |
|
---|
| 719 | if (errct == 0) {
|
---|
| 720 | printf("ok\n");
|
---|
| 721 | exit(0);
|
---|
| 722 | } else {
|
---|
| 723 | printf("%d errors\n", errct);
|
---|
| 724 | exit(1);
|
---|
| 725 | }
|
---|
| 726 | }
|
---|