2 open opentmpmyfile txt ORDONLY opentmpmyfile txt ORDONLY

  • Slides: 77
Download presentation

Το 2ο όρισμα της συνάρτησης open - Παραδείγματα open("/tmp/myfile. txt", O_RDONLY); open("/tmp/myfile. txt", O_RDONLY,

Το 2ο όρισμα της συνάρτησης open - Παραδείγματα open("/tmp/myfile. txt", O_RDONLY); open("/tmp/myfile. txt", O_RDONLY, S_IRWXU); open("thefile. bin", O_WRONLY | O_TRUNC); open("thefile. bin", O_WRONLY | O_CREAT, S_IRWXU | S_IRGRP); open("thefile. bin", O_WRONLY | O_CREAT | O_EXCL, S_IRWXU); open("thefile. bin", O_RDWR | O_SYNC); open("thefile. bin", O_RDWR | O_APPEND);

Παράδειγμα [long_name. c] #define MAX_NAME_GUESS 256 int make_long_filename(char *path) { char *the. File. Name;

Παράδειγμα [long_name. c] #define MAX_NAME_GUESS 256 int make_long_filename(char *path) { char *the. File. Name; int fd, the. Size, ctr, path. Len = strlen(path); if ((the. Size = pathconf(path, _PC_NAME_MAX)) == -1) { if (errno == 0) the. Size = MAX_NAME_GUESS; else { perror("_PC_NAME_MAX: "); exit(1); } } if ((the. File. Name = malloc(the. Size + path. Len + 4)) == NULL) { perror("malloc"); exit(1); } strcpy(the. File. Name, path); the. File. Name[path. Len] = '/'; for (ctr = 1; ctr <= the. Size + 1; ctr++) the. File. Name[path. Len + ctr] = 'a'; the. File. Name[path. Len + ctr] = ''; if ((fd = open(the. File. Name, O_WRONLY | O_CREAT, S_IRWXU)) == -1) { perror(the. File. Name); return -1; } printf("Created %sn", the. File. Name); close(fd); return 0; }

Συνάρτηση read – Παράδειγμα [fsize. c] • Υπολογισμός μεγέθους αρχείου (εξαιρετικά αναποτελεσματικός) #include <unistd.

Συνάρτηση read – Παράδειγμα [fsize. c] • Υπολογισμός μεγέθους αρχείου (εξαιρετικά αναποτελεσματικός) #include <unistd. h> #include <fcntl. h> #include <errno. h> #define BYTES_TO_READ 1000 size_t file. Size(char *path) { int fd; size_t result = 0, nbytes; char buff[BYTES_TO_READ]; if ((fd = open(path, O_RDONLY)) == -1) { perror(path); return -1; } while ((nbytes = read(fd, buff, BYTES_TO_READ)) > 0) result += nbytes; if (nbytes == -1) perror(path); close(fd); return result; }

Συνάρτηση write – Παράδειγμα [write 0. c] #include <unistd. h> #include <fcntl. h> #include

Συνάρτηση write – Παράδειγμα [write 0. c] #include <unistd. h> #include <fcntl. h> #include <stdlib. h> #include <string. h> #include <errno. h> int main(void) { int fd, nbytes; char *str 1 = "ABCD", *str 2 = "EFGHIJKL"; fd = open("text. dat", O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU); if (fd == -1) { perror("opening text. dat"); exit(1); } if (write(fd, str 1, strlen(str 1) /* + 1 */) < strlen(str 1)) { perror("writing text. dat"); close(fd); exit(2); } if (write(fd, str 2, strlen(str 2) /* + 1 */) < strlen(str 2)) { perror("writing text. dat"); close(fd); exit(2); } close(fd); return 0; }

Συνάρτηση write – Παράδειγμα [write. c] #include <math. h> #include <unistd. h> #include <fcntl.

Συνάρτηση write – Παράδειγμα [write. c] #include <math. h> #include <unistd. h> #include <fcntl. h> #include <stdlib. h> #include <errno. h> int main(void) { int fd, nbytes; double the. Number, the. Sine; fd = open("sines. dat", O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU) if (fd == -1) { perror("opening sines. dat"); exit(1); } for (the. Number = -M_PI; the. Number <= M_PI; the. Number += M_PI / 100) { the. Sine = sin(the. Number); if (write(fd, &the. Sine, sizeof(double)) < sizeof(double)) { perror("writing sines. dat"); close(fd); exit(2); } } close(fd); return 0; }

Συνάρτηση lseek – Παράδειγμα [lseek. c] • Ανάγνωση των bytes 6 -8 από ένα

Συνάρτηση lseek – Παράδειγμα [lseek. c] • Ανάγνωση των bytes 6 -8 από ένα αρχείο #include <unistd. h> #include <fcntl. h> #include <stdio. h> #include <errno. h> #include <sys/types. h> int main(int argc, char *argv[]) { int fd, nbytes, cnt; char buf[3]; if (argc == 1) return 0; if ((fd = open(argv[1], O_RDONLY)) == -1) {perror(argv[1]); exit(1); } if (lseek(fd, (off_t)5, SEEK_SET) == -1) { perror("cannot seek"); close(fd); exit(1); } if ((nbytes = read(fd, buf, 3)) == -1) { perror("Cannot read"); close(fd); exit(1); } printf("read %d bytesn", nbytes); for (cnt = 0; cnt < nbytes; cnt++) putchar(buf[cnt]); putchar('n'); close(fd); return 0; }

Συνάρτηση lseek – Παράδειγμα [lseek 1. c] • Εγγραφή των bytes ABC στις θέσεις

Συνάρτηση lseek – Παράδειγμα [lseek 1. c] • Εγγραφή των bytes ABC στις θέσεις 100 -102 σε ένα αρχείο #include <unistd. h> #include <fcntl. h> #include <stdio. h> #include <errno. h> #include <sys/types. h> int main(int argc, char *argv[]) { int fd, nbytes, cnt; char buf[3] = {'Α', 'Β', 'C'}; if (argc == 1) return 0; if ((fd = open(argv[1], O_WRONLY)) == -1) {perror(argv[1]); exit(1); } if (lseek(fd, (off_t)99, SEEK_SET) == -1) { perror("cannot seek"); close(fd); exit(1); } if ((nbytes = write(fd, buf, 3)) != 3) { perror("Cannot write"); close(fd); exit(1); } close(fd); return 0; }

Αποτελεσματικότητα εισόδου/εξόδου (1) • Έστω το πρόγραμμα [buffersize. c] #include <fcntl. h> #include <sys/types.

Αποτελεσματικότητα εισόδου/εξόδου (1) • Έστω το πρόγραμμα [buffersize. c] #include <fcntl. h> #include <sys/types. h> #include <errno. h> #include <unistd. h> #include <stdio. h> #define BUFFERSIZE 8192 int main(void) { int fd; ssize_t num_bytes; long loop_counter = 0; char buff[BUFFERSIZE]; while ((num_bytes = read(STDIN_FILENO, buff, BUFFERSIZE)) > 0) { if (write(STDOUT_FILENO, buff, num_bytes) < num_bytes) { perror("writing file"); break; } loop_counter++; } if (num_bytes < 0) perror("reading file"); fprintf(stderr, "%ld loops donen", loop_counter); return 0; } • Πως επηρεάζεται από την τιμή του BUFFERSIZE;

Αποτελεσματικότητα εισόδου/εξόδου (2) • Αρχείο εισόδου μεγέθους 6ΜΒ, έξοδος στο /dev/null BUFFERSIZE User CPU

Αποτελεσματικότητα εισόδου/εξόδου (2) • Αρχείο εισόδου μεγέθους 6ΜΒ, έξοδος στο /dev/null BUFFERSIZE User CPU System CPU Clock time #loops 1 10. 014 12. 588 23. 643 6093480 4 2. 233 3. 404 5. 629 1523370 16 0. 620 0. 851 1. 456 380843 64 0. 150 0. 240 0. 401 95211 256 0. 070 0. 090 0. 142 23803 1024 0. 040 0. 060 0. 081 5951 4096 0. 040 0. 030 0. 063 1488 16384 0. 040 0. 030 0. 056 372 65536 0. 040 0. 030 0. 056 93 • Ο πυρήνας διαβάζει/γράφει δεδομένα σε/από ενδιάμεσες μνήμες μεγέθους BUFSIZ

Συνάρτηση ftruncate – παράδειγμα [trunc. c] #include <fcntl. h> #include <stdio. h> #include <errno.

Συνάρτηση ftruncate – παράδειγμα [trunc. c] #include <fcntl. h> #include <stdio. h> #include <errno. h> #include <unistd. h> typedef struct {char isbn[20]; int year. Pub; char title[32]; float price; } book; int main(void) { int fd; ssize_t nbytes; off_t new_len; book the. Book; if ((fd = open("books. dat", O_RDWR)) == -1) { perror("Cannot open books. dat"); exit(1); } if ((new_len = lseek(fd, -(off_t)sizeof(book), SEEK_END)) == -1) { perror("cannot seek"); close(fd); exit(1); } if ((nbytes = read(fd, &the. Book, sizeof(book))) != sizeof(book)) { perror("cannot read"); close(fd); exit(1); } if (lseek(fd, sizeof(book), SEEK_SET) == -1) { perror("cannot seek"); close(fd); exit(1); } if ((nbytes = write(fd, &the. Book, sizeof(book))) != sizeof(book)) { perror("cannot write"); close(fd); exit(1); } if (ftruncate(fd, new_len) == -1) { perror("error in truncation"); close(fd); exit(1); } close(fd); return 0; }

Διαμοιρασμός αρχείων [sharefile. c] int main(void) { int infd, outfd, i, count; char buf[128],

Διαμοιρασμός αρχείων [sharefile. c] int main(void) { int infd, outfd, i, count; char buf[128], buf 1[128]; printf("Enter str: "); gets(buf); if ((infd = open("/etc/passwd", O_RDONLY)) == -1) { perror("/etc/passwd"); exit(1); } if ((outfd = open("testfile. txt", O_WRONLY | O_CREAT, 0644)) == -1) { perror("testfile. txt"); exit(1); } gets(buf 1); count = read(infd, buf 1, 100); buf 1[count] = ''; puts(buf 1); for (i = 0; i < 5; i++) {gets(buf 1); write(outfd, buf, strlen(buf)); } close(infd); close(outfd); return 0; }

Περιγραφείς που δείχνουν στην ίδια δομή πυρήνα [sharefile 2. c] int main(void) { int

Περιγραφείς που δείχνουν στην ίδια δομή πυρήνα [sharefile 2. c] int main(void) { int outfd, count; char *str 1; pid_t chpid; if ((outfd = open("testfile. txt", O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) { perror("testfile. txt"); exit(1); } if ((chpid = fork()) == -1) { perror("creating child"); exit(1); } else if (chpid == 0) { sleep(1); for (count = 0; count < 5; count++) { printf("CHILD: file position = %ldn", tell(outfd)); write(outfd, "CHILD PROCESSn", 14); sleep(2); } close(outfd); return 0; } for (count = 0; count < 5; count++) { printf("PARENT: file position = %ldn", tell(outfd)); write(outfd, "PARENT PROCESSn", 15); sleep(2); } close(outfd); wait(NULL); return 0; }

Παράδειγμα dup και dup 2 • Φλοιός με εντολή ls > myfile char in_redir[PATH_MAX],

Παράδειγμα dup και dup 2 • Φλοιός με εντολή ls > myfile char in_redir[PATH_MAX], out_redir[PATH_MAX]; int inrfd, outrfd, child. Pid; if ((child. Pid = fork()) == 0) { if (in_redir[0] != '') { /* input redirection */. . . } if (out_redir[0] != '') { /* output redirection */ if ((outrfd = open(out_redir, O_WRONLY | O_CREAT | O_TRUNC, the. Mode)) == -1) { perror(out_redir); exit(1); } dup 2(outrfd, STDOUT_FILENO); close(outrfd); } if (execvp("ls", lsargs) == -1). . . } /* Parent and error handling */

Συνάρτηση fcntl • Εντολές F_GETFD, F_SETFD fdflags = fcntl(fd, F_GETFD, 0); res = fcntl(fd,

Συνάρτηση fcntl • Εντολές F_GETFD, F_SETFD fdflags = fcntl(fd, F_GETFD, 0); res = fcntl(fd, F_SETFD, fdflags); • Σε επίπεδο περιγραφέα αρχείου ορίζεται μόνο η ένδειξη F_CLOEXEC • Παράδειγμα: fdflags = fcntl(fd, F_GETFD); if (flags & F_CLOEXEC == 0) puts("File does not close on exec"); else puts("File closes on exec"); puts("Clearing F_CLOEXEC flag. . . "); flags &= ~F_CLOEXEC; res = fcntl(fd, F_SETFD, flags); puts("Seting F_CLOEXEC flag. . . "); flags |= F_CLOEXEC; res = fcntl(fd, F_SETFD, flags);

Συνάρτηση fcntl – Παράδειγμα GETFL [getfl. c] #include <sys/types. h> #include <fcntl. h> #include

Συνάρτηση fcntl – Παράδειγμα GETFL [getfl. c] #include <sys/types. h> #include <fcntl. h> #include <stdio. h> #include <stdlib. h> int main(int argc, char *argv[]) { int accmode, val; if (argc != 2) return 2; if ((val = fcntl(atoi(argv[1]), F_GETFL, 0)) == -1) {perror(argv[1]); exit(1); } accmode = val & O_ACCMODE; if (accmode == O_RDONLY) puts("Read only"); else if (accmode == O_WRONLY) puts("Write only"); else if (accmode == O_RDWR) puts("Read/Write"); else puts("*** Unknown access mode ***"); if (val & O_APPEND) printf("Append"); if (val & O_NONBLOCK) printf(", non-blocking"); #if defined(O_SYNC) if (val & O_SYNC) printf(", synchronous writes"); #endif #if defined(O_ASYNC) if (val & O_SYNC) printf(", asynchronous I/O"); #endif putchar('n'); return 0; }

Συνάρτηση fcntl – Παράδειγμα SETFL /* Get current access mode */ if ((val =

Συνάρτηση fcntl – Παράδειγμα SETFL /* Get current access mode */ if ((val = fcntl(the. Fd, F_GETFL, 0)) == -1) { perror("cannot get current access mode"); exit(1); } /* Set append mode */ fcntl(the. Fd, F_SETFL, val | O_APPEND); /* write data */ write(fd, &the. Rec, sizeof(the. Rec)); /* Restore old access mode */ fcntl(the. Fd, F_SETFL, val);

Η συνάρτηση ioctl - Παράδειγμα • Πρόγραμμα ioctl-t. c #include <fcntl. h> #include <unistd.

Η συνάρτηση ioctl - Παράδειγμα • Πρόγραμμα ioctl-t. c #include <fcntl. h> #include <unistd. h> #include <termios. h> int main(void) { ioctl(STDOUT_FILENO, TIOCSTOP); printf("Hello theren"); printf("HELLO. . . HELLO I SAID!n"); sleep(5); ioctl(STDOUT_FILENO, TIOCSTART); printf("Ah, there you are!n"); return 0; }

Έλεγχος τύπου αρχείων – Παράδειγμα [stat-ftype. c] #include <sys/types. h> #include <sys/stat. h> #include

Έλεγχος τύπου αρχείων – Παράδειγμα [stat-ftype. c] #include <sys/types. h> #include <sys/stat. h> #include <stdio. h> #include <errno. h> #include <string. h> int main(int argc, char *argv[]) { int i; struct stat buf; char *desc_str; for (i = 1; i < argc; i++) { printf("%s: ", argv[i]); if (lstat(argv[i], &buf) == -1) desc_str = strerror(errno); else if (S_ISREG(buf. st_mode)) desc_str = "regular file"; else if (S_ISDIR(buf. st_mode)) desc_str = "directory"; else if (S_ISCHR(buf. st_mode)) desc_str = "character special"; else if (S_ISBLK(buf. st_mode)) desc_str = "block special"; else if (S_ISFIFO(buf. st_mode)) desc_str = "FIFO"; else if (S_ISLNK(buf. st_mode)) desc_str = "symbolic link"; #ifdef S_ISSOCK else if (S_ISSOCK(buf. st_mode)) desc_str = "socket"; #endif else desc_str = "**Unknown mode**"; printf("%sn", desc_str); } return 0; }

chmod – Παράδειγμα [chmod. c] #include <sys/types. h> #include <sys/stat. h> int main(void) {

chmod – Παράδειγμα [chmod. c] #include <sys/types. h> #include <sys/stat. h> int main(void) { struct stat buf; mode_t new_mode; /* Set absolute mode to rx-r--r-- ; chmod 644 file 1*/ if (chmod("file 1", S_IRUSR | S_IXUSR | S_IRGRP | S_IROTH) == -1) perror("Changing mode of file 1"); /* Read perms of file 2 for changing; chmod g+s, o-w file 2 */ if (stat("file 2", &buf) == 0) { new_mode = buf. st_mode & S_IAMB; new_mode |= S_ISGID; new_mode &= ~S_IWOTH; if (chmod("file 2", new_mode) == -1) perror("Changing mode of file 2"); } else perror("cannot stat file 2"); return 0; }

Συμβολικοί σύνδεσμοι [symlink. c] int main(void) { struct stat link_stat, file_stat; char buf[512]; int

Συμβολικοί σύνδεσμοι [symlink. c] int main(void) { struct stat link_stat, file_stat; char buf[512]; int result; if (symlink("/etc/passwd", "mylink") == -1) { perror("symlink mylink to /etc/passwd"); exit(1); } if (stat("mylink", &file_stat) == -1) { perror("cannot stat mylink"); exit(1); } if (lstat("mylink", &link_stat) == -1) { perror("cannot stat mylink"); exit(1); } printf("stat size: %ld, lstat size: %ldn", (long)(file_stat. st_size), (long)(link_stat. st_size)); if ((result = readlink("mylink", buf, 511)) == -1) { perror("reading mylink contents"); exit(1); } buf[result] = ''; printf("mylink contents: %sn", buf); if (unlink("mylink") == -1) { perror("unlinking mylink"); exit(1); } return 0; }

Δυνατότητα επανεισόδου • Έστω το κάτωθι πρόγραμμα εκτύπωσης κατά στήλες αρχείων και ημερομηνιών τελευταίας

Δυνατότητα επανεισόδου • Έστω το κάτωθι πρόγραμμα εκτύπωσης κατά στήλες αρχείων και ημερομηνιών τελευταίας τροποποίησης αρχείων [readdir 1. c]: int main(int argc, char *argv[]) { struct dirent **d_ents; char **dent_dates; int ncols, ctr 1, ctr 2; DIR *d 1; struct stat iteminfo; ncols = (argc > 1) ? (atoi(argv[1])) : 1; if ((ncols < 1) || (ncols > 100)) { fprintf(stderr, "Invalid columns value - defaulting to 1n"); ncols = 1; } d_ents = malloc(sizeof(struct dirent *) * ncols); dent_dates = malloc(sizeof(char *) * ncols); d 1 = opendir(". "); do { for (ctr 1 = 0; ctr 1 < ncols; ctr 1++) { if ((d_ents[ctr 1] = readdir(d 1)) == NULL) break; lstat(d_ents[ctr 1]->d_name, &iteminfo); dent_dates[ctr 1] = asctime(localtime(&(iteminfo. st_mtime))); } for (ctr 2 = 0; ctr 2 < ctr 1; ctr 2++) printf("%s-->%. 24 s ", d_ents[ctr 2]->d_name, dent_dates[ctr 2]); putchar('n'); } while (ctr 1 > 0); closedir(d 1); return 0; }

Ανάγνωση καταλόγων [read_a_dir. c] int main(int argc, char *argv[]) { DIR *dp; struct dirent

Ανάγνωση καταλόγων [read_a_dir. c] int main(int argc, char *argv[]) { DIR *dp; struct dirent *dirp; char the. Path[PATH_MAX]; if (argc != 2) { fprintf(stderr, "provide the directory namen"); exit(1); } if ((dp = opendir(argv[1])) == NULL) perror(argv[1]); exit(1); } while ((dirp = readdir(dp)) != NULL) { printf("%lut%-30 st", (unsigned long)(dirp->d_ino), dirp->d_name); sprintf(the. Path, "%s/%s", argv[1], dirp->d_name); putchar(access(the. Path, R_OK) == 0 ? 'r' : '-'); putchar(access(the. Path, W_OK) == 0 ? 'w' : '-'); putchar(access(the. Path, X_OK) == 0 ? 'x' : '-'); putchar('n'); } closedir(dp); return 0; }

Διαχείριση τρέχοντος καταλόγου • Κλήσεις συστήματος για ορισμό και αναφορά τρέχοντος καταλόγου #include <unistd.

Διαχείριση τρέχοντος καταλόγου • Κλήσεις συστήματος για ορισμό και αναφορά τρέχοντος καταλόγου #include <unistd. h> int chdir(const char *pathname); int fchdir(int filedes); int getcwd(char *buf, size_t size); • Η αλλαγή τρέχοντος καταλόγου ισχύει για τη διεργασία που αλλάζει κατάλογο και όχι για τη γονική της if (chdir(argv[1]) == -1) err_die("cannot chdir"); if ((dirp = opendir(". ")) == NULL) err_die("cannot chdir"); while ((dirp = readdir(dp)) != NULL) { printf("%lut%-30 st", (unsigned long)(dirp->d_ino), dirp->d_name); putchar(access(dirp->d_name, R_OK) == 0 ? 'r' : '-'); putchar(access(dirp->d_name, W_OK) == 0 ? 'w' : '-'); putchar(access(dirp->d_name, X_OK) == 0 ? 'x' : '-'); putchar('n'); }