1 /** 2 * ae.sys.process 3 * 4 * License: 5 * This Source Code Form is subject to the terms of 6 * the Mozilla Public License, v. 2.0. If a copy of 7 * the MPL was not distributed with this file, You 8 * can obtain one at http://mozilla.org/MPL/2.0/. 9 * 10 * Authors: 11 * Vladimir Panteleev <ae@cy.md> 12 */ 13 14 module ae.sys.process; 15 16 version (Posix) 17 { 18 import core.sys.posix.unistd : getlogin; 19 import std.process : environment; 20 import std.string : fromStringz; 21 } 22 version (Windows) 23 { 24 import core.sys.windows.lmcons : UNLEN; 25 import core.sys.windows.winbase : GetUserNameW; 26 import core.sys.windows.windef : DWORD; 27 import core.sys.windows.winnt : WCHAR; 28 import ae.sys.windows.exception : wenforce; 29 import ae.sys.windows.text : fromWString; 30 } 31 32 /// Get the name of the user that the current process is running under. 33 // Note: Windows does not have numeric user IDs, which is why this 34 // cross-platform function always returns a string. 35 string getCurrentUser() 36 { 37 version (Posix) 38 return environment.get("LOGNAME", cast(string)getlogin().fromStringz); 39 version (Windows) 40 { 41 WCHAR[UNLEN + 1] buf; 42 DWORD len = buf.length; 43 GetUserNameW(buf.ptr, &len).wenforce("GetUserNameW"); 44 return buf[].fromWString(); 45 } 46 } 47 48 version(Posix): 49 50 import ae.net.sync; 51 import ae.sys.signals; 52 53 import std.process; 54 55 /// Asynchronously wait for a process to terminate. 56 void asyncWait(Pid pid, void delegate(int status) dg) 57 { 58 auto anchor = new ThreadAnchor; 59 60 void handler() nothrow @nogc 61 { 62 anchor.runAsync( 63 { 64 // Linux may coalesce multiple SIGCHLD into one, so 65 // we need to explicitly check if our process exited. 66 auto result = tryWait(pid); 67 if (result.terminated) 68 { 69 removeSignalHandler(SIGCHLD, &handler); 70 dg(result.status); 71 } 72 }); 73 } 74 75 addSignalHandler(SIGCHLD, &handler); 76 } 77 78 version(unittest) import ae.sys.timing, ae.net.asockets; 79 80 unittest 81 { 82 string order; 83 84 auto pid = spawnProcess(["sleep", "1"]); 85 asyncWait(pid, (int status) { assert(status == 0); order ~= "b"; }); 86 setTimeout({ order ~= "a"; }, 500.msecs); 87 setTimeout({ order ~= "c"; }, 1500.msecs); 88 socketManager.loop(); 89 90 assert(order == "abc"); 91 }