©2004 by Marc J. Rochkind. All rights reserved. Portions marked "Open Source" may be copied under license.

 

Main Page   Modules   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

c3/x3a.c

Go to the documentation of this file.
00001 /*
00002     Miscellaneous examples for Chap. 3
00003     AUP2, Chap. 3
00004 
00005     NOTE: Some of this code is from AUP1 and no longer works.
00006 
00007     Copyright 2003 by Marc J. Rochkind. All rights reserved.
00008     May be copied only for purposes and under conditions described
00009     on the Web page www.basepath.com/aup/copyright.htm.
00010 
00011     The Example Files are provided "as is," without any warranty;
00012     without even the implied warranty of merchantability or fitness
00013     for a particular purpose. The author and his publisher are not
00014     responsible for any damages, direct or incidental, resulting
00015     from the use or non-use of these Example Files.
00016 
00017     The Example Files may contain defects, and some contain deliberate
00018     coding mistakes that were included for educational reasons.
00019     You are responsible for determining if and how the Example Files
00020     are to be used.
00021 
00022 */
00023 #define __EXTENSIONS__
00024 #include "defs.h"
00025 /*3-3*/
00026 #ifdef WANT_INODE
00027 #include <sys/types.h>
00028 #include <sys/ino.h>
00029 
00030 inodes()  /* print i-node info */
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) /* seek to i-node 2 */
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 /*3-4*/
00057 #if 0
00058 #include <sys/dir.h>
00059 
00060 directory(path)  /* list directory */
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 //printf("%d\n", where[i]);
00121 }
00122     printf("RAWBUFSIZE = %d; NUMBLOCKS = %d\n", RAWBUFSIZE, NUMBLOCKS);
00123     //ec_neg1( mlockall(MCL_CURRENT | MCL_FUTURE) )
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 /* WANT_RAWFILE */
00182 
00183 #if 0
00184 /*3-5*/
00185 int mkdir(path)  /* make directory; must be superuser */
00186 char *path;
00187 {
00188     return(mknod(path, S_IFDIR | 0775, 0));
00189 }
00190 /**/
00191 
00192 /*3-6*/
00193 int mkdir2(path)  /* make directory */
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 /*3-7*/
00207 int mkfifo(path)  /* make FIFO */
00208 char *path;
00209 {
00210     return(mknod(path, S_IFIFO | 0666, 0));
00211 }
00212 /**/
00213 
00214 /*3-8*/
00215 mv(from, to)  /* move file or directory; must be superuser */
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)  /* is path a directory? */
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 /*3-9*/
00245 char *parent(path, dir)  /* get parent directory */
00246 char *path, *dir;
00247 {
00248     char *lastslash, *strrchr();
00249 
00250     strcpy(dir, path);
00251     lastslash = strrchr(dir, '/');
00252     if (lastslash == NULL) /* current directory */
00253         strcpy(dir, ".");
00254     else if (lastslash == dir) /* root */
00255         strcpy(dir, "/");
00256     else
00257         *lastslash = '\0';
00258     return(dir);
00259 }
00260 /**/
00261 
00262 mv2(from, to) /* must be superuser */
00263 char *from, *to;
00264 {
00265     bool isdir();
00266     extern int errno;
00267 /*3-10*/
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 /*[setappend-right]*/
00290     ec_neg1( flags = fcntl(fd, F_GETFL) )
00291     ec_neg1( fcntl(fd, F_SETFL, flags | O_APPEND) )
00292 /*[clearappend-right]*/
00293     ec_neg1( fcntl(fd, F_SETFL, flags & ~O_APPEND) )
00294 /*[setappend-wrong]*/
00295     ec_neg1( fcntl(fd, F_SETFL, O_APPEND) ) /* wrong */
00296 /*[O_ACCMODE-right]*/
00297     ec_neg1( flags = fcntl(fd, F_GETFL) )
00298     if ((flags & O_ACCMODE) == O_RDONLY)
00299         /* file is opened read-only */
00300 /*[O_ACCMODE-wrong]*/
00301     if (flags & O_RDONLY)               /* wrong */
00302     if ((flags & O_RDONLY) == O_RDONLY) /* still wrong */
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 /*[print_statvfs]*/
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 /*[dir_read_test]*/
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 /*[readdir_r_test]*/
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     /* failure with errno == 0 means value not found */
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 /*[readdir_test]*/
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 /*[rmdir_test]*/
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 /*[access-example]*/
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     char s[50], dir[50];
00560     int fd;
00561     inodes();
00562     directory("/usr/marc/stuff");
00563 {
00564     ssize_t n;
00565     char buf[1024];
00566 
00567     ec_neg1( symlink("lunch with Mike at 11:30", "/home/marc/mylink") )
00568     ec_neg1( n = readlink("/home/marc/mylink", buf, sizeof(buf) - 1) )
00569     buf[n] = '\0';
00570 
00571     printf("\"%s\"\n", buf);
00572 }
00573     file_ctime_test();
00574 */
00575     readdir_r_test();
00576 /*
00577     printf("-----\n");
00578     readdir_test();
00579     access_test();
00580     fcntl_example();
00581     rmdir_test();
00582     if (argc > 1)
00583         print_statvfs(argv[1]);
00584     else
00585         print_statvfs(NULL);
00586 */
00587 #ifdef _XOPEN_UNIX
00588     getdate_example();
00589 #else
00590     printf("getdate not supported\n");
00591 #endif
00592 /*
00593     rawfile();
00594     mkdir2("dirx.tmp");
00595     while (gets(s) != NULL)
00596         printf("\"%s\"\n", parent(s, dir));
00597     mv2(argv[1], argv[2]);
00598     mkfifo("fifo.tmp");
00599     if (mkdir("dir.tmp") == -1)
00600         syserr("mkdir");
00601     system("li -ld *.tmp; rm -rf *.tmp");
00602     if ((fd = open("z.tmp", 1)) == -1)
00603         syserr("open");
00604     if (setappend(fd) == -1)
00605         syserr("setappend");
00606     write(fd, "should be last\n", 15);
00607 */
00608     return EXIT_SUCCESS;
00609 /*
00610 EC_CLEANUP_BGN
00611     return EXIT_FAILURE;
00612 EC_CLEANUP_END
00613 */
00614 }

Generated on Fri Apr 23 10:56:55 2004 for AUP2 Example Source by doxygen 1.3.1