ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ IΙ Λύβας Χρήστος chrislibas@ssl-unipi.gr Αρχική επιµέλεια Πιτροπάκης Νικόλαος και Υφαντόπουλος Νικόλαος
>_ FILE SYSTEM
>_ ΔΙΚΑΙΩΜΑΤΑ
>_ ΔΙΚΑΙΩΜΑΤΑ?
>_ ΜΕΤΑΒΟΛΗ ΔΙΚΑΙΩΜΑΤΩΝ +- chmod (change mode)- δικαιώματα πρόσβασης αλλαγη αρχεί ου. +- Η εντολη chmod αλλάζει τα permissions ενός αρχείου ή ενός directory. Ένα αρχείο μπορει να έχει τρία δυνατα modes: read, write και execute. Το καθένα απο αυτα αντιπροσωπεύεται απο ένα ακέραιο αριθμο (συμβολισμός 8αδικού συστήματος) ή ένα γράμμα: +- συμβολισμός με αριθμούς read 4 write 2 execute 1 +- συμβολισμός με χαρακτήρες read r write w execute x
>_ CHMOD (1/2) +- Σύνταξη εντολής: chmod mode file +- όπου το mode μπορει να γραφει είτε με την αριθμητικη του μορφη, είτε με τη συμβολικη του μορφη. +- Αλλαγη της λειτουργίας του κάθε ΑΡΧΕΙΟΥ στην MODE. -C, - αλλαγές +- όπως φλύαρη αλλα αναφορα μόνο όταν γίνεται αλλαγη -F, - silent, - quiet +- καταστέλλουν τα περισσότερα μηνύματα λάθους -V, - verbose +- χρησιμοποιήσε τη λειτουργία ΑΡΧΕΙΟΑΝΑΦΟΡΑΣ, αντι των τιμών MODE - Reference = ΑΡΧΕΙΟΑΝΑΦΟΡΑΣ +- Αλλαγη των αρχείων και των καταλόγων αναδρομικα -R, - recursive
>_ CHMOD (2/2) +- Ο έλεγχος των permissions γίνεται σε επίπεδο χρήστη, ομάδας χρηστών και του συνόλου των χρηστών που υπάρχουν σε ένα σύστημα. Για καθένα απο αυτα, ορίζονται οι άδειες για κάθε ένα απο τα τρία δυνατα modes (r,w,x). Ο τρόπος με τον οποίο θέτουμε τα permissions είναι ο εξής: αποφασίζουμε για τον χρήστη (u) στον οποίο ανήκει το αρχείο, το group (g) στο οποίο ανήκει το αρχείο και για το σύνολο των χρηστών του συστήματος (o), τι άδειες πρόσβασης θα έχουν για το αρχείο αυτο. Αν θέλουμε ο χρήστης να έχει δυνατότητα εγγραφής (mode 2), ανάγνωσης (mode4) και εκτέλεσης (mode 1) του αρχείου, σημαίνει ότι συνολικα για τον χρήστη (u) το mode είναι 7 (2+4+1). Εργαζόμαστε με τη ίδια λογικη και για το group (g) και τους υπόλοιπους χρήστες (o). +- Έτσι, ένα αποδεκτο mode για ένα αρχείο θα ήταν το 744, που σημαίνει, read/write/execute για τον χρήστη, read για το group και read επίσης για τους υπόλοιπους χρήστες. Στην περίπτωση που θέλαμε να χρησιμοποιήσουμε την συμβολικη γραφη για τα permissions θα γράφαμε για mode το u=rwx,go=r. Στην περίπτωση που θέλουμε απλα να αλλάξουμε τα permissions προσθέτοντας ή αφαιρώντας άδειες χρήσης, μπορούμε να χρησιμοποιήσουμε τους τελεστές " " και"+" σε συνδυασμο με το είδος της άδειας που θέλουμε να δώσουμε, δηλαδη ένα mode u-r σημαίνει αφαίρεσε την δυνατότητα ανάγνωσης του αρχείου απο τον χρήστη στον οποίο ανήκει αυτο το αρχείο".
>_ ΠΑΡΑΔΕΙΓΜΑ +- Έστω ότι για ένα αρχείο με όνομα file1 θέλουμε να δώσουμε την δυνατότητα ανά γνωσης, εγγραφής και εκτέλεσης για τον χρήστη στον οποίο ανήκει το αρχείο, δυνατό τητα ανάγνωσης και εκτέλεσης για το group και το σύνολο των χρηστών. Αυτο γίνεται ως εξής: +- ή με το συνδιασμο των εξής εντολών: chmod 755 file1 chmod u+rwx file1 chmod go+rx file1
>_ ΑΡΧΕΙΑ
>_ ΑΡΧΕΙΑ ΣΤΗ C (1/7) +- FILE *fopen(const char *filename, const char *mode) +- Ανοίγει το αρχείο με όνομα filename για να το χρησιμοποιήσουμε με τον τρόπο που περιγράφεται στο mode. Επιστρέφει μια ροή (ή δείκτη σε αρχείο), με βάση το οποίο μπορούμε στη συνέχεια να αναφερόμαστε στο αρχείο, ή NULL, αν για κάποιο λόγο δεν ήταν δυνατόν να ανοίξει το α +- Το FILE είναι μία δομη (typedef éd απο το stdio.h) με κατάλληλα μέλη για να γίνεται ο χειρισμός του αρχείου. ρχείο.
>_ ΑΡΧΕΙΑ ΣΤΗ C (2/7) +- Το mode μπορει να είναι: "r" : Για διάβασμα απο υπάρχον αρχείο. "w" : Για γράψιμο σε αρχείο. Αν το αρχείο δεν υπάρχει, δημιουργείται. Αν υπάρχει, τα προηγούμενα περιεχόμενα του διαγράφονται και το γράψιμο αρχίζει απο την αρχη του αρχείου. "a" : Για γράψιμο σε αρχείο με προσάρτηση στο τέλος του των νέων δεδομένων, αν το αρχείο υπάρχει ήδη, χωρίς διαγραφη των προηγούμενων περιεχομένων του. "r+" : Για διάβασμα απο οπουδήποτε μέσα σε υπάρχον αρχείο και γράψιμο στην αρχη του αρχείου, χωρίς διαγραφη των προηγούμενων περιεχομένων του. "w+" : Για διάβασμα και γράψιμο, οπουδήποτε μέσα στο αρχείο, με διαγραφη των προηγούμενων περιεχομένων του, εφ όσον αυτο υπάρχει ήδη. "a+" : Για διάβασμα απο οπουδήποτε μέσα στο αρχείο και γράψιμο μόνο στο τέλος του, χωρίς διαγραφη των προηγούμενων περιεχομένων του.
>_ ΑΡΧΕΙΑ ΣΤΗ C (3/7) +- Σε ορισμένα συστήματα, γίνεται διάκριση μεταξυ αρχείων κειμένου και δυαδικώ ν αρχείων (στο Unix πάντως, όχι), οπότε εκει, αν θέλουμε να χειριστούμε ένα δυαδικο αρχείο, πρέ πει στο mode να προστεθει και ο χαρακτήρας b, δηλαδη να έχουμε, ανάλογα με την περίπτωση "rb", "wb", "ab", "r+b" ("rb+" ), "w+b" ("wb+" ), ή "a+b«("ab+" ). +- Όταν φτάνουμε στο τέλος της εισόδου ενός αρχείου, τότε επιστρέφει στο ό νομα της μία ειδικη τιμη, το EOF, που είναι #define d σε μία συγκεκριμένη ακέραια τιμη μέσα στο αρχείο επικεφαλίδας stdio.h.
>_ ΑΡΧΕΙΑ ΣΤΗ C (4/7) +- int fclose(file *fp) Κλείνει τη ροή fp. Επιστρέφει 0 ή EOF, σε περίπτωση επιτυχίας ή αποτυχίας, αντίστοιχα. +- char *fgets(char *buf, int max, FILE *fp) Διαβάζει το πολυ max-1 χαρακτήρες απο τη ροή fp, μέχρι την αλλαγη γραμμής (\n). Οι χαρακτήρες που διαβάστηκαν (μαζι και με το \n) φυλάσσονται στη συμβολοσειρα buf, η οποία τερματίζεται κανονικα με \0. Επιστρέφει το buf, ή NULL αν έχει διαβαστει όλη η είσοδος. +- int feof(file *fp) Επιστρέφει μη μηδενικη τιμη αν έχουν διαβαστει όλα τα δεδομένα απο τη ροή fp, δηλαδη έχουμε φτάσει στο τέλος του αρχείου που αντιστοιχει στη ροή, ή, αλλιώς, 0. +- int getc(file *fp) Επιστρέφει έναν χαρακτήρα απο το αρχείο μέσω της ροής fp, ή επιστρέφει EOF αν έχουμε φτάσει στο τέλος του αντίστοιχου αρχείου.
>_ ΑΡΧΕΙΑ ΣΤΗ C (5/7) +- int putc(int ch, FILE *fp) Γράφει τον χαρακτήρα ch στη ροή fp και αυξάνει την ένδειξη θέσης κατα ένα. Σε περίπτωση λάθους επιστρέφει EOF. +- int ungetc(int ch, FILE *fp) Γυρίζει πίσω στη ροή fp τον χαρακτήρα ch, έτσι ώστε να διαβαστει πάλι σε επόμενη ανάγνωση. Επιστρέφει τον χαρακτήρα αυτο, ή EOF σε περίπτωση λάθους. +- int fprintf(file *fp, const char *format, <op> 1, <op> 2,...) Ίδια με την printf, μόνο που γράφει στη ροή fp, αντι για το stdout. +- int fscanf(file *fp, const char *format, <op> 1, <op> 2,...) Ίδια με την scanf, μόνο που διαβάζει απο τη ροή fp, αντι απο το stdin. +- int sprintf(char *str, const char *format, <op> 1, <op> 2,...) Ίδια με την printf, μόνο που γράφει στη συμβολοσειρα str, αντι για τη ροή stdout.
>_ ΑΡΧΕΙΑ ΣΤΗ C (6/7) +- size t fread(void *ptr, size t size, size t count, FILE *fp) Διαβάζει απο τη ροή fp το πολυ count δεδομένα μεγέθους size το καθένα και τα τοποθετει απο τη διεύθυνση ptr και μετα. Επιστρέφει το πλήθος των δεδομένων που διαβάστηκαν. Ο έλεγχος τ έλους της εισόδου μπορει να γίνει με τη συνάρτηση feof. +- size t fwrite(const void *ptr, size t size, size t count, FILE *fp) Γράφει στη ροή fp το πολυ count δεδομένα μεγέθους size το καθένα, παίρνοντάς τα απο τη διεύθυνση ptr και μετα. Επιστρέφει το πλήθος των δεδομένων που γράφτηκαν. Αν γραφούν λιγό τερα απο count δεδομένα, αυτο θα οφείλεται σε κάποιο λάθος που συνέβη. +- int fseek(file *fp, long offset, int origin) Θέτει την τρέχουσα θέση στη ροή fp να είναι: +- offset ( 0) χαρακτήρες απο την αρχη, αν το origin έχει τεθει SEEK SET. offset χαρακτήρες απο την τρέχουσα θέση, αν το origin έχει τεθει SEEK CUR. +- offset χαρακτήρες απο το τέλος, αν το origin έχει τεθει SEEK END. Επιστρέφει 0 σε περι πτωση αποτυχίας
+- long ftell(file *fp) >_ ΑΡΧΕΙΑ ΣΤΗ C (7/7) Επιστρέφει την τρέχουσα θέση στη ροή fp, ή -1L σε περίπτωση λάθους. +- int fflush(file *fp) Γράφει στη ροή εξόδου fp ό,τι πιθανώς βρίσκεται στην ενδιάμεση περιοχη αποθήκευσης. Επιστρέφει 0 ή EOF, σε περίπτωση επιτυχίας ή αποτυχίας, αντίστοιχα. +- void perror(const char *s) Εκτυπώνει τη συμβολοσειρα s και μία περιγραφη του πιο πρόσφατου λάθους που έχει συμβει. Η συνάρτηση perror είναι πολυ κατατοπιστικη όταν χρησιμοποιούμε συναρτήσεις της πρότυπης βιβλιοθή κης της C, οι οποίες ενδέχεται να προκαλέσουν κάποιο λάθος, για παράδειγμα η malloc ή οι συναρτήσεις διαχείρισης αρχείων, όπως η fopen, και μας ενδιαφέρει να μάθουμε ποιο ακριβώς λάθος προκλήθηκε. Σχετικη με τη συνάρτηση perror είναι και μία εξωτερικη μεταβλητη errno, η οποία έχει σαν τιμη έναν ακέ ραιο που αντιστοιχει στο πιο πρόσφατο λάθος που έχει συμβει. +- Αν θέλουμε να χρησιμοποιήσουμε τη μεταβλητη errno μέσα σ ένα πρόγραμμα, πρέπει να έχουμε συμπεριλάβει και το αρχείο επικεφαλίδας στο οποίο ορίζεται: #include <errno.h>
>_ ΑΣΚΗΣΗ +- Γράψτε ένα πρόγραμμα σε C, το οποίο να διαβάζει το όνομα και τους βαθμούς n αριθμου μαθητών και να τα αποθηκεύει σε ένα αρχείο.
>_ ΛΥΣΗ
>_ ΑΣΚΗΣΗ +- Γράψτε ένα πρόγραμμα σε C, το οποίο θα αντιγράφει ένα αρχείο σε ένα άλλο.
>_ ΛΥΣΗ
I got tired of people complaining that it was too hard to use UNIX because the editor was too complicated. Bill Joy