"pty" --- Βοηθητικά προγράμματα ψευδοτερματικού
***********************************************

**Πηγαίος κώδικας:** Lib/pty.py

======================================================================

Το "pty" module ορίζει λειτουργίες για τη διαχείριση της έννοιας του
ψευδοτερματικού: την εκκίνηση μιας άλλης διαδικασίας και την ικανότητα
να γράφει και να διαβάζει από το τερματικό πρόγραμμα ελέγχου της
προγραμματιστικά.

Διαθεσιμότητα: Unix.

Η διαχείριση ψευδοτερματικού είναι εξαιρετικά εξαρτώμενη από την
πλατφόρμα. Αυτός ο κώδικας έχει δοκιμαστεί κυρίως σε Linux, FreeBSD
και macOS (υποτίθεται ότι λειτουργεί σε άλλες πλατφόρμες POSIX αλλά
δεν έχει δοκιμαστεί διεξοδώς).

Το "pty" module ορίζει τις ακόλουθες λειτουργίες:

pty.fork()

   Αντιγραφή. Συνδέστε το τερματικό ελέγχου του παιδιού σε ένα
   ψευδοτερματικό. Η επιστρεφόμενη τιμή είναι "(pid, fd)". Σημειώστε
   ότι το παιδί λαμβάνει *pid* 0, και το *fd* είναι *invalid*. Η
   επιστρεφόμενη τιμή του γονέα είναι το *pid* του παιδιού, και το
   *fd* είναι ένας περιγραφέας αρχείου συνδεδεμένος με το τερματικό
   ελέγχου του παιδιού (και επίσης με την τυπική είσοδο και έξοδο του
   παιδιού).

   Προειδοποίηση:

     Σε macOS η χρήση αυτής της λειτουργίας είναι μη ασφαλής όταν
     αναμιγνύεται με τη χρήση ανώτερων συστημικών APIs, και αυτό
     περιλαμβάνει τη χρήση "urllib.request".

pty.openpty()

   Ανοίξτε ένα νέο ζεύγος ψευδοτερματικών, χρησιμοποιώντας
   "os.openpty()" αν είναι δυνατόν, ή κώδικα προσομοίωσης για γενικά
   συστήματα Unix. Επιστρέφει ένα ζεύγος περιγραφέων αρχείων "(master,
   slave)", για το κύριο και το δευτερεύον άκρο, αντίστοιχα.

pty.spawn(argv[, master_read[, stdin_read]])

   Δημιουργήστε μια διαδικασία, και συνδέστε το τερματικό ελέγχου της
   με την τυπική είσοδο/έξοδο της τρέχουσας διαδικασίας. Αυτό
   χρησιμοποιείται συχνά για να αποπροσανατολίσει προγράμματα που
   επιμένουν να διαβάζουν από το τερματικό ελέγχου. Αναμένεται ότι η
   διαδικασία που ξεκίνησε πίσω από το pty θα τερματιστεί τελικά, και
   όταν το κάνει *spawn* θα επιστρέψει.

   Ένας βρόχος αντιγράφει την STDIN της τρέχουσας διαδικασίας στο
   παιδί και τα δεδομένα που λαμβάνονται από το παιδί στην STDOUT της
   τρέχουσας διαδικασίας. Δεν ειδοποιείται το παιδί εάν η STDIN της
   τρέχουσας διαδικασίας κλείσει.

   Οι συναρτήσεις *master_read* και *stdin_read* λαμβάνουν έναν
   περιγραφέα αρχείου από τον οποίο πρέπει να διαβάσουν, και θα πρέπει
   πάντα να επιστρέφουν ένα byte string. Για να αναγκάσετε το spawn να
   επιστρέψει πριν τερματιστεί η διαδικασία παιδί, θα πρέπει να
   επιστραφεί ένας κενός πίνακας byte για να σηματοδοτήσει το τέλος
   του αρχείου.

   Η προεπιλεγμένη υλοποίηση και για τις δύο συναρτήσεις θα διαβάσει
   και θα επιστρέψει έως και 1024 bytes κάθε φορά που καλείται η
   συνάρτηση. Στην κλήση *master_read* περνάει ο περιγραφέας αρχείου
   του κύριου ψευδοτερματικού για να διαβάσει την έξοδο από τη
   διαδικασία παιδί, και στην *stdin_read* περνάει ο περιγραφέας
   αρχείου 0, για να διαβάσει από την τυπική είσοδο της διαδικασίας
   γονέα.

   Επιστροφή ενός κενό πίνακα byte από οποιαδήποτε κλήση ερμηνεύεται
   ως κατάσταση τέλους-αρχείου (EOF), και αυτή η κλήση δεν θα κληθεί
   μετά από αυτό. Εάν η *stdin_read* σηματοδοτήσει EOF, το τερματικό
   ελέγχου δεν μπορεί πλέον να επικοινωνήσει με τη διαδικασία γονέα ή
   τη διαδικασία παιδί. Εκτός εάν η διαδικασία παιδί θα τερματιστεί
   χωρίς καμία είσοδο, το *spawn* θα συνεχίσει να εκτελείται επ'
   άπειρον. Εάν η *master_read* σηματοδοτήσει EOF, προκύπτει η ίδια
   συμπεριφορά (τουλάχιστον στο linux).

   Επιστρέφει την τιμή κατάστασης εξόδου από "os.waitpid()" στη
   διαδικασία παιδί.

   Η συνάρτηση "os.waitstatus_to_exitcode()" μπορεί να χρησιμοποιηθεί
   για να μετατρέψει την κατάσταση εξόδου σε κωδικό εξόδου.

   Κάνει raise ένα auditing event "pty.spawn" με όρισμα "argv".

   Άλλαξε στην έκδοση 3.4: Η συνάρτηση "spawn()" τώρα επιστρέφει την
   τιμή κατάστασης από "os.waitpid()" στη διαδικασία παιδί.


Παράδειγμα
==========

Το ακόλουθο πρόγραμμα λειτουργεί όπως η εντολή Unix *script(1)*,
χρησιμοποιώντας ένα ψευδοτερματικό για να καταγράψει όλη την είσοδο
και έξοδο μιας συνεδρίας τερματικού σε ένα "typescript".

   import argparse
   import os
   import pty
   import sys
   import time

   parser = argparse.ArgumentParser()
   parser.add_argument('-a', dest='append', action='store_true')
   parser.add_argument('-p', dest='use_python', action='store_true')
   parser.add_argument('filename', nargs='?', default='typescript')
   options = parser.parse_args()

   shell = sys.executable if options.use_python else os.environ.get('SHELL', 'sh')
   filename = options.filename
   mode = 'ab' if options.append else 'wb'

   with open(filename, mode) as script:
       def read(fd):
           data = os.read(fd, 1024)
           script.write(data)
           return data

       print('Script started, file is', filename)
       script.write(('Script started on %s\n' % time.asctime()).encode())

       pty.spawn(shell, read)

       script.write(('Script done on %s\n' % time.asctime()).encode())
       print('Script done, file is', filename)
