merge from trunk revisions 58933, 58935, 58936
[mono.git] / mcs / class / Mono.Posix / Mono.Unix / UnixEnvironment.cs
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         {
38                 private UnixEnvironment () {}
39
40                 public static string CurrentDirectory {
41                         get {
42                                 return UnixDirectory.GetCurrentDirectory ();
43                         }
44                         set {
45                                 UnixDirectory.SetCurrentDirectory (value);
46                         }
47                 }
48
49                 public static string MachineName {
50                         get {
51                                 StringBuilder buf = new StringBuilder (8);
52                                 int r = 0;
53                                 Error e = (Error) 0;
54                                 do {
55                                         buf.Capacity *= 2;
56                                         r = Syscall.gethostname (buf);
57                                 } while (r == (-1) && ((e = Syscall.GetLastError()) == Error.EINVAL) || 
58                                                 (e == Error.ENAMETOOLONG));
59                                 if (r == (-1))
60                                         UnixMarshal.ThrowExceptionForLastError ();
61                                 return buf.ToString ();
62                         }
63                         set {
64                                 Syscall.sethostname (value);
65                         }
66                 }
67
68                 [CLSCompliant (false)]
69                 [Obsolete ("Use RealUserId")]
70                 public static uint User {
71                         get {return UnixUser.GetCurrentUserId ();}
72                 }
73
74                 [CLSCompliant (false)]
75                 [Obsolete ("Use RealUserId")]
76                 public static uint UserId {
77                         get {return UnixUser.GetCurrentUserId ();}
78                 }
79
80                 public static string UserName {
81                         get {return UnixUser.GetCurrentUserName();}
82                 }
83
84                 public static UnixGroupInfo RealGroup {
85                         get {return new UnixGroupInfo (RealGroupId);}
86                         // set can't be done as setgid(2) modifies effective gid as well
87                 }
88
89                 public static long RealGroupId {
90                         get {return Native.Syscall.getgid ();}
91                         // set can't be done as setgid(2) modifies effective gid as well
92                 }
93
94                 public static UnixUserInfo RealUser {
95                         get {return new UnixUserInfo (RealUserId);}
96                         // set can't be done as setuid(2) modifies effective uid as well
97                 }
98
99                 public static long RealUserId {
100                         get {return Native.Syscall.getuid ();}
101                         // set can't be done as setuid(2) modifies effective uid as well
102                 }
103
104                 public static UnixGroupInfo EffectiveGroup {
105                         get {return new UnixGroupInfo (EffectiveGroupId);}
106                         set {EffectiveGroupId = value.GroupId;}
107                 }
108
109                 public static long EffectiveGroupId {
110                         get {return Native.Syscall.getegid ();}
111                         set {Native.Syscall.setegid (Convert.ToUInt32 (value));}
112                 }
113
114                 public static UnixUserInfo EffectiveUser {
115                         get {return new UnixUserInfo (EffectiveUserId);}
116                         set {EffectiveUserId = value.UserId;}
117                 }
118
119                 public static long EffectiveUserId {
120                         get {return Native.Syscall.geteuid ();}
121                         set {Native.Syscall.seteuid (Convert.ToUInt32 (value));}
122                 }
123
124                 public static string Login {
125                         get {return UnixUser.GetLogin ();}
126                 }
127
128                 [CLSCompliant (false)]
129                 [Obsolete ("Use GetConfigurationValue (Mono.Unix.Native.SysconfName)")]
130                 public static long GetConfigurationValue (SysConf name)
131                 {
132                         long r = Syscall.sysconf (name);
133                         if (r == -1 && Syscall.GetLastError() == Error.EINVAL)
134                                 UnixMarshal.ThrowExceptionForLastError ();
135                         return r;
136                 }
137
138                 [CLSCompliant (false)]
139                 public static long GetConfigurationValue (Native.SysconfName name)
140                 {
141                         long r = Native.Syscall.sysconf (name);
142                         if (r == -1 && Native.Stdlib.GetLastError() == Native.Errno.EINVAL)
143                                 UnixMarshal.ThrowExceptionForLastError ();
144                         return r;
145                 }
146
147                 [CLSCompliant (false)]
148                 [Obsolete ("Use GetConfigurationString (Mono.Unix.Native.ConfstrName)")]
149                 public static string GetConfigurationString (ConfStr name)
150                 {
151                         ulong len = Syscall.confstr (name, null, 0);
152                         if (len == 0)
153                                 return "";
154                         StringBuilder buf = new StringBuilder ((int) len+1);
155                         len = Syscall.confstr (name, buf, len);
156                         return buf.ToString ();
157                 }
158
159                 [CLSCompliant (false)]
160                 public static string GetConfigurationString (Native.ConfstrName name)
161                 {
162                         ulong len = Native.Syscall.confstr (name, null, 0);
163                         if (len == 0)
164                                 return "";
165                         StringBuilder buf = new StringBuilder ((int) len+1);
166                         len = Native.Syscall.confstr (name, buf, len);
167                         return buf.ToString ();
168                 }
169
170                 public static void SetNiceValue (int inc)
171                 {
172                         int r = Syscall.nice (inc);
173                         UnixMarshal.ThrowExceptionForLastErrorIf (r);
174                 }
175
176                 public static int CreateSession ()
177                 {
178                         return Syscall.setsid ();
179                 }
180
181                 public static void SetProcessGroup ()
182                 {
183                         int r = Syscall.setpgrp ();
184                         UnixMarshal.ThrowExceptionForLastErrorIf (r);
185                 }
186
187                 public static int GetProcessGroup ()
188                 {
189                         return Syscall.getpgrp ();
190                 }
191
192                 [CLSCompliant (false)]
193                 [Obsolete ("Use GetSupplementaryGroupIds.  " +
194                                 "The return type will change to UnixGroupInfo[] in the next release.")]
195                 public static uint[] GetSupplementaryGroups ()
196                 {
197                         return GetSupplementaryGroupIds ();
198                 }
199
200                 [CLSCompliant (false)]
201                 [Obsolete ("The return type will change to Int64[] in the next release")]
202                 public static uint[] GetSupplementaryGroupIds ()
203                 {
204                         int ngroups = Syscall.getgroups (0, new uint[]{});
205                         if (ngroups == -1)
206                                 UnixMarshal.ThrowExceptionForLastError ();
207                         uint[] groups = new uint[ngroups];
208                         int r = Syscall.getgroups (groups);
209                         UnixMarshal.ThrowExceptionForLastErrorIf (r);
210                         return groups;
211                 }
212
213                 [CLSCompliant (false)]
214                 [Obsolete ("Use SetSupplementaryGroupIds(long[])")]
215                 public static void SetSupplementaryGroups (uint[] list)
216                 {
217                         SetSupplementaryGroupIds (list);
218                 }
219
220                 [CLSCompliant (false)]
221                 [Obsolete ("Use SetSupplementaryGroupIds(long[])")]
222                 public static void SetSupplementaryGroupIds (uint[] list)
223                 {
224                         int r = Syscall.setgroups (list);
225                         UnixMarshal.ThrowExceptionForLastErrorIf (r);
226                 }
227
228                 public static void SetSupplementaryGroupIds (long[] list)
229                 {
230                         uint[] _list = new uint [list.Length];
231                         for (int i = 0; i < _list.Length; ++i)
232                                 _list [i] = Convert.ToUInt32 (list [i]);
233                         int r = Syscall.setgroups (_list);
234                         UnixMarshal.ThrowExceptionForLastErrorIf (r);
235                 }
236
237                 public static int GetParentProcessId ()
238                 {
239                         return Syscall.getppid ();
240                 }
241                 
242                 public static UnixProcess GetParentProcess ()
243                 {
244                         return new UnixProcess (GetParentProcessId ());
245                 }
246
247                 public static string[] GetUserShells ()
248                 {
249                         ArrayList shells = new ArrayList ();
250
251                         lock (Syscall.usershell_lock) {
252                                 try {
253                                         if (Native.Syscall.setusershell () != 0)
254                                                 UnixMarshal.ThrowExceptionForLastError ();
255                                         string shell;
256                                         while ((shell = Native.Syscall.getusershell ()) != null)
257                                                 shells.Add (shell);
258                                 }
259                                 finally {
260                                         Native.Syscall.endusershell ();
261                                 }
262                         }
263
264                         return (string[]) shells.ToArray (typeof(string));
265                 }
266         }
267 }
268
269 // vim: noexpandtab