annotate common.cpp @ 78:07405f3a428b

* Use fork/setsid/fork to escape our controlling terminal, to ensure the pty we create is used for password requests
author Chris Cannam
date Mon, 22 Nov 2010 10:03:15 +0000
parents b522aaa2c053
children aaeabc920ca8
rev   line source
Chris@57 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@57 2
Chris@57 3 /*
Chris@57 4 EasyMercurial
Chris@57 5
Chris@57 6 Based on HgExplorer by Jari Korhonen
Chris@57 7 Copyright (c) 2010 Jari Korhonen
Chris@57 8 Copyright (c) 2010 Chris Cannam
Chris@57 9 Copyright (c) 2010 Queen Mary, University of London
Chris@57 10
Chris@57 11 This program is free software; you can redistribute it and/or
Chris@57 12 modify it under the terms of the GNU General Public License as
Chris@57 13 published by the Free Software Foundation; either version 2 of the
Chris@57 14 License, or (at your option) any later version. See the file
Chris@57 15 COPYING included with this distribution for more information.
Chris@57 16 */
jtkorhonen@0 17
Chris@62 18 #include "common.h"
Chris@62 19 #include "debug.h"
jtkorhonen@0 20
Chris@62 21 #include <QFileInfo>
Chris@62 22 #include <QProcessEnvironment>
Chris@62 23 #include <QStringList>
Chris@77 24 #include <QDir>
jtkorhonen@0 25
Chris@62 26 #include <sys/types.h>
Chris@76 27
Chris@76 28 #ifdef Q_OS_WIN32
Chris@76 29 #define _WIN32_WINNT 0x0500
Chris@76 30 #include <windows.h>
Chris@76 31 #include <security.h>
Chris@76 32 #else
Chris@78 33 #include <errno.h>
Chris@62 34 #include <pwd.h>
Chris@78 35 #include <unistd.h>
Chris@76 36 #endif
Chris@62 37
Chris@62 38 QString findExecutable(QString name)
Chris@62 39 {
Chris@77 40 bool found = false;
Chris@62 41 if (name != "") {
Chris@62 42 if (name[0] != '/') {
Chris@77 43 #ifdef Q_OS_WIN32
Chris@77 44 QChar pathSep = ';';
Chris@77 45 #else
Chris@77 46 QChar pathSep = ':';
Chris@77 47 #endif
Chris@62 48 name = QFileInfo(name).fileName();
Chris@62 49 QString path =
Chris@62 50 QProcessEnvironment::systemEnvironment().value("PATH");
Chris@62 51 DEBUG << "findExecutable: seeking location for binary " << name
Chris@74 52 << ": system path is " << path << endl;
Chris@74 53 #ifndef Q_OS_WIN32
Chris@74 54 path = path + ":/usr/local/bin";
Chris@74 55 DEBUG << "... adding /usr/local/bin just in case (fix and add settings dlg please)"
Chris@74 56 << endl;
Chris@74 57 #endif
Chris@62 58 QStringList elements = path.split(pathSep, QString::SkipEmptyParts);
Chris@62 59 foreach (QString element, elements) {
Chris@77 60 QString full = QDir(element).filePath(name);
Chris@62 61 QFileInfo fi(full);
Chris@62 62 if (fi.exists() && fi.isFile() && fi.isExecutable()) {
Chris@62 63 name = full;
Chris@77 64 found = true;
Chris@62 65 break;
Chris@62 66 }
Chris@62 67 }
Chris@62 68 }
Chris@62 69 }
Chris@77 70 #ifdef Q_OS_WIN32
Chris@77 71 if (!found) {
Chris@77 72 if (!name.endsWith(".exe")) {
Chris@77 73 return findExecutable(name + ".exe");
Chris@77 74 }
Chris@77 75 }
Chris@77 76 #endif
Chris@62 77 return name;
Chris@62 78 }
Chris@62 79
jtkorhonen@0 80 QString getSystem()
jtkorhonen@0 81 {
jtkorhonen@0 82 #ifdef Q_WS_X11
jtkorhonen@0 83 return QString("Linux");
jtkorhonen@0 84 #endif
jtkorhonen@0 85
jtkorhonen@0 86 #ifdef Q_WS_MAC
jtkorhonen@0 87 return QString("Mac");
jtkorhonen@0 88 #endif
jtkorhonen@0 89
jtkorhonen@0 90 #ifdef Q_WS_WIN
jtkorhonen@0 91 return QString("Windows");
jtkorhonen@0 92 #endif
jtkorhonen@0 93
jtkorhonen@0 94 return QString("");
jtkorhonen@0 95 }
jtkorhonen@0 96
jtkorhonen@0 97 QString getHgDirName()
jtkorhonen@0 98 {
jtkorhonen@0 99 if (getSystem() == "Windows")
jtkorhonen@0 100 {
jtkorhonen@0 101 return QString(".hg\\");
jtkorhonen@0 102 }
jtkorhonen@0 103 else
jtkorhonen@0 104 {
jtkorhonen@0 105 return QString(".hg/");
jtkorhonen@0 106 }
jtkorhonen@0 107 }
jtkorhonen@0 108
Chris@62 109 #ifdef Q_OS_WIN32
Chris@62 110 QString getUserRealName()
Chris@62 111 {
Chris@76 112 TCHAR buf[1024];
Chris@76 113 long unsigned int maxlen = 1000;
Chris@62 114 LPTSTR info = buf;
jtkorhonen@0 115
Chris@76 116 if (!GetUserNameEx(NameDisplay, info, &maxlen)) {
Chris@76 117 DEBUG << "GetUserNameEx failed: " << GetLastError() << endl;
Chris@62 118 return "";
Chris@62 119 }
jtkorhonen@0 120
Chris@76 121 #ifdef UNICODE
Chris@76 122 return QString::fromUtf16((const unsigned short *)info);
Chris@76 123 #else
Chris@76 124 return QString::fromLocal8Bit(info);
Chris@76 125 #endif
Chris@62 126 }
luisf@71 127 #else
luisf@71 128 #ifdef Q_OS_MAC
Chris@62 129 // Nothing here: definition is in common_osx.mm
Chris@62 130 #else
Chris@62 131 QString getUserRealName()
Chris@62 132 {
Chris@62 133 const int maxlen = 1023;
Chris@62 134 char buf[maxlen + 2];
jtkorhonen@0 135
Chris@62 136 if (getlogin_r(buf, maxlen)) return "";
jtkorhonen@0 137
Chris@62 138 struct passwd *p = getpwnam(buf);
Chris@62 139 if (!p) return "";
Chris@62 140
Chris@62 141 QString s(p->pw_gecos);
Chris@62 142 if (s != "") s = s.split(',')[0];
Chris@62 143 return s;
Chris@62 144 }
Chris@62 145 #endif
luisf@71 146 #endif
jtkorhonen@0 147
Chris@78 148 void loseControllingTerminal()
Chris@78 149 {
Chris@78 150 #ifndef Q_OS_WIN32
Chris@78 151 pid_t sid;
Chris@78 152 switch (fork()) {
Chris@78 153 case 0:
Chris@78 154 sid = setsid();
Chris@78 155 if (sid != (pid_t)-1) {
Chris@78 156 DEBUG << "setsid() succeeded, session ID is " << sid << endl;
Chris@78 157 } else {
Chris@78 158 perror("setsid failed");
Chris@78 159 DEBUG << "setsid() failed (errno = " << errno << ")" << endl;
Chris@78 160 }
Chris@78 161 switch (fork()) {
Chris@78 162 case 0:
Chris@78 163 return;
Chris@78 164 case -1:
Chris@78 165 perror("fork failed");
Chris@78 166 DEBUG << "second fork failed (errno = " << errno << ")" << endl;
Chris@78 167 return;
Chris@78 168 default:
Chris@78 169 exit(0);
Chris@78 170 }
Chris@78 171 case -1:
Chris@78 172 perror("fork failed");
Chris@78 173 DEBUG << "fork failed (errno = " << errno << ")" << endl;
Chris@78 174 return;
Chris@78 175 default:
Chris@78 176 exit(0);
Chris@78 177 }
Chris@78 178 #endif
Chris@78 179 }