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

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

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

The "pty" module defines operations for handling the pseudo-terminal
concept: starting another process and being able to write to and read
from its controlling terminal programmatically.

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

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

The "pty" module defines the following functions:

pty.fork()

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

   The returned file descriptor *fd* is non-inheritable.

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

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

   Άλλαξε στην έκδοση 3.15: The returned file descriptor is now made
   non-inheritable.

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)
