AIX

AIX

Connect with fellow AIX users and experts to gain knowledge, share insights, and solve problems.

 View Only
Expand all | Collapse all

What is ANSI STL or POSIX.2 replacement for getpass()?

  • 1.  What is ANSI STL or POSIX.2 replacement for getpass()?

    Posted Thu November 30, 2006 09:38 AM

    Originally posted by: SystemAdmin


    I understand that getpass() was not brought forward by POSIX.2 .

    How is the equivalent funcationality achieved?
    Is there a code sample online? where?

    The desired functionality is
    1. flush input from the controlling terminal
    2. present a prompt to the controlling terminal
    3. flush output to the controlling terminal
    4. record the state of the controlling terminal
    5. suppress echoing to the controlling terminal
    6. read a line from the controlling terminal
    7. flush input from the controlling terminal
    8. restore the state of the controlling terminal

    How is the above done using <istream> ... ?

    TIA,


  • 2.  Re: What is ANSI STL or POSIX.2 replacement for getpass()?

    Posted Fri March 02, 2007 01:26 PM

    Originally posted by: SystemAdmin


    > I understand that getpass() was deprecated by POSIX.2 .
    > How is the equivalent funcationality achieved with POSIX.2 and C++?

    Use tcgetattr(), tcsetattr().

    ---- getpass.h ----
    // -*- mode: c++; c-basic-offset: 2 -*-
    // Project: executable skeleton
    // File: getpass, non-echoing read from controlling terminal
    // Type: ANSI C++98
    // Copyright: public domain
    // Compliance:
    // POSIX.2
    // ANSI C++98
    // Deviations:
    // none yet
    // Bibliography:
    // POSIX.2 - ISO/IEC 9945-3:1993
    // ANSI C++98 - ISO/IEC 14882-1998
    // Author: rjm - Dr. Robert J. Meier <rm1023@dcx.com>
    // ska - Sanjay Alavandi
    // History: 2006.08.08 -ska- getpass()
    // 2007.02.14 -rjm- ported to pedantic c++98
    /// This file encapsulates a toolkit for standalone executables.
    ///
    /// If compiled with -DSTANDALONE_TEST,
    /// the executable performs a self-diagnostic.
    #ifndef _GETPASS_H_
    1. define _GETPASS_H_

    //
    // Platform dependencies
    //
    ///
    /// @Note All platform dependencies should only define static macros
    /// and only appear in the "Platform dependencies" section.
    /// Elsewhere #ifdef <static macro> should be used to select
    /// algorithm choices.
    ///

    // none yet

    //
    // Interface files
    //

    // ANSI C++98
    #include <string> /* std::string */

    //
    // Functions
    //
    extern "C++" {
    namespace skeleton {
    using std::string;
    /// @brief Read password from terminal without echoing
    ///
    /// Save terminal state.
    /// Disable terminal echoing before reading the password.
    /// Restore terminal state upon success or error
    ///
    /// @return password read from controlling terminal
    /// @param prompt string presented to cout
    /// @throws runtime_error unable to suppress echoing
    static string getpass(string prompt);
    } // namespace skeleton
    } // extern "C++"

    #endif /* _GETPASS_H_ */
    ---- getpass.h ----

    ---- getpass.cpp ----
    // -*- mode: c++; c-basic-offset: 2 -*-
    // Project: executable skeleton
    // File: getpass, non-echoing read from controlling terminal
    // Type: ANSI C++98
    // Usage: (self-diagnostic)
    // ksh> g++ -pedantic -std=c++98 -DSTANDALONE_TEST \
    // > -o getpasstest getpass.cpp
    // ksh> ./getpasstest
    // getpass: Type "abc" and return at the prompt.
    // This should not be echoed>
    // success: abc
    // ksh> ./getpasstest
    // Copyright: public domain
    // Compliance:
    // POSIX.2
    // ANSI C++98
    // Deviations:
    // none yet
    // Bibliography:
    // POSIX.2 - ISO/IEC 9945-3:1993
    // ANSI C++98 - ISO/IEC 14882-1998
    // Author: rjm - Dr. Robert J. Meier <rm1023@dcx.com>
    // ska - Sanjay Alavandi
    // History: 2006.08.08 -ska- getpass()
    // 2007.02.14 -rjm- ported to pedantic c++98

    //
    // Platform dependencies
    //

    // none yet

    //
    // Interface files
    //

    // ANSI C++98
    #include <cstdio> /* stdin */
    #include <iostream> /* std::cout */
    #include <string> /* std::string */
    #include <stdexcept> /* std::runtime_error */

    // POSIX.2
    #include <termios.h> /* struct termios */
    #include <stdio.h> /* fileno() */
    #include <string.h> /* strerror() */

    // Project Peculiar
    #include "skeleton.h" /* skeleton::getpass */

    //
    // Classes
    //
    extern "C++" {
    namespace skeleton {
    using std::cin;
    using std::cout;
    using std::endl;
    using std::flush;
    using std::getline;
    using std::runtime_error;
    using std::string;

    // Read password from controlling terminal without echoing
    string getpass(string prompt) {
    // One-time generation of debug string
    static string name("skeleton::getpass");

    // Cache for terminal state to restore even if unwinding
    struct termios savedtermstate;

    try {
    // Save a copy of the console state to restore;
    // http://ANSI C++98 27.3.1.1 cin must track stdin
    if (tcgetattr(fileno(stdin), &savedtermstate))
    throw runtime_error(name+": get: "+strerror(errno));

    // Suppress echo so password is not logged
    struct termios newtermstate = savedtermstate;
    newtermstate.c_lflag &= ~ECHO;
    if (tcsetattr(fileno(stdin), TCSAFLUSH, &newtermstate))
    throw runtime_error(name+": set: "+strerror(errno));

    // Verify that echo suppression is supported
    // http://POSIX.2 tcgetattr() Rationale must reflect actual state
    if (tcgetattr(fileno(stdin), TCSAFLUSH, &newtermstate))
    throw runtime_error(name+": verify: "+strerror(errno));
    if (newtermstate.c_lflag & ECHO)
    throw runtime_error(name+": verify: unable to suppress echo");

    // Prompt the user for a password
    cout << prompt << flush;
    string password("");
    getline<char>(cin, password);

    // Restore the terminal state before returning
    tcsetattr(fileno(stdin), TCSANOW, &savedtermstate);
    cout << endl;

    return password;
    } catch(...) {
    // Restore the terminal state before further unwinding
    tcsetattr(fileno(stdin), TCSANOW, &savedtermstate);
    throw;
    }
    };

    } // namespace skeleton
    } // extern "C++"

    //
    // Self Diagnostic Entry
    //
    #ifdef STANDALONE_TEST

    extern "C++" {
    using std::cout;
    using std::endl;
    using std::string;
    using skeleton::getpass

    int main(int argc, char *argv[]) {
    cout << "getpass: Type \"abc\" and return at the prompt." << endl;
    string getpass("This should not be echoed>");
    cout << (pass == "abc" ? "success" : "FAILURE");
    cout << ": " << pass << "'" << endl;
    }
    };

    } // extern "C++"

    #endif /* STANDALONE_TEST */
    ---- getpass.cpp ----