Merge pull request #1967 from D-POWER/master
[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                                 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)]
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)]
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
134                 public static void SetNiceValue (int inc)
135                 {
136                         int r = Native.Syscall.nice (inc);
137                         UnixMarshal.ThrowExceptionForLastErrorIf (r);
138                 }
139
140                 public static int CreateSession ()
141                 {
142                         int s = Native.Syscall.setsid ();
143                         UnixMarshal.ThrowExceptionForLastErrorIf (s);
144                         return s;
145                 }
146
147                 public static void SetProcessGroup ()
148                 {
149                         int r = Native.Syscall.setpgrp ();
150                         UnixMarshal.ThrowExceptionForLastErrorIf (r);
151                 }
152
153                 public static int GetProcessGroup ()
154                 {
155                         return Native.Syscall.getpgrp ();
156                 }
157
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
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
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
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
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
206                 public static int GetParentProcessId ()
207                 {
208                         return Native.Syscall.getppid ();
209                 }
210                 
211                 public static UnixProcess GetParentProcess ()
212                 {
213                         return new UnixProcess (GetParentProcessId ());
214                 }
215
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