Source code for schrodinger.test.darwinconsole
import getpass
import os
import sys
from ctypes import CDLL
from ctypes import POINTER
from ctypes import Structure
from ctypes import c_char
from ctypes import c_int16
from ctypes import c_int32
from ctypes.util import find_library
[docs]class Utmpx(Structure):
    """
    This struct utmpx definition is only correct on Darwin.
    """
    _fields_ = (
        ('ut_user', c_char * 256),
        ('ut_id', c_char * 4),
        ('ut_line', c_char * 32),
        ('ut_pid', c_int32),
        ('ut_type', c_int16),
        ('tv_sec', c_int32),
        ('tv_usec', c_int32),
        ('ut_host', c_char * 256),
        ('unused', c_int32 * 16),
    )
    def __repr__(self):
        s = ''
        for field in self._fields_:
            key = field[0]
            s += '{}:{} '.format(key, getattr(self, key))
        return s 
libc_path = find_library('c')
libc = CDLL(libc_path)
[docs]def is_console_user(user=None):
    """
    Returns True if the user is logged into an interactive console.
    This is really only useful on Darwin.
    """
    if user is None:
        user = getpass.getuser()
    user = user.encode('ascii')
    libc.setutxent.restype = None
    libc.getutxent.restype = POINTER(Utmpx)
    libc.getutxent.argtypes = []
    if sys.platform != 'darwin':
        raise UnsupportedPlatformException(
            'is_console_user called on non-Darwin platform')
    libc.setutxent()
    while 1:
        res = libc.getutxent()
        if not res:
            break
        record = res.contents
        if record.ut_user == user and record.ut_line == b'console' and record.ut_type == 7:  #USER_PROCESS
            return True
    return False 
if __name__ == '__main__':
    if len(sys.argv) >= 2:
        user = sys.argv[1]
    else:
        user = os.environ['USER']
    sys.exit(int(not is_console_user(user)))