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 ' }
212else
213 os . libsuffix , os . binsuffix , os . binsuffixes = ' so ' , ' ' , { ' ' }
214end
215
216do
217
218 local execute = os . execute
219 local iopopen = io . popen
220 local ostype = os . type
221
222 local function resultof ( command )
223
224 local handle = iopopen ( command , ostype = = " windows " and " rb " or " r " )
225 if handle then
226 local result = handle : read ( " *all " ) or " "
227 handle : close ( )
228 return result
229 else
230 return " "
231 end
232 end
233
234 os . resultof = resultof
235
236 function os . pipeto ( command )
237 return iopopen ( command , " w " )
238 end
239
240 local launchers = {
241 windows = " start %s " ,
242 macosx = " open %s " ,
243 unix = " xdg-open %s &> /dev/null & " ,
244 }
245
246 function os . launch ( str )
247 local command = format ( launchers [ os . name ] or launchers . unix , str )
248
249
250 execute ( command )
251 end
252
253end
254
255do
256
257 local gettimeofday = os . gettimeofday or os . clock
258 os . gettimeofday = gettimeofday
259
260 local startuptime = gettimeofday ( )
261
262 function os . runtime ( )
263 return gettimeofday ( ) - startuptime
264 end
265
266
267
268
269
270
271
272end
273
274
275
276
277
278
279
280
281
282
283
284
285
286do
287
288 local name = os . name or " linux "
289 local platform = os . getenv ( " MTX_PLATFORM " ) or " "
290 local architecture = os . uname and os . uname ( ) . machine
291 local bits = os . getenv ( " MTX_BITS " ) or find ( platform , " 64 " ) and 64 or 32
292
293 if platform ~ = " " then
294
295
296
297 elseif os . type = = " windows " then
298
299
300
301
302 architecture = string . lower ( architecture or os . getenv ( " PROCESSOR_ARCHITECTURE " ) or " " )
303 if architecture = = " x86_64 " then
304 bits , platform = 64 , " win64 "
305 elseif find ( architecture , " amd64 " ) then
306 bits , platform = 64 , " win64 "
307 elseif find ( architecture , " arm64 " ) then
308 bits , platform = 64 , " windows-arm64 "
309 elseif find ( architecture , " arm32 " ) then
310 bits , platform = 32 , " windows-arm32 "
311 else
312 bits , platform = 32 , " mswin "
313 end
314
315 elseif name = = " linux " then
316
317
318
319
320
321
322
323 architecture = architecture or os . getenv ( " HOSTTYPE " ) or resultof ( " uname -m " ) or " "
324 local musl = find ( os . selfdir or " " , " linuxmusl " )
325 if find ( architecture , " x86_64 " ) then
326 bits , platform = 64 , musl and " linuxmusl " or " linux-64 "
327 elseif find ( architecture , " ppc " ) then
328 bits , platform = 32 , " linux-ppc "
329 else
330 bits , platform = 32 , musl and " linuxmusl " or " linux "
331 end
332
333 elseif name = = " macosx " then
334
335
336
337
338
339
340
341
342 architecture = architecture or resultof ( " echo $HOSTTYPE " ) or " "
343 if architecture = = " " then
344 bits , platform = 64 , " osx-intel "
345 elseif find ( architecture , " i386 " ) then
346 bits , platform = 64 , " osx-intel "
347 elseif find ( architecture , " x86_64 " ) then
348 bits , platform = 64 , " osx-64 "
349 elseif find ( architecture , " arm64 " ) then
350 bits , platform = 64 , " osx-arm "
351 else
352 bits , platform = 32 , " osx-ppc "
353 end
354
355 elseif name = = " sunos " then
356
357 architecture = architecture or resultof ( " uname -m " ) or " "
358 if find ( architecture , " sparc " ) then
359 bits , platform = 32 , " solaris-sparc "
360 else
361 bits , platform = 32 , " solaris-intel "
362 end
363
364 elseif name = = " freebsd " then
365
366 architecture = architecture or os . getenv ( " MACHTYPE " ) or resultof ( " uname -m " ) or " "
367 if find ( architecture , " amd64 " ) or find ( architecture , " AMD64 " ) then
368 bits , platform = 64 , " freebsd-amd64 "
369 else
370 bits , platform = 32 , " freebsd "
371 end
372
373 elseif name = = " kfreebsd " then
374
375 architecture = architecture or os . getenv ( " HOSTTYPE " ) or resultof ( " uname -m " ) or " "
376 if architecture = = " x86_64 " then
377 bits , platform = 64 , " kfreebsd-amd64 "
378 else
379 bits , platform = 32 , " kfreebsd-i386 "
380 end
381
382 else
383
384 architecture = architecture or resultof ( " uname -m " ) or " "
385
386 if find ( architecture , " aarch64 " ) then
387 bits , platform = " linux-aarch64 "
388 elseif find ( architecture , " armv7l " ) then
389
390 bits , platform = 32 , " linux-armhf "
391 elseif find ( architecture , " mips64 " ) or find ( architecture , " mips64el " ) then
392 bits , platform = 64 , " linux-mipsel "
393 elseif find ( architecture , " mipsel " ) or find ( architecture , " mips " ) then
394 bits , platform = 32 , " linux-mipsel "
395 else
396 bits , platform = 64 , " linux-64 "
397 end
398
399 end
400
401 os . setenv ( " MTX_PLATFORM " , platform )
402 os . setenv ( " MTX_BITS " , bits )
403
404 os . platform = platform
405 os . bits = bits
406 os . newline = name = = " windows " and " \013\010 " or " \010 "
407
408end
409
410
411
412
413
414
415
416
417
418
419do
420
421 local t = { 8 , 9 , " a " , " b " }
422
423 function os . uuid ( )
424 return format ( " %04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x " ,
425 random ( 0xFFFF ) , random ( 0xFFFF ) ,
426 random ( 0x0FFF ) ,
427 t [ ceil ( random ( 4 ) ) ] or 8 , random ( 0x0FFF ) ,
428 random ( 0xFFFF ) ,
429 random ( 0xFFFF ) , random ( 0xFFFF ) , random ( 0xFFFF )
430 )
431 end
432
433end
434
435do
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451 local hour , min
452
453 function os . timezone ( difference )
454 if not hour then
455
456 local current = time ( )
457 local utcdate = date ( " !*t " , current )
458 local localdate = date ( " *t " , current )
459 localdate . isdst = false
460 local timediff = difftime ( time ( localdate ) , time ( utcdate ) )
461 hour , min = modf ( timediff / 3600 )
462 min = min * 60
463 end
464 if difference then
465 return hour , min
466 else
467 return format ( " %+03d:%02d " , hour , min )
468 end
469 end
470
471
472
473 local timeformat = format ( " %%s%s " , os . timezone ( ) )
474 local dateformat = " %Y-%m-%d %H:%M:%S "
475 local lasttime = nil
476 local lastdate = nil
477
478 function os . fulltime ( t , default )
479 t = t and tonumber ( t ) or 0
480 if t > 0 then
481
482 elseif default then
483 return default
484 else
485 t = time ( )
486 end
487 if t ~ = lasttime then
488 lasttime = t
489 lastdate = format ( timeformat , date ( dateformat ) )
490 end
491 return lastdate
492 end
493
494
495
496 local dateformat = " %Y-%m-%d %H:%M:%S "
497 local lasttime = nil
498 local lastdate = nil
499
500 function os . localtime ( t , default )
501 t = t and tonumber ( t ) or 0
502 if t > 0 then
503
504 elseif default then
505 return default
506 else
507 t = time ( )
508 end
509 if t ~ = lasttime then
510 lasttime = t
511 lastdate = date ( dateformat , t )
512 end
513 return lastdate
514 end
515
516 function os . converttime ( t , default )
517 local t = tonumber ( t )
518 if t and t > 0 then
519 return date ( dateformat , t )
520 else
521 return default or " - "
522 end
523 end
524
525
526
527 function os . today ( )
528 return date ( " !*t " )
529 end
530
531
532
533 function os . now ( )
534 return date ( " !%Y-%m-%d %H:%M:%S " )
535 end
536
537end
538
539do
540
541 local cache = { }
542
543 local function which ( filename )
544 local fullname = cache [ filename ]
545 if fullname = = nil then
546 local suffix = file . suffix ( filename )
547 local suffixes = suffix = = " " and os . binsuffixes or { suffix }
548 for directory in gmatch ( os . getenv ( " PATH " ) , " [^ " . . io . pathseparator . . " ]+ " ) do
549 local df = file . join ( directory , filename )
550 for i = 1 , # suffixes do
551 local dfs = file . addsuffix ( df , suffixes [ i ] )
552 if io . exists ( dfs ) then
553 fullname = dfs
554 break
555 end
556 end
557 end
558 if not fullname then
559 fullname = false
560 end
561 cache [ filename ] = fullname
562 end
563 return fullname
564 end
565
566 os . which = which
567 os . where = which
568
569
570
571
572
573
574end
575
576if not os . sleep then
577
578 local socket = socket
579
580 function os . sleep ( n )
581 if not socket then
582
583
584 socket = require ( " socket " )
585 end
586 socket . sleep ( n )
587 end
588
589end
590
591
592
593do
594
595 local function isleapyear ( year )
596
597 return ( year % 4 = = 0 ) and ( year % 100 ~ = 0 or year % 400 = = 0 )
598
599 end
600
601 os . isleapyear = isleapyear
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617 local days = { 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 }
618
619 local function nofdays ( year , month , day )
620 if not month then
621 return isleapyear ( year ) and 365 or 364
622 elseif not day then
623 return month = = 2 and isleapyear ( year ) and 29 or days [ month ]
624 else
625 for i = 1 , month -1 do
626 day = day + days [ i ]
627 end
628 if month > 2 and isleapyear ( year ) then
629 day = day + 1
630 end
631 return day
632 end
633 end
634
635 os . nofdays = nofdays
636
637 function os . weekday ( day , month , year )
638 return date ( " %w " , time { year = year , month = month , day = day } ) + 1
639 end
640
641 function os . validdate ( year , month , day )
642
643
644 if month < 1 then
645 month = 1
646 elseif month > 12 then
647 month = 12
648 end
649 if day < 1 then
650 day = 1
651 else
652 local max = nofdays ( year , month )
653 if day > max then
654 day = max
655 end
656 end
657 return year , month , day
658 end
659
660 function os . date ( fmt , ... )
661 if not fmt then
662
663 fmt = " %Y-%m-%d %H:%M "
664 end
665 return date ( fmt , ... )
666 end
667
668end
669
670do
671
672 local osexit = os . exit
673 local exitcode = nil
674
675 function os . setexitcode ( code )
676 exitcode = code
677 end
678
679 function os . exit ( c )
680 if exitcode ~ = nil then
681 return osexit ( exitcode )
682 end
683 if c ~ = nil then
684 return osexit ( c )
685 end
686 return osexit ( )
687 end
688
689end
690 |