1
2
3
4
5
6 using System.Collections;
7 using System.IO;
8
9 namespace System.Os
10 {
11 public nothrow void Exit(byte exitCode)
12 {
13 exit(exitCode);
14 }
15
16 public int Fork()
17 {
18 int result = fork();
19 if (result == -1)
20 {
21 ThrowSystemError();
22 }
23 return result;
24 }
25
26 public void Exec(const string& program, const List<string>& args)
27 {
28 Exec(program, args, Environment.Instance());
29 }
30
31 public void Exec(const string& program, const List<string>& args, const Environment& environment)
32 {
33 string prog = program;
34 bool hasExtension = Path.HasExtension(prog);
35 if (!hasExtension)
36 {
37 prog.Append(".x");
38 }
39 long size = prog.Length() + 1 + 16;
40 for (const string& arg : args)
41 {
42 size = size + arg.Length() + 1 + 16;
43 }
44 size = size + 16;
45 size = size + environment.Size();
46 size = size + 16;
47 UniquePtr<byte> block = cast<byte*>(MemAlloc(size));
48 MemoryWriter writer(block.Get(), size);
49 const char** argv = cast<const char**>(cast<void*>(block.Get()));
50 writer.Write(cast<long>(0));
51 for (const string& arg : args)
52 {
53 writer.Write(cast<long>(0));
54 }
55 writer.Write(cast<long>(0));
56 const char** envp = cast<const char**>(cast<void*>(block.Get() + writer.Offset()));
57 for (const Pair<string, string>& v : environment.Variables())
58 {
59 writer.Write(cast<long>(0));
60 }
61 writer.Write(cast<long>(0));
62 List<byte*> addresses;
63 addresses.Add(block.Get() + writer.Offset());
64 writer.Write(prog);
65 for (const string& arg : args)
66 {
67 addresses.Add(block.Get() + writer.Offset());
68 writer.Write(arg);
69 }
70 addresses.Add(null);
71 for (const Pair<string, string>& v : environment.Variables())
72 {
73 string env = v.first;
74 env.Append('=').Append(v.second);
75 addresses.Add(block.Get() + writer.Offset());
76 writer.Write(env);
77 }
78 addresses.Add(null);
79 MemoryWriter headerWriter(block.Get(), size);
80 for (byte* address : addresses)
81 {
82 headerWriter.Write(cast<ulong>(cast<void*>(address)));
83 }
84 int result = exec(prog.Chars(), argv, envp);
85 if (result == -1)
86 {
87 ThrowSystemError();
88 }
89 }
90
91 public int Wait(byte* exitCode)
92 {
93 int result = wait(exitCode);
94 if (result == -1)
95 {
96 SystemError systemError = GetSystemError();
97 if (systemError.errorCode == ENOCHILD)
98 {
99 return -1;
100 }
101 else
102 {
103 throw systemError;
104 }
105 }
106 return result;
107 }
108
109 public int WaitPid(int pid, byte* exitCode)
110 {
111 int result = waitpid(pid, exitCode);
112 if (result == -1)
113 {
114 SystemError systemError = GetSystemError();
115 if (systemError.errorCode == ENOCHILD)
116 {
117 return -1;
118 }
119 else
120 {
121 throw systemError;
122 }
123 }
124 return result;
125 }
126
127 public int GetPid()
128 {
129 int result = getpid();
130 if (result == -1)
131 {
132 ThrowSystemError();
133 }
134 return result;
135 }
136
137 public int Create(const char* path, int mode)
138 {
139 int result = create(path, mode);
140 if (result == -1)
141 {
142 ThrowSystemError();
143 }
144 return result;
145 }
146
147 public int Open(const char* path, OpenFlags flags, int mode)
148 {
149 int result = open(path, flags, mode);
150 if (result == -1)
151 {
152 ThrowSystemError();
153 }
154 return result;
155 }
156
157 public void Close(int fd)
158 {
159 int result = close(fd);
160 if (result == -1)
161 {
162 ThrowSystemError();
163 }
164 }
165
166 public long Read(int fd, void* buffer, long count)
167 {
168 long result = read(fd, buffer, count);
169 if (result == -1)
170 {
171 ThrowSystemError();
172 }
173 return result;
174 }
175
176 public long Write(int fd, void* buffer, long count)
177 {
178 long result = write(fd, buffer, count);
179 if (result == -1)
180 {
181 ThrowSystemError();
182 }
183 return result;
184 }
185
186 public int IOCtl(int fd, IOControlItem item, byte* arg, long argSize)
187 {
188 int result = ioctl(fd, item, arg, argSize);
189 if (result == -1)
190 {
191 ThrowSystemError();
192 }
193 return result;
194 }
195
196 public long Seek(int fd, long pos, Origin origin)
197 {
198 long result = seek(fd, pos, origin);
199 if (result == -1)
200 {
201 ThrowSystemError();
202 }
203 return result;
204 }
205
206 public long Tell(int fd)
207 {
208 long result = tell(fd);
209 if (result == -1)
210 {
211 ThrowSystemError();
212 }
213 return result;
214 }
215
216 public void Unlink(const char* path)
217 {
218 int result = unlink(path);
219 if (result == -1)
220 {
221 ThrowSystemError();
222 }
223 }
224
225 public void GetCWD(char* pathBuf, long bufSize)
226 {
227 int result = getcwd(pathBuf, bufSize);
228 if (result == -1)
229 {
230 ThrowSystemError();
231 }
232 }
233
234 public void ChDir(const char* path)
235 {
236 int result = chdir(path);
237 if (result == -1)
238 {
239 ThrowSystemError();
240 }
241 }
242
243 public void MkDir(const char* path)
244 {
245 MkDir(path, 0);
246 }
247
248 public void MkDir(const char* path, int mode)
249 {
250 int result = mkdir(path, mode);
251 if (result == -1)
252 {
253 ThrowSystemError();
254 }
255 }
256
257 public void UTime(const char* path, byte* timeBuf, long timeBufSize)
258 {
259 int result = utime(path, timeBuf, timeBufSize);
260 if (result == -1)
261 {
262 ThrowSystemError();
263 }
264 }
265
266 public int OpenDir(const char* dirPath)
267 {
268 int result = opendir(dirPath);
269 if (result == -1)
270 {
271 ThrowSystemError();
272 }
273 return result;
274 }
275
276 public void CloseDir(int dfd)
277 {
278 int result = closedir(dfd);
279 if (result == -1)
280 {
281 ThrowSystemError();
282 }
283 }
284
285 public int ReadDir(int dfd, byte* dirEntryBuf, long dirEntryBufSize)
286 {
287 int result = readdir(dfd, dirEntryBuf, dirEntryBufSize);
288 if (result == -1)
289 {
290 ThrowSystemError();
291 }
292 return result;
293 }
294
295 public int OpenResource(const char* resource_name)
296 {
297 int rd = open_resource(resource_name);
298 if (rd == -1)
299 {
300 ThrowSystemError();
301 }
302 return rd;
303 }
304
305 public void CloseResource(int rd)
306 {
307 int result = close_resource(rd);
308 if (result == -1)
309 {
310 ThrowSystemError();
311 }
312 }
313
314 public long GetResourceSize(int rd)
315 {
316 long size = get_resource_size(rd);
317 if (size == -1)
318 {
319 ThrowSystemError();
320 }
321 return size;
322 }
323
324 public void ReadResource(int rd, long offset, long size, byte* buffer)
325 {
326 int result = read_resource(rd, offset, size, buffer);
327 if (result == -1)
328 {
329 ThrowSystemError();
330 }
331 }
332
333 public int Decompress(byte* buffer, long count)
334 {
335 int dd = decompress(buffer, count);
336 if (dd == -1)
337 {
338 ThrowSystemError();
339 }
340 return dd;
341 }
342
343 public long GetDecompressedDataSize(int dd)
344 {
345 long size = get_decompressed_data_size(dd);
346 if (size == -1)
347 {
348 ThrowSystemError();
349 }
350 return size;
351 }
352
353 public void GetDecompressedData(int dd, byte* buffer, long count)
354 {
355 int result = get_decompressed_data(dd, buffer, count);
356 if (result == -1)
357 {
358 ThrowSystemError();
359 }
360 }
361
362 public void CloseDecompression(int dd)
363 {
364 int result = close_decompression(dd);
365 if (result == -1)
366 {
367 ThrowSystemError();
368 }
369 }
370
371 public string GetHostName()
372 {
373 char[256] buffer;
374 int result = get_host_name(&buffer[0], 256);
375 if (result == -1)
376 {
377 ThrowSystemError();
378 }
379 return string(&buffer[0]);
380 }
381
382 public string GetUserName()
383 {
384 char[256] buffer;
385 int result = get_user_name(&buffer[0], 256);
386 if (result == -1)
387 {
388 ThrowSystemError();
389 }
390 return string(&buffer[0]);
391 }
392
393 public void Pipe(int* readerFd, int* writerFd)
394 {
395 int result = pipe(readerFd, writerFd);
396 if (result == -1)
397 {
398 ThrowSystemError();
399 }
400 }
401
402 public int Dup(int fd)
403 {
404 int result = dup(fd);
405 if (result == -1)
406 {
407 ThrowSystemError();
408 }
409 return result;
410 }
411
412 public void SetUID(int uid)
413 {
414 int result = setuid(uid);
415 if (result == -1)
416 {
417 ThrowSystemError();
418 }
419 }
420
421 public void SetGID(int gid)
422 {
423 int result = setgid(gid);
424 if (result == -1)
425 {
426 ThrowSystemError();
427 }
428 }
429
430 public int GetUID()
431 {
432 int result = getuid();
433 if (result == -1)
434 {
435 ThrowSystemError();
436 }
437 return result;
438 }
439
440 public int GetGID()
441 {
442 int result = getgid();
443 if (result == -1)
444 {
445 ThrowSystemError();
446 }
447 return result;
448 }
449
450 public void SetEUID(int euid)
451 {
452 int result = seteuid(euid);
453 if (result == -1)
454 {
455 ThrowSystemError();
456 }
457 }
458
459 public void SetEGID(int egid)
460 {
461 int result = setegid(egid);
462 if (result == -1)
463 {
464 ThrowSystemError();
465 }
466 }
467
468 public int GetEUID()
469 {
470 int result = geteuid();
471 if (result == -1)
472 {
473 ThrowSystemError();
474 }
475 return result;
476 }
477
478 public int GetEGID()
479 {
480 int result = getegid();
481 if (result == -1)
482 {
483 ThrowSystemError();
484 }
485 return result;
486 }
487
488 public int UMask(int mask)
489 {
490 int result = umask(mask);
491 if (result == -1)
492 {
493 ThrowSystemError();
494 }
495 return result;
496 }
497
498 public void ChMod(const char* path, int mode)
499 {
500 int result = chmod(path, mode);
501 if (result == -1)
502 {
503 ThrowSystemError();
504 }
505 }
506
507 public void ChOwn(const char* path, int uid, int gid)
508 {
509 int result = chown(path, uid, gid);
510 if (result == -1)
511 {
512 ThrowSystemError();
513 }
514 }
515
516 public void Rename(const char* source, const char* target)
517 {
518 int result = rename(source, target);
519 if (result == -1)
520 {
521 ThrowSystemError();
522 }
523 }
524
525 public void AddDirChangeNotification(const char* directories)
526 {
527 int result = add_dir_change_notification(directories);
528 if (result == -1)
529 {
530 ThrowSystemError();
531 }
532 }
533
534 public void RemoveDirChangeNotifications()
535 {
536 int result = remove_dir_change_notifications();
537 if (result == -1)
538 {
539 ThrowSystemError();
540 }
541 }
542
543 public bool DirectoriesChanged()
544 {
545 int result = directories_changed();
546 if (result == -1)
547 {
548 ThrowSystemError();
549 }
550 return result == 1;
551 }
552
553 public void ClearDirectoriesChanged()
554 {
555 int result = clear_directories_changed();
556 if (result == -1)
557 {
558 ThrowSystemError();
559 }
560 }
561
562 public int MsgQ(const char* name)
563 {
564 int result = msgq(name);
565 if (result == -1)
566 {
567 ThrowSystemError();
568 }
569 return result;
570 }
571
572 public void CloseMsgQ(int md)
573 {
574 int result = close_msgq(md);
575 if (result == -1)
576 {
577 ThrowSystemError();
578 }
579 }
580
581 public void WaitMsg(int md)
582 {
583 int result = wait_msg(md);
584 if (result == -1)
585 {
586 ThrowSystemError();
587 }
588 }
589
590 public void PutMsg(int md, byte* msgData, int msgSize)
591 {
592 int result = put_msg(md, msgData, msgSize);
593 if (result == -1)
594 {
595 ThrowSystemError();
596 }
597 }
598
599 public int GetMsgQLength(int md)
600 {
601 int result = get_msgq_length(md);
602 if (result == -1)
603 {
604 ThrowSystemError();
605 }
606 return result;
607 }
608
609 public int GetMsgSize(int md)
610 {
611 int result = get_msg_size(md);
612 if (result == -1)
613 {
614 ThrowSystemError();
615 }
616 return result;
617 }
618
619 public void GetMsg(int md, byte* buffer)
620 {
621 int result = get_msg(md, buffer);
622 if (result == -1)
623 {
624 ThrowSystemError();
625 }
626 }
627
628 public void BindTerminal(int md)
629 {
630 int result = bind_terminal(md);
631 if (result == -1)
632 {
633 ThrowSystemError();
634 }
635 }
636
637 public void UnbindTerminal()
638 {
639 int result = unbind_terminal();
640 if (result == -1)
641 {
642 ThrowSystemError();
643 }
644 }
645
646 public void Tab(int fd, int putTabMsgQ, int getTabMsgQ)
647 {
648 byte[8] arg;
649 MemoryWriter writer(&arg[0], 8);
650 writer.Write(putTabMsgQ);
651 writer.Write(getTabMsgQ);
652 IOCtl(fd, IOControlItem.tab, &arg[0], 8);
653 }
654
655 public void Untab(int fd)
656 {
657 IOCtl(fd, IOControlItem.untab, null, 0);
658 }
659
660 public void PushPid(int fd, int pid)
661 {
662 byte[4] arg;
663 MemoryWriter writer(&arg[0], 4);
664 writer.Write(pid);
665 IOCtl(fd, IOControlItem.push_pid, &arg[0], 4);
666 }
667
668 public void PopPid(int fd)
669 {
670 IOCtl(fd, IOControlItem.pop_pid, null, 0);
671 }
672
673 public void TimerMsg(const Duration& duration, int md, byte* msgData, int msgSize)
674 {
675 int result = timer_msg(duration.Rep(), md, msgData, msgSize);
676 if (result == -1)
677 {
678 ThrowSystemError();
679 }
680 }
681
682 public int Connect(const char* node, const char* service)
683 {
684 int result = connect(node, service);
685 if (result == -1)
686 {
687 ThrowSystemError();
688 }
689 return result;
690 }
691
692 public void Kill(int pid)
693 {
694 int result = kill(pid);
695 if (result == -1)
696 {
697 ThrowSystemError();
698 }
699 }
700 }