Κλήση συστήματος Linux Exec

Linux Exec System Call



Η κλήση συστήματος exec χρησιμοποιείται για την εκτέλεση ενός αρχείου που βρίσκεται σε μια ενεργή διαδικασία. Όταν καλείται exec, το προηγούμενο εκτελέσιμο αρχείο αντικαθίσταται και το νέο αρχείο εκτελείται.

Πιο συγκεκριμένα, μπορούμε να πούμε ότι η χρήση κλήσης συστήματος exec θα αντικαταστήσει το παλιό αρχείο ή πρόγραμμα από τη διαδικασία με ένα νέο αρχείο ή πρόγραμμα. Ολόκληρο το περιεχόμενο της διαδικασίας αντικαθίσταται με νέο πρόγραμμα.







Το τμήμα δεδομένων χρήστη που εκτελεί την κλήση συστήματος exec () αντικαθίσταται με το αρχείο δεδομένων του οποίου το όνομα παρέχεται στο όρισμα κατά την κλήση του exec ().



Το νέο πρόγραμμα φορτώνεται στον ίδιο χώρο διαδικασίας. Η τρέχουσα διαδικασία μόλις μετατράπηκε σε μια νέα διαδικασία και ως εκ τούτου το PID id της διαδικασίας δεν αλλάζει, αυτό συμβαίνει επειδή δεν δημιουργούμε μια νέα διαδικασία αλλά απλώς αντικαθιστούμε μια διαδικασία με μια άλλη διαδικασία στο exec.



Εάν η τρέχουσα διαδικασία περιέχει περισσότερα από ένα νήματα, τότε όλα τα νήματα θα τερματιστούν και η νέα εικόνα της διαδικασίας θα φορτωθεί και στη συνέχεια θα εκτελεστεί. Δεν υπάρχουν συναρτήσεις καταστροφής που τερματίζουν νήματα της τρέχουσας διαδικασίας.





Το PID της διαδικασίας δεν αλλάζει αλλά τα δεδομένα, ο κώδικας, η στοίβα, ο σωρός, κ.λπ. της διαδικασίας αλλάζουν και αντικαθίστανται με αυτά της νέας φόρτωσης της διαδικασίας. Η νέα διαδικασία εκτελείται από το σημείο εισόδου.

Η κλήση συστήματος Exec είναι μια συλλογή λειτουργιών και στη γλώσσα προγραμματισμού C, τα τυπικά ονόματα αυτών των συναρτήσεων είναι τα εξής:



  1. εκτ
  2. εκτέλεση
  3. execlp
  4. execv
  5. εκτελώ
  6. execvp


Πρέπει να σημειωθεί εδώ ότι αυτές οι συναρτήσεις έχουν την ίδια βάση εκτελ ακολουθούμενο από ένα ή περισσότερα γράμματα. Αυτά εξηγούνται παρακάτω:

Και: Είναι ένας πίνακας δεικτών που δείχνει μεταβλητές περιβάλλοντος και μεταφέρεται ρητά στη διαδικασία που φορτώθηκε πρόσφατα.

ο: Το l είναι για τα ορίσματα της γραμμής εντολών που πέρασαν μια λίστα στη συνάρτηση

Π: p είναι η μεταβλητή περιβάλλοντος διαδρομής που βοηθά στην εύρεση του αρχείου που έχει περάσει ως όρισμα για φόρτωση στη διαδικασία.

v: v είναι για τα ορίσματα της γραμμής εντολών. Αυτά μεταφέρονται ως πίνακας δεικτών στη συνάρτηση.

Γιατί χρησιμοποιείται το exec;

exec χρησιμοποιείται όταν ο χρήστης θέλει να ξεκινήσει ένα νέο αρχείο ή πρόγραμμα στην ίδια διαδικασία.

Εσωτερική εργασία του exec

