Πώς να χρησιμοποιήσετε την execvp() σε C και C++
Με execvp, ένα πρόγραμμα μπορεί να εκκινήσει εντολές συστήματος, όπως την εκκίνηση εφαρμογών ή την εκτέλεση υπηρεσιών συστήματος. Όταν συνδυάζεται με τη λειτουργία fork(), ο κώδικας μπορεί επίσης να κληθεί μετά execvp.
Πώς λειτουργεί το execvp;
Ο κύριος σκοπός του execvp είναι να επιτρέπει σε ένα πρόγραμμα να ελέγχει ένα άλλο χωρίς να χρειάζεται να επανεκκινήσει ολόκληρη τη διαδικασία. Αυτό επιτρέπει την απρόσκοπτη εναλλαγή μεταξύ διαφορετικών λειτουργιών ή την εκτέλεση εξωτερικών εντολών με μεταβλητά επιχειρήματα. execvp λειτουργεί σαν ένας αόρατος σκηνοθέτης, αλλάζοντας το σκηνικό και πηδώντας μπρος-πίσω μεταξύ διαφορετικών ιστοριών.
Η δυναμική εκτέλεση διεργασιών σας επιτρέπει να προσαρμόζετε τη διαδρομή του προγράμματος και τα επιχειρήματά του κατά τη διάρκεια της εκτέλεσης. Η συνάρτηση execvp() χρησιμοποιείται σε κλήσεις συστήματος που απαιτούν σύνθετες εργασίες, όπως εκτέλεση σεναρίων, εντολές συστήματος, διαδοχική επεξεργασία και ανακατευθύνσεις. Αυξάνει σημαντικά την ευελιξία των προγραμμάτων C.
Ποια είναι η σύνταξη του execvp;
Η συνάρτηση execvp χρειάζεται δύο παραμέτρους: τη διαδρομή του αρχείου ή το όνομα του προγράμματος που θέλετε να εκτελέσετε και μια σειρά από συμβολοσειρές με τα επιχειρήματα για το πρόγραμμα αυτό.
#include <unistd.h>
int execvp(const char *command, char* argv[]);cconst char *command: Αυτή είναι η διαδρομή του αρχείου ή το όνομα του προγράμματος που θέλετε να εκτελέσετε. Μπορεί να είναι απόλυτη ή σχετική διαδρομή. Εάν χρησιμοποιείται σχετική διαδρομή,execvpαναζητά το αρχείο στο PATH του συστήματος.char *argv[]: Ένας πίνακας συμβολοσειρών που περιέχει τα επιχειρήματα για το πρόγραμμα που θα εκτελεστεί. Ο πίνακας πρέπει να τελειώνει με έναν δείκτηNULLγια να υποδείξει το τέλος της λίστας επιχειρημάτων. Η πρώτη καταχώριση στοargvείναι συνήθως το όνομα του ίδιου του προγράμματος, ακολουθούμενο από τα επιχειρήματα.
Η συνάρτηση execvp και άλλες συναρτήσεις της οικογένειας exec είναι ειδικές για λειτουργικά συστήματα που βασίζονται σε Unix. Η δήλωση #include <unistd.h> είναι ένα αρχείο κεφαλίδας στη γλώσσα προγραμματισμού C που περιέχει ορισμούς και δηλώσεις συναρτήσεων για αλληλεπίδραση με λειτουργικό σύστημα που βασίζεται σε Unix και έλεγχο διεργασιών. Θα συναντήσετε συχνά αυτό το αρχείο όταν μαθαίνετε να γράφετε κώδικα σε C.
Παράδειγμα χρήσης execvp
Στο παρακάτω παράδειγμα, θα χρησιμοποιήσουμε τη συνάρτηση execvp() από το αρχείο κεφαλίδας unistd.h για να ξεκινήσουμε το εξωτερικό πρόγραμμα ls με τα ορίσματα -l και /usr/bin. Ο πίνακας args αντιπροσωπεύει τα ορίσματα του προγράμματος. Εάν η συνάρτηση execvp() είναι επιτυχής, η τρέχουσα διαδικασία θα αντικατασταθεί από το εξωτερικό πρόγραμμα και οι επόμενες γραμμές θα αγνοηθούν. Σε περίπτωση σφάλματος, θα εμφανιστεί ένα μήνυμα σφάλματος μέσω perror και το πρόγραμμα θα επιστρέψει τον κωδικό κατάστασης 1.
#include <unistd.h>
int main() {
char *args[] = {"ls", "-l", "/usr/bin", NULL};
execvp("ls", args);
perror("execvp");
return 1;
}cΧρησιμοποιώντας fork(), μπορείτε να δημιουργήσετε μια νέα διαδικασία. Σε αυτή την υποδιαδικασία, μπορείτε να εκτελέσετε ένα άλλο πρόγραμμα χρησιμοποιώντας execvp. Αυτό επιτρέπει στη γονική διαδικασία να συνεχίσει να εκτελεί τον δικό της κώδικα, ενώ η νέα διαδικασία ξεκινά το εξωτερικό πρόγραμμα.
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main() {
char* command = "ls";
char *args[] = {"ls", "-l", "/usr/bin", NULL};
printf("Before calling execvp()\n");
pid_t child_pid = fork();
if (child_pid == -1) {
// Error creating the process
perror("fork");
return 1;
}
if (child_pid == 0) {
// Code executed in the child process
// Call execvp in the child process to execute "ls" with the specified arguments
int status_code = execvp(command, args);
// This line is reached if execvp encounters an error
perror("execvp");
// Print statement after execvp
printf("ls -l /usr/bin has taken control of this child process. If this is printed, execvp encountered
an error.\n");
// Error handling in the child process
return 1;
} else {
// Code executed in the parent process
// Wait for the completion of the child process
waitpid(child_pid, NULL, 0);
printf("The child process has completed its execution.\n");
}
return 0;
}cΣτο παραπάνω παράδειγμα, δημιουργήσαμε μια νέα διαδικασία χρησιμοποιώντας fork(). Χρησιμοποιώντας τη συνάρτηση execvp(), ls αναλαμβάνει τη θυγατρική διαδικασία με τα επιχειρήματά της. Με waitpid, η γονική διαδικασία περιμένει να ολοκληρωθεί η θυγατρική διαδικασία και στη συνέχεια εμφανίζει το μήνυμα.