1if not modules then modules = { } end modules ['l-os'] = {
2 version = 1.001,
3 comment = "companion to luat-lib.mkiv",
4 author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5 copyright = "PRAGMA ADE / ConTeXt Development Team",
6 license = "see context related readme files"
7}
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28local os = os
29local date, time, difftime = os.date, os.time, os.difftime
30local find, format, gsub, upper, gmatch = string.find, string.format, string.gsub, string.upper, string.gmatch
31local concat = table.concat
32local random, ceil, randomseed, modf = math.random, math.ceil, math.randomseed, math.modf
33local type, setmetatable, tonumber, tostring = type, setmetatable, tonumber, tostring
34
35
36
37
38do
39
40 local selfdir = os.selfdir
41
42 if selfdir == "" then
43 selfdir = nil
44 end
45
46 if not selfdir then
47
48
49
50 if arg then
51
52 for i=1,#arg do
53 local a = arg[i]
54 if find(a,"^%-%-[c:]*texmfbinpath=") then
55 selfdir = gsub(a,"^.-=","")
56 break
57 end
58 end
59 end
60
61 if not selfdir then
62 selfdir = os.selfbin or "luatex"
63 if find(selfdir,"[/\\]") then
64 selfdir = gsub(selfdir,"[/\\][^/\\]*$","")
65 elseif os.getenv then
66 local path = os.getenv("PATH")
67 local name = gsub(selfdir,"^.*[/\\][^/\\]","")
68 local patt = "[^:]+"
69 if os.type == "windows" then
70 patt = "[^;]+"
71 name = name .. ".exe"
72 end
73 local isfile
74 if lfs then
75
76 local attributes = lfs.attributes
77 isfile = function(name)
78 local a = attributes(name,"mode")
79 return a == "file" or a == "link" or nil
80 end
81 else
82
83 local open = io.open
84 isfile = function(name)
85 local f = open(name)
86 if f then
87 f:close()
88 return true
89 end
90 end
91 end
92 for p in gmatch(path,patt) do
93
94 if isfile(p .. "/" .. name) then
95 selfdir = p
96 break
97 end
98 end
99 end
100 end
101
102
103
104 os.selfdir = selfdir or "."
105
106 end
107
108
109
110end
111
112
113
114
115
116
117
118
119math.initialseed = tonumber(string.sub(string.reverse(tostring(ceil(socket and socket.gettime()*10000 or time()))),1,6))
120
121randomseed(math.initialseed)
122
123if not os.__getenv__ then
124
125 os.__getenv__ = os.getenv
126 os.__setenv__ = os.setenv
127
128 if os.env then
129
130 local osgetenv = os.getenv
131 local ossetenv = os.setenv
132 local osenv = os.env local _ = osenv.PATH
133
134 function os.setenv(k,v)
135 if v == nil then
136 v = ""
137 end
138 local K = upper(k)
139 osenv[K] = v
140 if type(v) == "table" then
141 v = concat(v,";")
142 end
143 ossetenv(K,v)
144 end
145
146 function os.getenv(k)
147 local K = upper(k)
148 local v = osenv[K] or osenv[k] or osgetenv(K) or osgetenv(k)
149 if v == "" then
150 return nil
151 else
152 return v
153 end
154 end
155
156 else
157
158 local ossetenv = os.setenv
159 local osgetenv = os.getenv
160 local osenv = { }
161
162 function os.setenv(k,v)
163 if v == nil then
164 v = ""
165 end
166 local K = upper(k)
167 osenv[K] = v
168 end
169
170 function os.getenv(k)
171 local K = upper(k)
172 local v = osenv[K] or osgetenv(K) or osgetenv(k)
173 if v == "" then
174 return nil
175 else
176 return v
177 end
178 end
179
180 local function __index(t,k)
181 return os.getenv(k)
182 end
183 local function __newindex(t,k,v)
184 os.setenv(k,v)
185 end
186
187 os.env = { }
188
189 setmetatable(os.env, { __index = __index, __newindex = __newindex } )
190
191 end
192
193end
194
195
196
197if not io.fileseparator then
198
199 if find(os.getenv("PATH"),";",1,true) then
200 io.fileseparator, io.pathseparator, os.type = "\\", ";", os.type or "windows"
201 else
202 io.fileseparator, io.pathseparator, os.type = "/" , ":", os.type or "unix"
203 end
204
205end
206
207os.type = os.type or (io.pathseparator == ";" and "windows") or "unix"
208os.name = os.name or (os.type == "windows" and "mswin" ) or "linux"
209
210if os.type == "windows" then
211 os.libsuffix, os.binsuffix, os.binsuffixes = 'dll', 'exe', { 'exe', 'cmd', 'bat' }
212elseif os.name == "macosx" then
213 os.libsuffix, os.binsuffix, os.binsuffixes = 'dylib', '', { '' }
214else
215 os.libsuffix, os.binsuffix, os.binsuffixes = 'so', '', { '' }
216end
217
218do
219
220 local execute = os.execute
221 local iopopen = io.popen
222 local ostype = os.type
223
224 local function resultof(command)
225
226 local handle = iopopen(command,ostype == "windows" and "rb" or "r")
227 if handle then
228 local result = handle:read("*all") or ""
229 handle:close()
230 return result
231 else
232 return ""
233 end
234 end
235
236 os.resultof = resultof
237
238 function os.pipeto(command)
239 return iopopen(command,"w")
240 end
241
242 local launchers = {
243 windows = "start %s",
244 macosx = "open %s",
245 unix = "xdg-open %s &> /dev/null &",
246 }
247
248 function os.launch(str)
249 local command = format(launchers[os.name] or launchers.unix,str)
250
251
252 execute(command)
253 end
254
255end
256
257do
258
259 local gettimeofday = os.gettimeofday or os.clock
260 os.gettimeofday = gettimeofday
261
262 local startuptime = gettimeofday()
263
264 function os.runtime()
265 return gettimeofday() - startuptime
266 end
267
268
269
270
271
272
273
274end
275
276
277
278
279
280
281
282
283
284
285
286
287
288do
289
290 local name = os.name or "linux"
291 local platform = os.getenv("MTX_PLATFORM") or ""
292 local architecture = os.uname and os.uname().machine
293 local bits = os.getenv("MTX_BITS") or find(platform,"64") and 64 or 32
294
295 if platform ~= "" then
296
297
298
299 elseif os.type == "windows" then
300
301
302
303
304 architecture = string.lower(architecture or os.getenv("PROCESSOR_ARCHITECTURE") or "")
305 if architecture == "x86_64" then
306 bits, platform = 64, "win64"
307 elseif find(architecture,"amd64") then
308 bits, platform = 64, "win64"
309 elseif find(architecture,"arm64") then
310 bits, platform = 64, "windows-arm64"
311 elseif find(architecture,"arm32") then
312 bits, platform = 32, "windows-arm32"
313 else
314 bits, platform = 32, "mswin"
315 end
316
317 elseif name == "linux" then
318
319
320
321
322
323
324
325 architecture = architecture or os.getenv("HOSTTYPE") or resultof("uname -m") or ""
326 local musl = find(os.selfdir or "","linuxmusl")
327 if find(architecture,"x86_64") then
328 bits, platform = 64, musl and "linuxmusl" or "linux-64"
329 elseif find(architecture,"ppc") then
330 bits, platform = 32, "linux-ppc"
331 else
332 bits, platform = 32, musl and "linuxmusl" or "linux"
333 end
334
335 elseif name == "macosx" then
336
337
338
339
340
341
342
343
344 architecture = architecture or resultof("echo $HOSTTYPE") or ""
345 if architecture == "" then
346 bits, platform = 64, "osx-intel"
347 elseif find(architecture,"i386") then
348 bits, platform = 64, "osx-intel"
349 elseif find(architecture,"x86_64") then
350 bits, platform = 64, "osx-64"
351 elseif find(architecture,"arm64") then
352 bits, platform = 64, "osx-arm"
353 else
354 bits, platform = 32, "osx-ppc"
355 end
356
357 elseif name == "sunos" then
358
359 architecture = architecture or resultof("uname -m") or ""
360 if find(architecture,"sparc") then
361 bits, platform = 32, "solaris-sparc"
362 else
363 bits, platform = 32, "solaris-intel"
364 end
365
366 elseif name == "freebsd" then
367
368 architecture = architecture or os.getenv("MACHTYPE") or resultof("uname -m") or ""
369 if find(architecture,"amd64") or find(architecture,"AMD64") then
370 bits, platform = 64, "freebsd-amd64"
371 else
372 bits, platform = 32, "freebsd"
373 end
374
375 elseif name == "kfreebsd" then
376
377 architecture = architecture or os.getenv("HOSTTYPE") or resultof("uname -m") or ""
378 if architecture == "x86_64" then
379 bits, platform = 64, "kfreebsd-amd64"
380 else
381 bits, platform = 32, "kfreebsd-i386"
382 end
383
384 else
385
386 architecture = architecture or resultof("uname -m") or ""
387
388 if find(architecture,"aarch64") then
389 bits, platform = "linux-aarch64"
390 elseif find(architecture,"armv7l") then
391
392 bits, platform = 32, "linux-armhf"
393 elseif find(architecture,"mips64") or find(architecture,"mips64el") then
394 bits, platform = 64, "linux-mipsel"
395 elseif find(architecture,"mipsel") or find(architecture,"mips") then
396 bits, platform = 32, "linux-mipsel"
397 else
398 bits, platform = 64, "linux-64"
399 end
400
401 end
402
403 os.setenv("MTX_PLATFORM",platform)
404 os.setenv("MTX_BITS", bits)
405
406 os.platform = platform
407 os.bits = bits
408 os.newline = name == "windows" and "\013\010" or "\010"
409
410end
411
412
413
414
415
416
417
418
419
420
421do
422
423 local t = { 8, 9, "a", "b" }
424
425 function os.uuid()
426 return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
427 random(0xFFFF),random(0xFFFF),
428 random(0x0FFF),
429 t[ceil(random(4))] or 8,random(0x0FFF),
430 random(0xFFFF),
431 random(0xFFFF),random(0xFFFF),random(0xFFFF)
432 )
433 end
434
435end
436
437do
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453 local hour, min
454
455 function os.timezone(difference)
456 if not hour then
457
458 local current = time()
459 local utcdate = date("!*t", current)
460 local localdate = date("*t", current)
461 localdate.isdst = false
462 local timediff = difftime(time(localdate), time(utcdate))
463 hour, min = modf(timediff / 3600)
464 min = min * 60
465 end
466 if difference then
467 return hour, min
468 else
469 return format("%+03d:%02d",hour,min)
470 end
471 end
472
473
474
475 local timeformat = format("%%s%s",os.timezone())
476 local dateformat = "%Y-%m-%d %H:%M:%S"
477 local lasttime = nil
478 local lastdate = nil
479
480 function os.fulltime(t,default)
481 t = t and tonumber(t) or 0
482 if t > 0 then
483
484 elseif default then
485 return default
486 else
487 t = time()
488 end
489 if t ~= lasttime then
490 lasttime = t
491 lastdate = format(timeformat,date(dateformat))
492 end
493 return lastdate
494 end
495
496
497
498 local dateformat = "%Y-%m-%d %H:%M:%S"
499 local lasttime = nil
500 local lastdate = nil
501
502 function os.localtime(t,default)
503 t = t and tonumber(t) or 0
504 if t > 0 then
505
506 elseif default then
507 return default
508 else
509 t = time()
510 end
511 if t ~= lasttime then
512 lasttime = t
513 lastdate = date(dateformat,t)
514 end
515 return lastdate
516 end
517
518 function os.converttime(t,default)
519 local t = tonumber(t)
520 if t and t > 0 then
521 return date(dateformat,t)
522 else
523 return default or "-"
524 end
525 end
526
527
528
529 function os.today()
530 return date("!*t")
531 end
532
533
534
535 function os.now()
536 return date("!%Y-%m-%d %H:%M:%S")
537 end
538
539end
540
541do
542
543 local cache = { }
544
545 local function which(filename)
546 local fullname = cache[filename]
547 if fullname == nil then
548 local suffix = file.suffix(filename)
549 local suffixes = suffix == "" and os.binsuffixes or { suffix }
550 for directory in gmatch(os.getenv("PATH"),"[^" .. io.pathseparator .."]+") do
551 local df = file.join(directory,filename)
552 for i=1,#suffixes do
553 local dfs = file.addsuffix(df,suffixes[i])
554 if io.exists(dfs) then
555 fullname = dfs
556 break
557 end
558 end
559 end
560 if not fullname then
561 fullname = false
562 end
563 cache[filename] = fullname
564 end
565 return fullname
566 end
567
568 os.which = which
569 os.where = which
570
571
572
573
574
575
576end
577
578if not os.sleep then
579
580 local socket = socket
581
582 function os.sleep(n)
583 if not socket then
584
585
586 socket = require("socket")
587 end
588 socket.sleep(n)
589 end
590
591end
592
593
594
595do
596
597 local function isleapyear(year)
598
599 return (year % 4 == 0) and (year % 100 ~= 0 or year % 400 == 0)
600
601 end
602
603 os.isleapyear = isleapyear
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619 local days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
620
621 local function nofdays(year,month,day)
622 if not month then
623 return isleapyear(year) and 365 or 364
624 elseif not day then
625 return month == 2 and isleapyear(year) and 29 or days[month]
626 else
627 for i=1,month-1 do
628 day = day + days[i]
629 end
630 if month > 2 and isleapyear(year) then
631 day = day + 1
632 end
633 return day
634 end
635 end
636
637 os.nofdays = nofdays
638
639 function os.weekday(day,month,year)
640 return date("%w",time { year = year, month = month, day = day }) + 1
641 end
642
643 function os.validdate(year,month,day)
644
645
646 if month < 1 then
647 month = 1
648 elseif month > 12 then
649 month = 12
650 end
651 if day < 1 then
652 day = 1
653 else
654 local max = nofdays(year,month)
655 if day > max then
656 day = max
657 end
658 end
659 return year, month, day
660 end
661
662 function os.date(fmt,...)
663 if not fmt then
664
665 fmt = "%Y-%m-%d %H:%M"
666 end
667 return date(fmt,...)
668 end
669
670end
671
672do
673
674 local osexit = os.exit
675 local exitcode = nil
676
677 function os.setexitcode(code)
678 exitcode = code
679 end
680
681 function os.exit(c)
682 if exitcode ~= nil then
683 return osexit(exitcode)
684 end
685 if c ~= nil then
686 return osexit(c)
687 end
688 return osexit()
689 end
690
691end
692 |