Εξετάστε τα ακόλουθα σημεία για να κατανοήσετε τη λειτουργία του exec:

  1. Η τρέχουσα εικόνα διεργασίας αντικαθίσταται με μια νέα εικόνα διεργασίας.
  2. Η νέα εικόνα διαδικασίας είναι αυτή που περάσατε ως όρισμα exec
  3. Η τρέχουσα διαδικασία ολοκληρώθηκε
  4. Η νέα εικόνα διαδικασίας έχει το ίδιο αναγνωριστικό διεργασίας, το ίδιο περιβάλλον και τον ίδιο περιγραφέα αρχείων (επειδή η διαδικασία δεν αντικαθίσταται η εικόνα της διαδικασίας αντικαθίσταται)
  5. Η κατάσταση της CPU και η εικονική μνήμη επηρεάζονται. Η απεικόνιση εικονικής μνήμης της τρέχουσας εικόνας διεργασίας αντικαθίσταται από εικονική μνήμη νέας εικόνας διεργασίας.

Συντάξεις λειτουργιών οικογένειας exec:

Ακολουθούν οι συντακτικές για κάθε συνάρτηση του exec:

int execl (const char* path, const char* arg,…)
int execlp (const char* αρχείο, const char* arg,…)
int execle (const char* path, const char* arg,…, char* const envp [])
int execv (const char* path, const char* argv [])
int execvp (const char* αρχείο, const char* argv [])
int execvpe (const char* αρχείο, const char* argv [], char* const envp [])

Περιγραφή:

Ο τύπος επιστροφής αυτών των συναρτήσεων είναι Int. Όταν η εικόνα διεργασίας αντικατασταθεί επιτυχώς, τίποτα δεν επιστρέφει στη λειτουργία κλήσης, επειδή η διαδικασία που την κάλεσε δεν εκτελείται πλέον. Αλλά εάν υπάρχει κάποιο σφάλμα -1 θα επιστρέφεται. Εάν παρουσιαστεί κάποιο σφάλμα, errno έχει οριστεί.

Στη σύνταξη:

  1. μονοπάτι χρησιμοποιείται για τον καθορισμό του πλήρους ονόματος διαδρομής του αρχείου που πρόκειται να εκτελεστεί.
  1. θυμωμένος έχει περάσει το επιχείρημα. Είναι στην πραγματικότητα το όνομα του αρχείου που θα εκτελεστεί κατά τη διαδικασία. Τις περισσότερες φορές η τιμή του arg και της διαδρομής είναι ίδια.
  1. const char* arg στις συναρτήσεις execl (), execlp () και execle () θεωρείται ως arg0, arg1, arg2,…, argn. Είναι βασικά ένας κατάλογος δεικτών προς μηδενικές τερματισμένες συμβολοσειρές. Εδώ το πρώτο όρισμα δείχνει το όνομα αρχείου το οποίο θα εκτελεστεί όπως περιγράφεται στο σημείο 2.
  1. περιτ είναι ένας πίνακας που περιέχει δείκτες που δείχνουν τις μεταβλητές περιβάλλοντος.
  1. αρχείο χρησιμοποιείται για να καθορίσει το όνομα της διαδρομής που θα προσδιορίσει τη διαδρομή του νέου αρχείου εικόνας διεργασίας.
  1. Οι συναρτήσεις της κλήσης exec που τελειώνουν με Και χρησιμοποιούνται για την αλλαγή του περιβάλλοντος για τη νέα εικόνα της διαδικασίας. Αυτές οι συναρτήσεις περνούν λίστα ρυθμίσεων περιβάλλοντος χρησιμοποιώντας το όρισμα περιτ Το Αυτό το όρισμα είναι ένας πίνακας χαρακτήρων που οδηγεί σε μηδενική τερματική συμβολοσειρά και ορίζει μεταβλητή περιβάλλοντος.

Για να χρησιμοποιήσετε τις λειτουργίες οικογένειας exec, πρέπει να συμπεριλάβετε το ακόλουθο αρχείο κεφαλίδας στο πρόγραμμα C:

#περιλαμβάνω

Παράδειγμα 1: Χρήση κλήσης συστήματος exec στο πρόγραμμα C

