1 /*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include "errno.h"
33 #include "unistd.h"
34 #include "limits.h"
35 #include "utime.h"
36 #include "time.h"
37 #include "user_copy.h"
38 #include "sys/times.h"
39 #include "los_signal.h"
40 #include "los_memory.h"
41 #include "los_strncpy_from_user.h"
42 #include "time_posix.h"
43
44 #ifdef LOSCFG_FS_VFS
SysUtime(const char * path,const struct utimbuf * ptimes)45 int SysUtime(const char *path, const struct utimbuf *ptimes)
46 {
47 int ret;
48 char *spath = NULL;
49 struct utimbuf sptimes;
50
51 if (path == NULL) {
52 errno = EINVAL;
53 return -EINVAL;
54 }
55
56 spath = LOS_MemAlloc(m_aucSysMem0, PATH_MAX + 1);
57 if (spath == NULL) {
58 errno = ENOMEM;
59 return -ENOMEM;
60 }
61
62 ret = LOS_StrncpyFromUser(spath, path, PATH_MAX + 1);
63 if (ret == -EFAULT) {
64 LOS_MemFree(m_aucSysMem0, spath);
65 return ret;
66 } else if (ret > PATH_MAX) {
67 LOS_MemFree(m_aucSysMem0, spath);
68 PRINT_ERR("%s[%d], path exceeds maxlen: %d\n", __FUNCTION__, __LINE__, PATH_MAX);
69 return -ENAMETOOLONG;
70 }
71 spath[ret] = '\0';
72
73 if (ptimes && LOS_ArchCopyFromUser(&sptimes, ptimes, sizeof(struct utimbuf))) {
74 LOS_MemFree(m_aucSysMem0, spath);
75 errno = EFAULT;
76 return -EFAULT;
77 }
78
79 ret = utime(spath, ptimes ? &sptimes : NULL);
80 if (ret < 0) {
81 ret = -get_errno();
82 }
83
84 LOS_MemFree(m_aucSysMem0, spath);
85
86 return ret;
87 }
88 #endif
89
SysTime(time_t * tloc)90 time_t SysTime(time_t *tloc)
91 {
92 int ret;
93 time_t stloc;
94
95 ret = time(tloc ? &stloc : NULL);
96 if (ret < 0) {
97 return -get_errno();
98 }
99
100 if (tloc && LOS_ArchCopyToUser(tloc, &stloc, sizeof(time_t))) {
101 errno = EFAULT;
102 ret = -EFAULT;
103 }
104
105 return ret;
106 }
107
SysSetiTimer(int which,const struct itimerval * value,struct itimerval * ovalue)108 int SysSetiTimer(int which, const struct itimerval *value, struct itimerval *ovalue)
109 {
110 int ret;
111 struct itimerval svalue;
112 struct itimerval sovalue = { 0 };
113
114 if (value == NULL) {
115 errno = EINVAL;
116 return -EINVAL;
117 }
118
119 if (LOS_ArchCopyFromUser(&svalue, value, sizeof(struct itimerval))) {
120 errno = EFAULT;
121 return -EFAULT;
122 }
123
124 ret = setitimer(which, &svalue, &sovalue);
125 if (ret < 0) {
126 return -get_errno();
127 }
128
129 if (ovalue && LOS_ArchCopyToUser(ovalue, &sovalue, sizeof(struct itimerval))) {
130 errno = EFAULT;
131 return -EFAULT;
132 }
133
134 return ret;
135 }
136
SysGetiTimer(int which,struct itimerval * value)137 int SysGetiTimer(int which, struct itimerval *value)
138 {
139 int ret;
140 struct itimerval svalue = { 0 };
141
142 if (value == NULL) {
143 errno = EINVAL;
144 return -EINVAL;
145 }
146
147 ret = getitimer(which, &svalue);
148 if (ret < 0) {
149 return -get_errno();
150 }
151
152 if (LOS_ArchCopyToUser(value, &svalue, sizeof(struct itimerval))) {
153 errno = EFAULT;
154 return -EFAULT;
155 }
156
157 return ret;
158 }
159
SysTimerCreate(clockid_t clockID,struct ksigevent * evp,timer_t * timerID)160 int SysTimerCreate(clockid_t clockID, struct ksigevent *evp, timer_t *timerID)
161 {
162 int ret;
163 timer_t stimerID;
164 struct ksigevent ksevp;
165
166 if (timerID == NULL) {
167 errno = EINVAL;
168 return -EINVAL;
169 }
170
171 if (evp && LOS_ArchCopyFromUser(&ksevp, evp, sizeof(struct ksigevent))) {
172 errno = EFAULT;
173 return -EFAULT;
174 }
175
176 ret = OsTimerCreate(clockID, evp ? &ksevp : NULL, &stimerID);
177 if (ret < 0) {
178 return -get_errno();
179 }
180
181 if (LOS_ArchCopyToUser(timerID, &stimerID, sizeof(timer_t))) {
182 errno = EFAULT;
183 return -EFAULT;
184 }
185
186 return ret;
187 }
188
SysTimerGettime(timer_t timerID,struct itimerspec * value)189 int SysTimerGettime(timer_t timerID, struct itimerspec *value)
190 {
191 int ret;
192 struct itimerspec svalue = { 0 };
193
194 if (value == NULL) {
195 errno = EINVAL;
196 return -EINVAL;
197 }
198
199 ret = timer_gettime(timerID, &svalue);
200 if (ret < 0) {
201 return -get_errno();
202 }
203
204 if (LOS_ArchCopyToUser(value, &svalue, sizeof(struct itimerspec))) {
205 errno = EFAULT;
206 return -EFAULT;
207 }
208
209 return ret;
210 }
211
SysTimerSettime(timer_t timerID,int flags,const struct itimerspec * value,struct itimerspec * oldValue)212 int SysTimerSettime(timer_t timerID, int flags, const struct itimerspec *value, struct itimerspec *oldValue)
213 {
214 int ret;
215 struct itimerspec svalue;
216 struct itimerspec soldValue = { 0 };
217
218 if (value == NULL) {
219 errno = EINVAL;
220 return -EINVAL;
221 }
222
223 if (LOS_ArchCopyFromUser(&svalue, value, sizeof(struct itimerspec))) {
224 errno = EFAULT;
225 return -EFAULT;
226 }
227
228 ret = timer_settime(timerID, flags, &svalue, &soldValue);
229 if (ret < 0) {
230 return -get_errno();
231 }
232
233 if (oldValue && LOS_ArchCopyToUser(oldValue, &soldValue, sizeof(struct itimerspec))) {
234 errno = EFAULT;
235 return -EFAULT;
236 }
237
238 return ret;
239 }
240
SysTimerGetoverrun(timer_t timerID)241 int SysTimerGetoverrun(timer_t timerID)
242 {
243 int ret;
244
245 ret = timer_getoverrun(timerID);
246 if (ret < 0) {
247 return -get_errno();
248 }
249 return ret;
250 }
251
SysTimerDelete(timer_t timerID)252 int SysTimerDelete(timer_t timerID)
253 {
254 int ret;
255
256 ret = timer_delete(timerID);
257 if (ret < 0) {
258 return -get_errno();
259 }
260 return ret;
261 }
262
SysClockSettime(clockid_t clockID,const struct timespec * tp)263 int SysClockSettime(clockid_t clockID, const struct timespec *tp)
264 {
265 int ret;
266 struct timespec stp;
267
268 if (tp == NULL) {
269 errno = EINVAL;
270 return -EINVAL;
271 }
272
273 if (LOS_ArchCopyFromUser(&stp, tp, sizeof(struct timespec))) {
274 errno = EFAULT;
275 return -EFAULT;
276 }
277
278 ret = clock_settime(clockID, &stp);
279 if (ret < 0) {
280 return -get_errno();
281 }
282 return ret;
283 }
284
SysClockGettime(clockid_t clockID,struct timespec * tp)285 int SysClockGettime(clockid_t clockID, struct timespec *tp)
286 {
287 int ret;
288 struct timespec stp = { 0 };
289
290 if (tp == NULL) {
291 errno = EINVAL;
292 return -EINVAL;
293 }
294
295 ret = clock_gettime(clockID, &stp);
296 if (ret < 0) {
297 return -get_errno();
298 }
299
300 if (LOS_ArchCopyToUser(tp, &stp, sizeof(struct timespec))) {
301 errno = EFAULT;
302 return -EFAULT;
303 }
304
305 return ret;
306 }
307
SysClockGetres(clockid_t clockID,struct timespec * tp)308 int SysClockGetres(clockid_t clockID, struct timespec *tp)
309 {
310 int ret;
311 struct timespec stp = { 0 };
312
313 if (tp == NULL) {
314 errno = EINVAL;
315 return -EINVAL;
316 }
317
318 ret = clock_getres(clockID, &stp);
319 if (ret < 0) {
320 return -get_errno();
321 }
322
323 if (LOS_ArchCopyToUser(tp, &stp, sizeof(struct timespec))) {
324 errno = EFAULT;
325 return -EFAULT;
326 }
327
328 return ret;
329 }
330
SysClockNanoSleep(clockid_t clk,int flags,const struct timespec * req,struct timespec * rem)331 int SysClockNanoSleep(clockid_t clk, int flags, const struct timespec *req, struct timespec *rem)
332 {
333 int ret;
334 struct timespec sreq;
335 struct timespec srem = { 0 };
336
337 if (!req || LOS_ArchCopyFromUser(&sreq, req, sizeof(struct timespec))) {
338 errno = EFAULT;
339 return -EFAULT;
340 }
341
342 ret = clock_nanosleep(clk, flags, &sreq, rem ? &srem : NULL);
343 if (ret < 0) {
344 return -get_errno();
345 }
346
347 if (rem && LOS_ArchCopyToUser(rem, &srem, sizeof(struct timespec))) {
348 errno = EFAULT;
349 return -EFAULT;
350 }
351
352 return ret;
353 }
354
SysNanoSleep(const struct timespec * rqtp,struct timespec * rmtp)355 int SysNanoSleep(const struct timespec *rqtp, struct timespec *rmtp)
356 {
357 int ret;
358 struct timespec srqtp;
359 struct timespec srmtp = { 0 };
360
361 if (!rqtp || LOS_ArchCopyFromUser(&srqtp, rqtp, sizeof(struct timespec))) {
362 errno = EFAULT;
363 return -EFAULT;
364 }
365
366 if (rmtp && LOS_ArchCopyFromUser(&srmtp, rmtp, sizeof(struct timespec))) {
367 errno = EFAULT;
368 return -EFAULT;
369 }
370
371 ret = nanosleep(&srqtp, rmtp ? &srmtp : NULL);
372 if (ret < 0) {
373 return -get_errno();
374 }
375
376 if (rmtp && LOS_ArchCopyToUser(rmtp, &srmtp, sizeof(struct timespec))) {
377 errno = EFAULT;
378 return -EFAULT;
379 }
380
381 return ret;
382 }
383
SysTimes(struct tms * buf)384 clock_t SysTimes(struct tms *buf)
385 {
386 clock_t ret;
387 struct tms sbuf = { 0 };
388
389 if (buf == NULL) {
390 errno = EFAULT;
391 return -EFAULT;
392 }
393 ret = times(&sbuf);
394 if (ret == -1) {
395 return -get_errno();
396 }
397 if (LOS_ArchCopyToUser(buf, &sbuf, sizeof(struct tms))) {
398 errno = EFAULT;
399 return -EFAULT;
400 }
401
402 return ret;
403 }
404
SysClockSettime64(clockid_t clockID,const struct timespec64 * tp)405 int SysClockSettime64(clockid_t clockID, const struct timespec64 *tp)
406 {
407 int ret;
408 struct timespec t;
409 struct timespec64 stp;
410
411 if (tp == NULL) {
412 errno = EINVAL;
413 return -EINVAL;
414 }
415
416 if (LOS_ArchCopyFromUser(&stp, tp, sizeof(struct timespec64))) {
417 errno = EFAULT;
418 return -EFAULT;
419 }
420
421 if (stp.tv_sec > UINT32_MAX) {
422 errno = ENOSYS;
423 return -ENOSYS;
424 }
425 t.tv_sec = stp.tv_sec;
426 t.tv_nsec = stp.tv_nsec;
427
428 ret = clock_settime(clockID, &t);
429 if (ret < 0) {
430 return -get_errno();
431 }
432 return ret;
433 }
434
SysClockGettime64(clockid_t clockID,struct timespec64 * tp)435 int SysClockGettime64(clockid_t clockID, struct timespec64 *tp)
436 {
437 int ret;
438 struct timespec t;
439 struct timespec64 stp = { 0 };
440
441 if (tp == NULL) {
442 errno = EINVAL;
443 return -EINVAL;
444 }
445
446 ret = clock_gettime(clockID, &t);
447 if (ret < 0) {
448 return -get_errno();
449 }
450
451 stp.tv_sec = t.tv_sec;
452 stp.tv_nsec = t.tv_nsec;
453
454 if (LOS_ArchCopyToUser(tp, &stp, sizeof(struct timespec64))) {
455 errno = EFAULT;
456 return -EFAULT;
457 }
458
459 return ret;
460 }
461
SysClockGetres64(clockid_t clockID,struct timespec64 * tp)462 int SysClockGetres64(clockid_t clockID, struct timespec64 *tp)
463 {
464 int ret;
465 struct timespec t;
466 struct timespec64 stp = { 0 };
467
468 if (tp == NULL) {
469 errno = EINVAL;
470 return -EINVAL;
471 }
472
473 ret = clock_getres(clockID, &t);
474 if (ret < 0) {
475 return -get_errno();
476 }
477
478 stp.tv_sec = t.tv_sec;
479 stp.tv_nsec = t.tv_nsec;
480
481 if (LOS_ArchCopyToUser(tp, &stp, sizeof(struct timespec64))) {
482 errno = EFAULT;
483 return -EFAULT;
484 }
485
486 return ret;
487 }
488
SysClockNanoSleep64(clockid_t clk,int flags,const struct timespec64 * req,struct timespec64 * rem)489 int SysClockNanoSleep64(clockid_t clk, int flags, const struct timespec64 *req, struct timespec64 *rem)
490 {
491 int ret;
492 struct timespec rq;
493 struct timespec rm = { 0 };
494 struct timespec64 sreq;
495 struct timespec64 srem = { 0 };
496
497 if (!req || LOS_ArchCopyFromUser(&sreq, req, sizeof(struct timespec64))) {
498 errno = EFAULT;
499 return -EFAULT;
500 }
501
502 if (req != NULL) {
503 rq.tv_sec = (sreq.tv_sec > UINT32_MAX) ? UINT32_MAX : sreq.tv_sec;
504 rq.tv_nsec = sreq.tv_nsec;
505 }
506
507 ret = clock_nanosleep(clk, flags, &rq, rem ? &rm : NULL);
508 if (ret < 0) {
509 return -get_errno();
510 }
511
512 if (rem != NULL) {
513 srem.tv_sec = rm.tv_sec;
514 srem.tv_nsec = rm.tv_nsec;
515 if (LOS_ArchCopyToUser(rem, &srem, sizeof(struct timespec64))) {
516 errno = EFAULT;
517 return -EFAULT;
518 }
519 }
520
521 return ret;
522 }
523
SysTimerGettime64(timer_t timerID,struct itimerspec64 * value)524 int SysTimerGettime64(timer_t timerID, struct itimerspec64 *value)
525 {
526 int ret;
527 struct itimerspec val;
528 struct itimerspec64 svalue = { 0 };
529
530 if (value == NULL) {
531 errno = EINVAL;
532 return -EINVAL;
533 }
534
535 ret = timer_gettime(timerID, &val);
536 if (ret < 0) {
537 return -get_errno();
538 }
539
540 svalue.it_interval.tv_sec = val.it_interval.tv_sec;
541 svalue.it_interval.tv_nsec = val.it_interval.tv_nsec;
542 svalue.it_value.tv_sec = val.it_value.tv_sec;
543 svalue.it_value.tv_nsec = val.it_value.tv_nsec;
544
545 if (LOS_ArchCopyToUser(value, &svalue, sizeof(struct itimerspec64))) {
546 errno = EFAULT;
547 return -EFAULT;
548 }
549
550 return ret;
551 }
552
SysTimerSettime64(timer_t timerID,int flags,const struct itimerspec64 * value,struct itimerspec64 * oldValue)553 int SysTimerSettime64(timer_t timerID, int flags, const struct itimerspec64 *value, struct itimerspec64 *oldValue)
554 {
555 int ret;
556 struct itimerspec val;
557 struct itimerspec oldVal;
558 struct itimerspec64 svalue;
559 struct itimerspec64 soldValue;
560
561 if (value == NULL) {
562 errno = EINVAL;
563 return -EINVAL;
564 }
565
566 if (LOS_ArchCopyFromUser(&svalue, value, sizeof(struct itimerspec64))) {
567 errno = EFAULT;
568 return -EFAULT;
569 }
570
571 if (svalue.it_interval.tv_sec > UINT32_MAX || svalue.it_value.tv_sec > UINT32_MAX) {
572 errno = ENOSYS;
573 return -ENOSYS;
574 }
575
576 val.it_interval.tv_sec = svalue.it_interval.tv_sec;
577 val.it_interval.tv_nsec = svalue.it_interval.tv_nsec;
578 val.it_value.tv_sec = svalue.it_value.tv_sec;
579 val.it_value.tv_nsec = svalue.it_value.tv_nsec;
580
581 ret = timer_settime(timerID, flags, &val, oldValue ? &oldVal : NULL);
582 if (ret < 0) {
583 return -get_errno();
584 }
585
586 if (oldValue != NULL) {
587 (void)memset_s(&soldValue, sizeof(struct itimerspec64), 0, sizeof(struct itimerspec64));
588 soldValue.it_interval.tv_sec = oldVal.it_interval.tv_sec;
589 soldValue.it_interval.tv_nsec = oldVal.it_interval.tv_nsec;
590 soldValue.it_value.tv_sec = oldVal.it_value.tv_sec;
591 soldValue.it_value.tv_nsec = oldVal.it_value.tv_nsec;
592
593 if (LOS_ArchCopyToUser(oldValue, &soldValue, sizeof(struct itimerspec64))) {
594 errno = EFAULT;
595 return -EFAULT;
596 }
597 }
598
599 return ret;
600 }
601