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