00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #define __EXTENSIONS__
00024 #include "defs.h"
00025
00026 #ifdef WANT_INODE
00027 #include <sys/types.h>
00028 #include <sys/ino.h>
00029
00030 inodes()
00031 {
00032 struct dinode di;
00033 int fd, inumber, nread;
00034
00035 if ((fd = open("/dev/hd0", 0)) == -1)
00036 syserr("open");
00037 if (lseek(fd, 1024L + sizeof(di), 0) == -1)
00038 syserr("lseek");
00039
00040 for (inumber = 2; inumber <= 6; inumber++) {
00041 if ((nread = read(fd, &di, sizeof(di))) != sizeof(di))
00042 switch (nread) {
00043 case 0:
00044 fatal("EOF");
00045 case -1:
00046 syserr("read");
00047 default:
00048 fatal("partial read");
00049 }
00050 printf("i-node %d; owner = %3o; size = %7ld\n", inumber, di.di_uid, di.di_size);
00051 }
00052 }
00053
00054 #endif WANT_INODE
00055
00056
00057 #if 0
00058 #include <sys/dir.h>
00059
00060 directory(path)
00061 char *path;
00062 {
00063 struct directx {
00064 ino_t d_ino;
00065 char d_name[DIRSIZ + 1];
00066 } dlink;
00067 int fd, nread;
00068 char *dname;
00069
00070
00071 if ((fd = open(path, 0)) == -1)
00072 syserr(path);
00073 dlink.d_name[DIRSIZ] = '\0';
00074
00075 while ((nread = read(fd, &dlink, sizeof(struct direct))) == sizeof(struct direct)) {
00076 if (dlink.d_ino == 0)
00077 dname = "--- UNUSED ---";
00078 else
00079 dname = dlink.d_name;
00080 printf("%-14s %4d\n", dname, dlink.d_ino);
00081 }
00082
00083 switch (nread) {
00084 case 0:
00085 return;
00086 case -1:
00087 syserr("read");
00088 default:
00089 fatal("partial read");
00090 }
00091 }
00092
00093 #endif
00094
00095 #ifdef WANT_RAWFILE
00096
00097 #include <sys/mman.h>
00098
00099 #define RAWBUFSIZE (4096*16)
00100 #define NUMBLOCKS 10000
00101
00102 #ifdef LINUX
00103 #define FILE_BLOCK "/dev/hda2"
00104 #define FILE_RAW "/dev/raw/raw2"
00105 #elif SOLARIS
00106 #define FILE_BLOCK "/dev/dsk/c0d0p0"
00107 #define FILE_RAW "/dev/rdsk/c0d0p0"
00108 #else
00109 #error "Not supported"
00110 #endif
00111
00112 void rawfile(void)
00113 {
00114 void *buf = NULL;
00115 int fd, i;
00116 off_t where[NUMBLOCKS];
00117
00118 for (i = 0; i < NUMBLOCKS; i++) {
00119 where[i] = (random() % NUMBLOCKS) * RAWBUFSIZE;
00120
00121 }
00122 printf("RAWBUFSIZE = %d; NUMBLOCKS = %d\n", RAWBUFSIZE, NUMBLOCKS);
00123
00124 #ifdef SOLARIS
00125 ec_null( buf = memalign(RAWBUFSIZE, RAWBUFSIZE) )
00126 #else
00127 ec_nzero( errno = posix_memalign(&buf, RAWBUFSIZE, RAWBUFSIZE) )
00128 #endif
00129 ec_neg1( fd = open(FILE_BLOCK, O_RDONLY) )
00130 timestart();
00131 for (i = 0; i < NUMBLOCKS; i++) {
00132 errno = 0;
00133 if (pread(fd, buf, RAWBUFSIZE, where[i]) != RAWBUFSIZE)
00134 EC_FAIL
00135 }
00136 timestop("reading " FILE_BLOCK);
00137 ec_neg1( close(fd) )
00138 ec_neg1( fd = open(FILE_RAW, O_RDONLY) )
00139 timestart();
00140 for (i = 0; i < NUMBLOCKS; i++) {
00141 errno = 0;
00142 if (pread(fd, buf, RAWBUFSIZE, where[i]) != RAWBUFSIZE)
00143 EC_FAIL
00144 }
00145 timestop("reading " FILE_RAW);
00146 ec_neg1( close(fd) )
00147 ec_neg1( fd = creat("z.tmp", PERM_FILE) )
00148 for (i = 0; i < NUMBLOCKS; i++) {
00149 errno = 0;
00150 if (write(fd, buf, RAWBUFSIZE) != RAWBUFSIZE)
00151 EC_FAIL
00152 }
00153 ec_neg1( close(fd) )
00154 system("ls -l z.tmp");
00155 ec_neg1( fd = open("z.tmp", O_RDONLY) )
00156 timestart();
00157 for (i = 0; i < NUMBLOCKS; i++) {
00158 errno = 0;
00159 if (pread(fd, buf, RAWBUFSIZE, where[i]) != RAWBUFSIZE)
00160 EC_FAIL
00161 }
00162 timestop("reading ordinary file");
00163 ec_neg1( close(fd) )
00164 ec_neg1( fd = open("z.tmp", O_RDONLY | O_RSYNC | O_DSYNC) )
00165 timestart();
00166 for (i = 0; i < NUMBLOCKS; i++) {
00167 errno = 0;
00168 if (pread(fd, buf, RAWBUFSIZE, where[i]) != RAWBUFSIZE)
00169 EC_FAIL
00170 }
00171 timestop("reading ordinary file (O_RSYNC | O_DSYNC)");
00172 ec_neg1( close(fd) )
00173 return;
00174
00175 EC_CLEANUP_BGN
00176 printf("buf addr = 0x%lx\n", (long)buf);
00177 EC_FLUSH("rawfile");
00178 EC_CLEANUP_END
00179 }
00180
00181 #endif
00182
00183 #if 0
00184
00185 int mkdir(path)
00186 char *path;
00187 {
00188 return(mknod(path, S_IFDIR | 0775, 0));
00189 }
00190
00191
00192
00193 int mkdir2(path)
00194 char *path;
00195 {
00196 char cmd[50];
00197
00198 sprintf(cmd, "mkdir %s", path);
00199 if (system(cmd) == 0)
00200 return(0);
00201 else
00202 return(-1);
00203 }
00204
00205
00206
00207 int mkfifo(path)
00208 char *path;
00209 {
00210 return(mknod(path, S_IFIFO | 0666, 0));
00211 }
00212
00213
00214
00215 mv(from, to)
00216 char *from, *to;
00217 {
00218 bool isdir();
00219 extern int errno;
00220
00221 if (!isdir(to))
00222 if(unlink(to) == -1 && errno != ENOENT)
00223 syserr("unlink1");
00224 if (link(from, to) == -1)
00225 syserr("link");
00226 if (unlink(from) == -1)
00227 syserr("unlink2");
00228 }
00229
00230 bool isdir(path)
00231 char *path;
00232 {
00233 bool ans;
00234 int fd;
00235 extern int errno;
00236
00237 ans = (fd = open(path, 1)) == -1 && errno == EISDIR;
00238 if (fd != -1 && close(fd) == -1)
00239 syserr("close");
00240 return(ans);
00241 }
00242
00243
00244
00245 char *parent(path, dir)
00246 char *path, *dir;
00247 {
00248 char *lastslash, *strrchr();
00249
00250 strcpy(dir, path);
00251 lastslash = strrchr(dir, '/');
00252 if (lastslash == NULL)
00253 strcpy(dir, ".");
00254 else if (lastslash == dir)
00255 strcpy(dir, "/");
00256 else
00257 *lastslash = '\0';
00258 return(dir);
00259 }
00260
00261
00262 mv2(from, to)
00263 char *from, *to;
00264 {
00265 bool isdir();
00266 extern int errno;
00267
00268 char dir[50], *parent();
00269
00270 if (access(parent(from, dir), 2) == -1 || access(parent(to, dir), 2) == -1)
00271 syserr(dir);
00272
00273 if (!isdir(to))
00274 if(unlink(to) == -1 && errno != ENOENT)
00275 syserr("unlink1");
00276 if (link(from, to) == -1)
00277 syserr("link");
00278 if (unlink(from) == -1)
00279 syserr("unlink2");
00280 }
00281 #endif
00282 void fcntl_example(void)
00283 {
00284 int fd = -1, flags;
00285
00286 ec_neg1( fd = open("tmpfile", O_WRONLY | O_CREAT | O_TRUNC,
00287 PERM_FILE) )
00288 printf("flags at open are 0%o\n", fcntl(fd, F_GETFL));
00289
00290 ec_neg1( flags = fcntl(fd, F_GETFL) )
00291 ec_neg1( fcntl(fd, F_SETFL, flags | O_APPEND) )
00292
00293 ec_neg1( fcntl(fd, F_SETFL, flags & ~O_APPEND) )
00294
00295 ec_neg1( fcntl(fd, F_SETFL, O_APPEND) )
00296
00297 ec_neg1( flags = fcntl(fd, F_GETFL) )
00298 if ((flags & O_ACCMODE) == O_RDONLY)
00299
00300
00301 if (flags & O_RDONLY)
00302 if ((flags & O_RDONLY) == O_RDONLY)
00303
00304 ;
00305 printf("flags are now 0%o\n", fcntl(fd, F_GETFL));
00306 ec_neg1( close(fd) )
00307 ec_neg1( unlink("tmpfile") )
00308 return;
00309
00310 EC_CLEANUP_BGN
00311 EC_FLUSH("setappend")
00312 EC_CLEANUP_END
00313 }
00314
00315
00316
00317 #if _XOPEN_SOURCE >= 4
00318 #include <sys/statvfs.h>
00319 #define FCN_NAME statvfs
00320 #define STATVFS 1
00321
00322 #elif defined(BSD_DERIVED)
00323 #include <sys/param.h>
00324 #include <sys/mount.h>
00325 #define FCN_NAME statfs
00326
00327 #else
00328 #error "Need statvfs or nonstandard substitute"
00329 #endif
00330
00331 void print_statvfs(const char *path)
00332 {
00333 struct FCN_NAME buf;
00334
00335 if (path == NULL)
00336 path = ".";
00337 ec_neg1( FCN_NAME(path, &buf) )
00338 #ifdef STATVFS
00339 printf("block size = %lu\n", buf.f_bsize);
00340 printf("fundamental block (fblock) size = %lu\n", buf.f_frsize);
00341 #else
00342 printf("block size = %lu\n", buf.f_iosize);
00343 printf("fundamental block size = %lu\n", buf.f_bsize);
00344 #endif
00345 printf("total number of fblocks = %llu\n",
00346 (unsigned long long)buf.f_blocks);
00347 printf("number of free fblocks = %llu\n",
00348 (unsigned long long)buf.f_bfree);
00349 printf("number of avail. fblocks = %llu\n",
00350 (unsigned long long)buf.f_bavail);
00351 printf("total number of i-numbers = %llu\n",
00352 (unsigned long long)buf.f_files);
00353 printf("number of free i-numbers = %llu\n",
00354 (unsigned long long)buf.f_ffree);
00355 #ifdef STATVFS
00356 printf("number of avail. i-numbers = %llu\n",
00357 (unsigned long long)buf.f_favail);
00358 printf("file-system ID = %lu\n", buf.f_fsid);
00359 printf("Read-only = %s\n",
00360 (buf.f_flag & ST_RDONLY) == ST_RDONLY ? "yes" : "no");
00361 printf("No setuid/setgid = %s\n",
00362 (buf.f_flag & ST_NOSUID) == ST_NOSUID ? "yes" : "no");
00363 printf("max length of filename = %lu\n", buf.f_namemax);
00364 #else
00365 printf("Read-only = %s\n",
00366 (buf.f_flags & MNT_RDONLY) == MNT_RDONLY ? "yes" : "no");
00367 printf("No setuid/setgid = %s\n",
00368 (buf.f_flags & MNT_NOSUID) == MNT_NOSUID ? "yes" : "no");
00369 #endif
00370 printf("\nFree space = %.0f%%\n",
00371 (double)buf.f_bfree * 100 / buf.f_blocks);
00372 return;
00373
00374 EC_CLEANUP_BGN
00375 EC_FLUSH("print_statvfs");
00376 EC_CLEANUP_END
00377 }
00378
00379 #undef FCN_NAME
00380 #undef STATVFS
00381
00382 static void file_ctime_test(void)
00383 {
00384 struct stat buf;
00385 int fd;
00386
00387 ec_neg1( fd = open("tmp2", O_RDWR | O_CREAT | O_TRUNC, PERM_FILE) )
00388 ec_neg1( write(fd, &buf, sizeof(buf)) )
00389 ec_neg1( lseek(fd, 0, SEEK_SET) )
00390 ec_neg1( fstat(fd, &buf) )
00391 printf("st_atime = %s", ctime(&buf.st_atime));
00392 printf("st_mtime = %s", ctime(&buf.st_mtime));
00393 printf("st_ctime = %s", ctime(&buf.st_ctime));
00394 sleep(5);
00395 ec_neg1( write(fd, "x", 1) )
00396 ec_neg1( fstat(fd, &buf) )
00397 printf("st_atime = %s", ctime(&buf.st_atime));
00398 printf("st_mtime = %s", ctime(&buf.st_mtime));
00399 printf("st_ctime = %s", ctime(&buf.st_ctime));
00400 ec_neg1( close(fd) )
00401
00402 return;
00403
00404 EC_CLEANUP_BGN
00405 EC_FLUSH("file_ctime_test");
00406 EC_CLEANUP_END
00407 }
00408
00409 static void dump(const unsigned char *buf, ssize_t n)
00410 {
00411 int i, j;
00412
00413 for (i = 0; i < n; i += 16) {
00414 printf("%4d ", i);
00415 for (j = i; j < n && j < i + 16; j++)
00416 printf(" %c", isprint((int)buf[j]) ? buf[j] : ' ');
00417 printf("\n ");
00418 for (j = i; j < n && j < i + 16; j++)
00419 printf(" %.2x", buf[j]);
00420 printf("\n\n");
00421 }
00422 printf("\n");
00423 }
00424
00425 static void dir_read_test(void)
00426 {
00427 int fd;
00428 unsigned char buf[96];
00429 ssize_t nread;
00430
00431 ec_neg1( fd = open(".", O_RDONLY) )
00432 ec_neg1( nread = read(fd, buf, sizeof(buf)) )
00433 dump(buf, nread);
00434 return;
00435
00436 EC_CLEANUP_BGN
00437 EC_FLUSH("dir_read_test");
00438 EC_CLEANUP_END
00439 }
00440
00441 #include <dirent.h>
00442
00443 static void readdir_r_test(void)
00444 {
00445 bool ok = false;
00446 long name_max;
00447 DIR *dir = NULL;
00448 struct dirent *entry = NULL, *result;
00449
00450 errno = 0;
00451
00452 ec_neg1( name_max = pathconf(".", _PC_NAME_MAX) )
00453 ec_null( entry = malloc(offsetof(struct dirent, d_name) +
00454 name_max + 1) )
00455 ec_null( dir = opendir(".") )
00456 while (true) {
00457 ec_rv( readdir_r(dir, entry, &result) )
00458 if (result == NULL)
00459 break;
00460 printf("name: %s; i-number: %ld\n", result->d_name,
00461 (long)result->d_ino);
00462 }
00463 ok = true;
00464 EC_CLEANUP
00465
00466 EC_CLEANUP_BGN
00467 if (dir != NULL)
00468 (void)closedir(dir);
00469 free(entry);
00470 if (!ok)
00471 EC_FLUSH("readdir_r_test");
00472 EC_CLEANUP_END
00473 }
00474
00475 static void readdir_test(void)
00476 {
00477 DIR *dir = NULL;
00478 struct dirent *entry;
00479
00480 ec_null( dir = opendir(".") )
00481 while (errno = 0, (entry = readdir(dir)) != NULL) {
00482 char buf[200];
00483 printf("name: %s; i-number: %ld\n", entry->d_name,
00484 (long)entry->d_ino);
00485 sprintf(buf, "ls -id %s", entry->d_name);
00486 system(buf);
00487 }
00488 ec_nzero( errno )
00489 EC_CLEANUP
00490
00491 EC_CLEANUP_BGN
00492 if (dir != NULL)
00493 (void)closedir(dir);
00494 EC_FLUSH("readdir_test");
00495 EC_CLEANUP_END
00496 }
00497
00498 void rmdir_test(void)
00499 {
00500 ec_neg1( mkdir("somedir", PERM_DIRECTORY) )
00501 ec_neg1( rmdir("somedir") )
00502 ec_neg1( mkdir("somedir", PERM_DIRECTORY) )
00503 ec_neg1( close(open("somedir/x", O_WRONLY | O_CREAT, PERM_FILE)) )
00504 ec_neg1( system("ls -ld somedir; ls -l somedir") )
00505 if (rmdir("somedir") == -1)
00506 perror("Expected error");
00507 ec_neg1( system("rm -rf somedir") )
00508 ec_neg1( system("ls -ld somedir") )
00509 return;
00510
00511 EC_CLEANUP_BGN
00512 EC_FLUSH("rmdir_test");
00513 EC_CLEANUP_END
00514 }
00515
00516
00517 static void access_test(void)
00518 {
00519
00520 if (access("tmp", F_OK) == 0)
00521 printf("Exists\n");
00522 else if (errno == EACCES)
00523 printf("Does not exist\n");
00524 else
00525 EC_FAIL
00526
00527 return;
00528
00529 EC_CLEANUP_BGN
00530 EC_FLUSH("access_test");
00531 EC_CLEANUP_END
00532 }
00533
00534 #ifdef _XOPEN_UNIX
00535 void getdate_example(void)
00536 {
00537 struct tm *tp;
00538 char s[100];
00539
00540 printf("Type dates (Ctrl-d to stop)\n");
00541 while (fgets(s, sizeof(s), stdin)) {
00542 s[strlen(s) - 1] = '\0';
00543 printf("Trying \"%s\" ...\n", s);
00544 if ((tp = getdate(s)) == NULL) {
00545 printf("getdate_err = %d\n", getdate_err);
00546 if (getdate_err == 1)
00547 printf("***** Must set environment variable DATEMSK to "
00548 "getdate_template.txt (and EXPORT it).*****\n");
00549 }
00550 else
00551 printf("%s", asctime(tp));
00552 }
00553 }
00554 #endif
00555
00556 int main(int argc, char *argv[])
00557 {
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575 readdir_r_test();
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587 #ifdef _XOPEN_UNIX
00588 getdate_example();
00589 #else
00590 printf("getdate not supported\n");
00591 #endif
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608 return EXIT_SUCCESS;
00609
00610
00611
00612
00613
00614 }