1 // =================================
  2 // Copyright (c) 2022 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 using System;
  7 using System.Collections;
  8 using System.Os;
  9 using paths;
 10 
 11 void PrintHelp()
 12 {
 13     Console.Out() << "time [options] COMMAND [ARGS...]" << endl() << endl();
 14     Console.Out() << "Prints command execution times to standard output." << endl() << endl();
 15     Console.Out() << "Options:" << endl() << endl();
 16     Console.Out() << "--help | -h" << endl();
 17     Console.Out() << "  Print help and exit." << endl() << endl();
 18 }
 19 
 20 int main(int argcconst char** argv)
 21 {
 22     try
 23     {
 24         List<string> args;
 25         bool programSeen = false;
 26         for (int i = 1; i < argc; ++i;)
 27         {
 28             string arg = argv[i];
 29             if (!programSeen)
 30             {
 31                 if (arg.StartsWith("--"))
 32                 {
 33                     if (arg == "--help")
 34                     {
 35                         PrintHelp();
 36                         return 1;
 37                     }
 38                     else
 39                     {
 40                         throw Exception("unknown option '" + arg + "'");
 41                     }
 42                 }
 43                 else if (arg.StartsWith("-"))
 44                 {
 45                     string options = arg.Substring(1);
 46                     if (options.IsEmpty())
 47                     {
 48                         throw Exception("unknown argument '" + arg + "'");
 49                     }
 50                     else
 51                     {
 52                         bool unknown = false;
 53                         string uo;
 54                         for (char o : options)
 55                         {
 56                             switch (o)
 57                             {
 58                                 case 'h':
 59                                 {
 60                                     PrintHelp();
 61                                     return 1;
 62                                 }
 63                                 default:
 64                                 {
 65                                     unknown = true;
 66                                     uo.Append(o);
 67                                     break;
 68                                 }
 69                             }
 70                             if (unknown)
 71                             {
 72                                 throw Exception("unknown option '-" + uo + "'");
 73                             }
 74                         }
 75                     }
 76                 }
 77                 else
 78                 {
 79                     programSeen = true;
 80                     args.Add(arg);
 81                 }
 82             }
 83             else
 84             {
 85                 args.Add(arg);
 86             }
 87         }
 88         if (args.IsEmpty())
 89         {
 90             throw Exception("no program to execute");
 91         }
 92         int pid = Fork();
 93         if (pid == 0)
 94         {
 95             string program = GetProgramFilePath(args[0]);
 96             List<string> progArgs;
 97             for (int i = 1; i < args.Count(); ++i;)
 98             {
 99                 progArgs.Add(args[i]);
100             }
101             Exec(programprogArgs);
102         }
103         else
104         {
105             byte exitCode = 0u;
106             if (Wait(&exitCode) != -1)
107             {
108                 Duration userTime;
109                 Duration sleepTime;
110                 Duration systemTime;
111                 ChildTimes(userTimesleepTimesystemTime);
112                 string tms = "Process " + ToString(pid) + ":\nuser time:   " + DurationStr(userTime) + "\nsleep time:  " + DurationStr(sleepTime) + "\nsystem time: " + DurationStr(systemTime) + "\n";
113                 Console.Out() << tms << endl();
114             }
115             else
116             {
117                 throw Exception("error executing '" + args[0] + "'");
118             }
119         }
120     }
121     catch (const Exception& ex)
122     {
123         Console.Error() << ex.ToString() << endl();
124         return 1;
125     }
126     return 0;
127 }