Εξετάστε το ακόλουθο παράδειγμα στο οποίο χρησιμοποιήσαμε κλήση συστήματος exec στον προγραμματισμό C στο Linux, Ubuntu: Έχουμε δύο αρχεία c εδώ example.c και hello.c:

παράδειγμα.γ

ΚΩΔΙΚΑΣ:

#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω
intκύριος(intargc, απανθρακώνω *argv[])
{
printf ('PID του παραδείγματος.c = %d n',χάλια())?
απανθρακώνω *αψίδες[] = {'Γεια σας', 'ΝΤΟ', 'Προγραμματισμός',ΜΗΔΕΝΙΚΟ}?
execv('./γεια σας',αψίδες)?
printf ('Επιστροφή στο example.c')?
ΕΠΙΣΤΡΟΦΗ 0?
}

γεια.γ

ΚΩΔΙΚΑΣ:

#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω
intκύριος(intargc, απανθρακώνω *argv[])
{
printf («Είμαστε στο Hello.c n')?
printf ('PID του hello.c = %d n',χάλια())?
ΕΠΙΣΤΡΟΦΗ 0?
}

ΠΑΡΑΓΩΓΗ:

PID του παραδείγματος.c = 4733
Βρισκόμαστε στο Hello.c
PID του hello.c = 4733

Στο παραπάνω παράδειγμα έχουμε ένα αρχείο example.c και αρχείο hello.c. Στο παράδειγμα .c αρχείο πρώτα απ 'όλα έχουμε εκτυπώσει το αναγνωριστικό της τρέχουσας διαδικασίας (το αρχείο example.c εκτελείται στην τρέχουσα διαδικασία). Στη συνέχεια, στην επόμενη γραμμή έχουμε δημιουργήσει μια σειρά από δείκτες χαρακτήρων. Το τελευταίο στοιχείο αυτού του πίνακα θα πρέπει να είναι το NULL ως τελικό σημείο.

Στη συνέχεια, χρησιμοποιήσαμε τη συνάρτηση execv () η οποία παίρνει το όνομα αρχείου και τον πίνακα δείκτη χαρακτήρων ως όρισμα. Πρέπει να σημειωθεί εδώ ότι έχουμε χρησιμοποιήσει ./ με το όνομα του αρχείου, καθορίζει τη διαδρομή του αρχείου. Καθώς το αρχείο βρίσκεται στο φάκελο όπου βρίσκεται το example.c, δεν χρειάζεται να καθορίσετε την πλήρη διαδρομή.

Όταν κληθεί η συνάρτηση execv (), η εικόνα της διαδικασίας μας θα αντικατασταθεί τώρα το αρχείο example.c δεν είναι στη διαδικασία αλλά το αρχείο hello.c είναι σε διαδικασία. Μπορεί να φανεί ότι το αναγνωριστικό διεργασίας είναι ίδιο είτε το hello.c είναι εικόνα διεργασίας είτε το example.c είναι εικόνα διεργασίας επειδή η διαδικασία είναι ίδια και η εικόνα διεργασίας αντικαθίσταται μόνο.

Στη συνέχεια, έχουμε ένα άλλο πράγμα που πρέπει να σημειώσουμε εδώ, το οποίο είναι ότι η εντολή printf () μετά την εκτέλεση του execv () δεν εκτελείται. Αυτό συμβαίνει επειδή ο έλεγχος δεν επιστρέφεται ποτέ στην παλιά εικόνα διεργασίας μόλις την αντικαταστήσει η νέα εικόνα διεργασίας. Το στοιχείο ελέγχου επιστρέφει στη λειτουργία κλήσης μόνο όταν η αντικατάσταση της εικόνας διεργασίας δεν είναι επιτυχής. (Η τιμή επιστροφής είναι -1 στην περίπτωση αυτή).

Διαφορά μεταξύ κλήσεων συστήματος fork () και exec ():

Η κλήση συστήματος fork () χρησιμοποιείται για τη δημιουργία ενός ακριβούς αντιγράφου μιας διαδικασίας που εκτελείται και το αντίγραφο που δημιουργήθηκε είναι η θυγατρική διαδικασία και η διαδικασία εκτέλεσης είναι η γονική διαδικασία. Ενώ, η κλήση συστήματος exec () χρησιμοποιείται για να αντικαταστήσει μια εικόνα διεργασίας με μια νέα εικόνα διεργασίας. Επομένως, δεν υπάρχει έννοια διαδικασιών γονέα και παιδιού στην κλήση συστήματος exec ().

Στο σύστημα κλήσης πιρούνι () οι διαδικασίες γονέα και παιδιού εκτελούνται ταυτόχρονα. Αλλά στην κλήση συστήματος exec (), εάν η αντικατάσταση της εικόνας διεργασίας είναι επιτυχής, ο έλεγχος δεν επιστρέφει εκεί όπου κλήθηκε η συνάρτηση exec μάλλον θα εκτελέσει τη νέα διαδικασία. Το στοιχείο ελέγχου θα μεταφερθεί πίσω μόνο εάν υπάρχει κάποιο σφάλμα.

Παράδειγμα 2: Συνδυασμός κλήσεων συστήματος fork () και exec ()

Εξετάστε το ακόλουθο παράδειγμα στο οποίο έχουμε χρησιμοποιήσει και τις κλήσεις συστήματος fork () και exec () στο ίδιο πρόγραμμα:

παράδειγμα.γ

ΚΩΔΙΚΑΣ:

#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω
intκύριος(intargc, απανθρακώνω *argv[])
{
printf ('PID του παραδείγματος.c = %d n',χάλια())?
pid_t ρ?
Π=πιρούνι()?
αν(Π== -1)
{
printf ('Υπάρχει σφάλμα κατά την κλήση του πιρουνιού ()')?
}
αν(Π==0)
{
printf («Είμαστε στη διαδικασία του παιδιού n')?
printf («Καλώντας το hello.c από τη διαδικασία του παιδιού n')?
απανθρακώνω *αψίδες[] = {'Γεια σας', 'ΝΤΟ', 'Προγραμματισμός',ΜΗΔΕΝΙΚΟ}?
execv('./γεια σας',αψίδες)?
}
αλλού
{
printf («Είμαστε στη διαδικασία του γονέα»)?
}
ΕΠΙΣΤΡΟΦΗ 0?
}

γεια σας.c:

ΚΩΔΙΚΑΣ:

#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω
intκύριος(intargc, απανθρακώνω *argv[])
{
printf («Είμαστε στο Hello.c n')?
printf ('PID του hello.c = %d n',χάλια())?
ΕΠΙΣΤΡΟΦΗ 0?
}

ΠΑΡΑΓΩΓΗ:

PID του παραδείγματος.c = 4790
Είμαστε σε διαδικασία Γονέα
Βρισκόμαστε στη διαδικασία του παιδιού
Κλήση hello.c από τη διαδικασία για παιδιά
Είμαστε στο hello.c
PID του hello.c = 4791

Σε αυτό το παράδειγμα χρησιμοποιήσαμε κλήση συστήματος fork (). Όταν δημιουργηθεί η θυγατρική διαδικασία, το 0 θα αντιστοιχιστεί στο p και στη συνέχεια θα περάσουμε στη θυγατρική διαδικασία. Τώρα το μπλοκ των δηλώσεων με εάν (p == 0) θα εκτελεστεί. Εμφανίζεται ένα μήνυμα και χρησιμοποιήσαμε την κλήση συστήματος execv () και η τρέχουσα θυγατρική εικόνα που είναι example.c θα αντικατασταθεί με hello.c. Πριν από την κλήση execv () οι διαδικασίες παιδιού και γονέα ήταν ίδιες.

Μπορεί να φανεί ότι το PID των example.c και hello.c είναι διαφορετικό τώρα. Αυτό συμβαίνει γιατί το example.c είναι η εικόνα της γονικής διαδικασίας και το hello.c είναι η εικόνα της διαδικασίας του παιδιού.