1 /**
2  * Copyright: Copyright (c) 2009 Jacob Carlborg. All rights reserved.
3  * Authors: Jacob Carlborg
4  * Version: Initial created: Feb 21, 2009
5  * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0)
6  */
7 module mambo.sys.Process;
8 
9 import mambo.core.string;
10 
11 version (darwin)
12 {
13 	import tango.stdc.posix.stdlib;
14 	import tango.stdc.stringz;
15 	private extern (C) int _NSGetExecutablePath(char* buf, uint* bufsize);
16 }
17 
18 else version (freebsd)
19 	import tango.stdc.posix.unistd;
20 
21 else version (linux)
22 	import tango.stdc.posix.unistd;
23 
24 else version (Windows)
25 {
26 	import tango.sys.win32.UserGdi;
27 	import tango.text.convert.Utf;
28 	import tango.text.Util;
29 }
30 
31 /**
32  * Gets the path of the current process.
33  * 
34  * To fit the whole path inside the given buffer without
35  * using the heap the buffer has to be equal or larger than:
36  * 
37  * On darwin: 1024
38  * On freebsd: 1024
39  * On linux: 1024
40  * On windows: tango.sys.win32.UserGdi.MAX_PATH + 1
41  * 
42  * Params:
43  *     buf = this buffer will be used unless it's to small
44  *     
45  * Returns: the path of the current process
46  */
47 char[] getProcessPath (char[] buf = null)
48 {
49 	version (darwin)
50 	{
51 		uint size;
52 		
53 		_NSGetExecutablePath(null, &size); // get the length of the path
54 		
55 		if (size > buf.length)
56 			buf ~= new char[size - buf.length];
57 		
58 		_NSGetExecutablePath(buf.ptr, &size);
59 		
60 		auto tmp = buf[0 .. size];
61 		size_t len = 1024 - size;	
62 		buf = buf[size .. $];
63 		
64 		if (len > buf.length)
65 			buf ~= new char[len - buf.length];
66 
67 		auto strLen = strlenz(realpath(tmp.ptr, buf.ptr));
68 		buf = buf[0 .. strLen];
69 	}
70 	
71 	else version (freebsd)
72 	{
73 		const size_t len = 1024;
74 		
75 		if (len > buf.length)
76 			buf ~= new char[len - buf.length];
77 		
78 		auto count = readlink("/proc/curproc/file".ptr, buf.ptr, buf.length);
79 		
80 		buf = buf[0 .. count];
81 	}
82 	
83 	else version (linux)
84 	{
85 		const size_t len = 1024;
86 		
87 		if (len > buf.length)
88 			buf ~= new char[len - buf.length];
89 		
90 		auto count = readlink("/proc/self/exe".ptr, buf.ptr, buf.length);
91 		
92 		buf = buf[0 .. count];
93 	}
94 	
95 	else version (Windows)
96 	{
97 		const size_t len = MAX_PATH + 1; // Don't forget the null char
98 		
99 		if (len > buf.length)
100 			buf ~= new char[len - buf.length];
101 		
102 		GetModuleFileNameA(null, buf.ptr, buf.length - 1);
103 		
104 		size_t i = buf.locate(char.init);
105 		
106 		buf = buf[0 .. i - 1]; // Remove the null char		
107 	}
108 	
109 	else
110 		assert(false, "getProcessPath is not supported on this platform");
111 
112 	return buf;
113 }