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_
-
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 ----