annotate common.cpp @ 80:32fa40c3d174

* OS/X doesn't like fork() without exec(). Scrap that, revert to ioctl
author Chris Cannam
date Mon, 22 Nov 2010 15:21:12 +0000
parents aaeabc920ca8
children af7cf6f7282c
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@80 36 #include <sys/ioctl.h>
Chris@80 37 #include <sys/types.h>
Chris@80 38 #include <sys/stat.h>
Chris@80 39 #include <fcntl.h>
Chris@76 40 #endif
Chris@62 41
Chris@62 42 QString findExecutable(QString name)
Chris@62 43 {
Chris@77 44 bool found = false;
Chris@62 45 if (name != "") {
Chris@62 46 if (name[0] != '/') {
Chris@77 47 #ifdef Q_OS_WIN32
Chris@77 48 QChar pathSep = ';';
Chris@77 49 #else
Chris@77 50 QChar pathSep = ':';
Chris@77 51 #endif
Chris@62 52 name = QFileInfo(name).fileName();
Chris@62 53 QString path =
Chris@62 54 QProcessEnvironment::systemEnvironment().value("PATH");
Chris@62 55 DEBUG << "findExecutable: seeking location for binary " << name
Chris@74 56 << ": system path is " << path << endl;
Chris@74 57 #ifndef Q_OS_WIN32
Chris@74 58 path = path + ":/usr/local/bin";
Chris@74 59 DEBUG << "... adding /usr/local/bin just in case (fix and add settings dlg please)"
Chris@74 60 << endl;
Chris@74 61 #endif
Chris@62 62 QStringList elements = path.split(pathSep, QString::SkipEmptyParts);
Chris@62 63 foreach (QString element, elements) {
Chris@77 64 QString full = QDir(element).filePath(name);
Chris@62 65 QFileInfo fi(full);
Chris@62 66 if (fi.exists() && fi.isFile() && fi.isExecutable()) {
Chris@62 67 name = full;
Chris@77 68 found = true;
Chris@62 69 break;
Chris@62 70 }
Chris@62 71 }
Chris@62 72 }
Chris@62 73 }
Chris@77 74 #ifdef Q_OS_WIN32
Chris@77 75 if (!found) {
Chris@77 76 if (!name.endsWith(".exe")) {
Chris@77 77 return findExecutable(name + ".exe");
Chris@77 78 }
Chris@77 79 }
Chris@77 80 #endif
Chris@62 81 return name;
Chris@62 82 }
Chris@62 83
jtkorhonen@0 84 QString getSystem()
jtkorhonen@0 85 {
jtkorhonen@0 86 #ifdef Q_WS_X11
jtkorhonen@0 87 return QString("Linux");
jtkorhonen@0 88 #endif
jtkorhonen@0 89
jtkorhonen@0 90 #ifdef Q_WS_MAC
jtkorhonen@0 91 return QString("Mac");
jtkorhonen@0 92 #endif
jtkorhonen@0 93
jtkorhonen@0 94 #ifdef Q_WS_WIN
jtkorhonen@0 95 return QString("Windows");
jtkorhonen@0 96 #endif
jtkorhonen@0 97
jtkorhonen@0 98 return QString("");
jtkorhonen@0 99 }
jtkorhonen@0 100
jtkorhonen@0 101 QString getHgDirName()
jtkorhonen@0 102 {
jtkorhonen@0 103 if (getSystem() == "Windows")
jtkorhonen@0 104 {
jtkorhonen@0 105 return QString(".hg\\");
jtkorhonen@0 106 }
jtkorhonen@0 107 else
jtkorhonen@0 108 {
jtkorhonen@0 109 return QString(".hg/");
jtkorhonen@0 110 }
jtkorhonen@0 111 }
jtkorhonen@0 112
Chris@62 113 #ifdef Q_OS_WIN32
Chris@62 114 QString getUserRealName()
Chris@62 115 {
Chris@76 116 TCHAR buf[1024];
Chris@76 117 long unsigned int maxlen = 1000;
Chris@62 118 LPTSTR info = buf;
jtkorhonen@0 119
Chris@76 120 if (!GetUserNameEx(NameDisplay, info, &maxlen)) {
Chris@76 121 DEBUG << "GetUserNameEx failed: " << GetLastError() << endl;
Chris@62 122 return "";
Chris@62 123 }
jtkorhonen@0 124
Chris@76 125 #ifdef UNICODE
Chris@76 126 return QString::fromUtf16((const unsigned short *)info);
Chris@76 127 #else
Chris@76 128 return QString::fromLocal8Bit(info);
Chris@76 129 #endif
Chris@62 130 }
luisf@71 131 #else
luisf@71 132 #ifdef Q_OS_MAC
Chris@62 133 // Nothing here: definition is in common_osx.mm
Chris@62 134 #else
Chris@62 135 QString getUserRealName()
Chris@62 136 {
Chris@62 137 const int maxlen = 1023;
Chris@62 138 char buf[maxlen + 2];
jtkorhonen@0 139
Chris@62 140 if (getlogin_r(buf, maxlen)) return "";
jtkorhonen@0 141
Chris@62 142 struct passwd *p = getpwnam(buf);
Chris@62 143 if (!p) return "";
Chris@62 144
Chris@62 145 QString s(p->pw_gecos);
Chris@62 146 if (s != "") s = s.split(',')[0];
Chris@62 147 return s;
Chris@62 148 }
Chris@62 149 #endif
luisf@71 150 #endif
jtkorhonen@0 151
Chris@78 152 void loseControllingTerminal()
Chris@78 153 {
Chris@78 154 #ifndef Q_OS_WIN32
Chris@80 155
Chris@80 156 if (!isatty(0)) {
Chris@80 157 DEBUG << "stdin is not a terminal" << endl;
Chris@80 158 } else {
Chris@80 159 DEBUG << "stdin is a terminal, detaching from it" << endl;
Chris@80 160 if (ioctl(0, TIOCNOTTY, NULL) < 0) {
Chris@80 161 perror("ioctl failed");
Chris@80 162 DEBUG << "ioctl for TIOCNOTTY failed (errno = " << errno << ")" << endl;
Chris@78 163 } else {
Chris@80 164 DEBUG << "ioctl for TIOCNOTTY succeeded" << endl;
Chris@78 165 }
Chris@80 166 return;
Chris@80 167 }
Chris@80 168
Chris@80 169 int ttyfd = open("/dev/tty", O_RDWR);
Chris@80 170 if (ttyfd < 0) {
Chris@80 171 DEBUG << "failed to open controlling terminal" << endl;
Chris@80 172 } else {
Chris@80 173 if (ioctl(ttyfd, TIOCNOTTY, NULL) < 0) {
Chris@80 174 perror("ioctl failed");
Chris@80 175 DEBUG << "ioctl for TIOCNOTTY failed (errno = " << errno << ")" << endl;
Chris@80 176 } else {
Chris@80 177 DEBUG << "ioctl for TIOCNOTTY succeeded" << endl;
Chris@78 178 }
Chris@78 179 return;
Chris@78 180 }
Chris@80 181
Chris@78 182 #endif
Chris@78 183 }
Chris@79 184
Chris@79 185 FolderStatus getFolderStatus(QString path)
Chris@79 186 {
Chris@79 187 QFileInfo fi(path);
Chris@79 188 if (fi.exists()) {
Chris@79 189 QDir dir(path);
Chris@79 190 if (!dir.exists()) { // returns false for files
Chris@79 191 return FolderIsFile;
Chris@79 192 }
Chris@79 193 if (QDir(dir.filePath(".hg")).exists()) {
Chris@79 194 return FolderHasRepo;
Chris@79 195 }
Chris@79 196 return FolderExists;
Chris@79 197 } else {
Chris@79 198 QDir parent = fi.dir();
Chris@79 199 if (parent.exists()) {
Chris@79 200 return FolderParentExists;
Chris@79 201 }
Chris@79 202 return FolderUnknown;
Chris@79 203 }
Chris@79 204 }
Chris@79 205
Chris@79 206 QString getContainingRepoFolder(QString path)
Chris@79 207 {
Chris@79 208 if (getFolderStatus(path) == FolderHasRepo) return "";
Chris@79 209
Chris@79 210 QFileInfo me(path);
Chris@79 211 QFileInfo parent(me.dir().absolutePath());
Chris@79 212
Chris@79 213 while (me != parent) {
Chris@79 214 QString parentPath = parent.filePath();
Chris@79 215 if (getFolderStatus(parentPath) == FolderHasRepo) {
Chris@79 216 return parentPath;
Chris@79 217 }
Chris@79 218 me = parent;
Chris@79 219 parent = me.dir().absolutePath();
Chris@79 220 }
Chris@79 221
Chris@79 222 return "";
Chris@79 223 }
Chris@79 224
Chris@79 225 QString xmlEncode(QString s)
Chris@79 226 {
Chris@79 227 s
Chris@79 228 .replace("&", "&amp;")
Chris@79 229 .replace("<", "&lt;")
Chris@79 230 .replace(">", "&gt;")
Chris@79 231 .replace("\"", "&quot;")
Chris@79 232 .replace("'", "&apos;");
Chris@79 233
Chris@79 234 return s;
Chris@79 235 }