1 //
2 // Mono.Unix/UnixEnvironment.cs
3 //
4 // Authors:
5 //   Jonathan Pryor (jonpryor@vt.edu)
6 //
7 // (C) 2004 Jonathan Pryor
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 
29 using System;
30 using System.Collections;
31 using System.Text;
32 using Mono.Unix;
33 
34 namespace Mono.Unix {
35 
36 	public sealed /* static */ class UnixEnvironment
37 	{
UnixEnvironment()38 		private UnixEnvironment () {}
39 
40 		public static string CurrentDirectory {
41 			get {
42 				return UnixDirectoryInfo.GetCurrentDirectory ();
43 			}
44 			set {
45 				UnixDirectoryInfo.SetCurrentDirectory (value);
46 			}
47 		}
48 
49 		public static string MachineName {
50 			get {
51 				Native.Utsname buf;
52 				if (Native.Syscall.uname (out buf) != 0)
53 					throw UnixMarshal.CreateExceptionForLastError ();
54 				return buf.nodename;
55 			}
56 			set {
57 				int r = Native.Syscall.sethostname (value);
58 				UnixMarshal.ThrowExceptionForLastErrorIf (r);
59 			}
60 		}
61 
62 		public static string UserName {
63 			get {return UnixUserInfo.GetRealUser ().UserName;}
64 		}
65 
66 		public static UnixGroupInfo RealGroup {
67 			get {return new UnixGroupInfo (RealGroupId);}
68 			// set can't be done as setgid(2) modifies effective gid as well
69 		}
70 
71 		public static long RealGroupId {
72 			get {return Native.Syscall.getgid ();}
73 			// set can't be done as setgid(2) modifies effective gid as well
74 		}
75 
76 		public static UnixUserInfo RealUser {
77 			get {return new UnixUserInfo (RealUserId);}
78 			// set can't be done as setuid(2) modifies effective uid as well
79 		}
80 
81 		public static long RealUserId {
82 			get {return Native.Syscall.getuid ();}
83 			// set can't be done as setuid(2) modifies effective uid as well
84 		}
85 
86 		public static UnixGroupInfo EffectiveGroup {
87 			get {return new UnixGroupInfo (EffectiveGroupId);}
88 			set {EffectiveGroupId = value.GroupId;}
89 		}
90 
91 		public static long EffectiveGroupId {
92 			get {return Native.Syscall.getegid ();}
93 			set {Native.Syscall.setegid (Convert.ToUInt32 (value));}
94 		}
95 
96 		public static UnixUserInfo EffectiveUser {
97 			get {return new UnixUserInfo (EffectiveUserId);}
98 			set {EffectiveUserId = value.UserId;}
99 		}
100 
101 		public static long EffectiveUserId {
102 			get {return Native.Syscall.geteuid ();}
103 			set {Native.Syscall.seteuid (Convert.ToUInt32 (value));}
104 		}
105 
106 		public static string Login {
107 			get {return UnixUserInfo.GetRealUser ().UserName;}
108 		}
109 
110 		[CLSCompliant (false)]
GetConfigurationValue(Native.SysconfName name)111 		public static long GetConfigurationValue (Native.SysconfName name)
112 		{
113 			long r = Native.Syscall.sysconf (name);
114 			if (r == -1 && Native.Stdlib.GetLastError() != (Native.Errno) 0)
115 				UnixMarshal.ThrowExceptionForLastError ();
116 			return r;
117 		}
118 
119 		[CLSCompliant (false)]
GetConfigurationString(Native.ConfstrName name)120 		public static string GetConfigurationString (Native.ConfstrName name)
121 		{
122 			ulong len = Native.Syscall.confstr (name, null, 0);
123 			if (len == unchecked ((ulong) (-1)))
124 				UnixMarshal.ThrowExceptionForLastError ();
125 			if (len == 0)
126 				return "";
127 			StringBuilder buf = new StringBuilder ((int) len+1);
128 			len = Native.Syscall.confstr (name, buf, len);
129 			if (len == unchecked ((ulong) (-1)))
130 				UnixMarshal.ThrowExceptionForLastError ();
131 			return buf.ToString ();
132 		}
133 
SetNiceValue(int inc)134 		public static void SetNiceValue (int inc)
135 		{
136 			int r = Native.Syscall.nice (inc);
137 			UnixMarshal.ThrowExceptionForLastErrorIf (r);
138 		}
139 
CreateSession()140 		public static int CreateSession ()
141 		{
142 			int s = Native.Syscall.setsid ();
143 			UnixMarshal.ThrowExceptionForLastErrorIf (s);
144 			return s;
145 		}
146 
SetProcessGroup()147 		public static void SetProcessGroup ()
148 		{
149 			int r = Native.Syscall.setpgrp ();
150 			UnixMarshal.ThrowExceptionForLastErrorIf (r);
151 		}
152 
GetProcessGroup()153 		public static int GetProcessGroup ()
154 		{
155 			return Native.Syscall.getpgrp ();
156 		}
157 
GetSupplementaryGroups()158 		public static UnixGroupInfo[] GetSupplementaryGroups ()
159 		{
160 			uint[] ids = _GetSupplementaryGroupIds ();
161 			UnixGroupInfo[] groups = new UnixGroupInfo [ids.Length];
162 			for (int i = 0; i < groups.Length; ++i)
163 				groups [i] = new UnixGroupInfo (ids [i]);
164 			return groups;
165 		}
166 
_GetSupplementaryGroupIds()167 		private static uint[] _GetSupplementaryGroupIds ()
168 		{
169 			int ngroups = Native.Syscall.getgroups (0, new uint[]{});
170 			if (ngroups == -1)
171 				UnixMarshal.ThrowExceptionForLastError ();
172 			uint[] groups = new uint[ngroups];
173 			int r = Native.Syscall.getgroups (groups);
174 			UnixMarshal.ThrowExceptionForLastErrorIf (r);
175 			return groups;
176 		}
177 
SetSupplementaryGroups(UnixGroupInfo[] groups)178 		public static void SetSupplementaryGroups (UnixGroupInfo[] groups)
179 		{
180 			uint[] list = new uint [groups.Length];
181 			for (int i = 0; i < list.Length; ++i) {
182 				list [i] = Convert.ToUInt32 (groups [i].GroupId);
183 			}
184 			int r = Native.Syscall.setgroups (list);
185 			UnixMarshal.ThrowExceptionForLastErrorIf (r);
186 		}
187 
GetSupplementaryGroupIds()188 		public static long[] GetSupplementaryGroupIds ()
189 		{
190 			uint[] _groups = _GetSupplementaryGroupIds ();
191 			long[] groups = new long [_groups.Length];
192 			for (int i = 0; i < groups.Length; ++i)
193 				groups [i] = _groups [i];
194 			return groups;
195 		}
196 
SetSupplementaryGroupIds(long[] list)197 		public static void SetSupplementaryGroupIds (long[] list)
198 		{
199 			uint[] _list = new uint [list.Length];
200 			for (int i = 0; i < _list.Length; ++i)
201 				_list [i] = Convert.ToUInt32 (list [i]);
202 			int r = Native.Syscall.setgroups (_list);
203 			UnixMarshal.ThrowExceptionForLastErrorIf (r);
204 		}
205 
GetParentProcessId()206 		public static int GetParentProcessId ()
207 		{
208 			return Native.Syscall.getppid ();
209 		}
210 
GetParentProcess()211 		public static UnixProcess GetParentProcess ()
212 		{
213 			return new UnixProcess (GetParentProcessId ());
214 		}
215 
GetUserShells()216 		public static string[] GetUserShells ()
217 		{
218 			ArrayList shells = new ArrayList ();
219 
220 			lock (Native.Syscall.usershell_lock) {
221 				try {
222 					if (Native.Syscall.setusershell () != 0)
223 						UnixMarshal.ThrowExceptionForLastError ();
224 					string shell;
225 					while ((shell = Native.Syscall.getusershell ()) != null)
226 						shells.Add (shell);
227 				}
228 				finally {
229 					Native.Syscall.endusershell ();
230 				}
231 			}
232 
233 			return (string[]) shells.ToArray (typeof(string));
234 		}
235 	}
236 }
237 
238 // vim: noexpandtab
239