• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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