lib: Add support for J721S2 SoCs
[rpmsg/ti-rpmsg-char.git] / src / utils.c
1 /*
2  * Copyright (c) 2020 Texas Instruments Incorporated - https://www.ti.com
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * *  Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *
11  * *  Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * *  Neither the name of Texas Instruments Incorporated nor the names of
16  *    its contributors may be used to endorse or promote products derived
17  *    from this software without specific prior written 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
21  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  *
31  */
33 #include <dirent.h>
34 #include <errno.h>
35 #include <fcntl.h>
36 #include <stdarg.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <unistd.h>
41 #include <sys/stat.h>
43 int get_child_dir_suffix(char *fpath, const char *child_name_pattern,
44                          unsigned int *suffix)
45 {
46         struct dirent *iter;
47         DIR *parent;
48         int ret = -ENODEV;
50         parent = opendir(fpath);
51         if (!parent)
52                 return -errno;
54         while ((iter = readdir(parent))) {
55                 if (iter->d_type == DT_DIR &&
56                     sscanf(iter->d_name, child_name_pattern, suffix)) {
57                         ret = 0;
58                         break;
59                 }
60         }
62         closedir(parent);
63         return ret;
64 }
66 int file_read_string(char *fpath, char *buf, int size)
67 {
68         int fd, bytes;
70         fd = open(fpath, O_RDONLY);
71         if (fd < 0) {
72                 fprintf(stderr, "could not open %s: errno = %d\n",
73                         fpath, errno);
74                 return -errno;
75         }
77         bytes = read(fd, buf, size);
78         close(fd);
79         if (bytes <= 0) {
80                 fprintf(stderr, "could not read %s: errno = %d\n",
81                         fpath, errno);
82                 return -EIO;
83         }
84         if (bytes >= size) {
85                 fprintf(stderr, "%d bytes read from %s are larger than size %d\n",
86                         bytes, fpath, size);
87                 return -EIO;
88         }
90         /* suppress the newline */
91         buf[bytes - 1] = '\0';
93         return bytes;
94 }
96 int file_read_value(char *fpath)
97 {
98         char buf[32];
99         int ret;
101         ret = file_read_string(fpath, buf, sizeof(buf));
102         if (ret < 0)
103                 return ret;
105         return strtol(buf, NULL, 0);
108 int check_dir(char *dirpath)
110         struct stat s;
112         if (stat(dirpath, &s) == 0 && S_ISDIR(s.st_mode))
113                 return 0;
115         return -ENOENT;
118 /* Returns a pointer to allocated memory, needs to be freed once done */
119 char *file_deref_link(char *fpath, char *link_name)
121         char path[512] = { 0 };
122         char rel_path[256] = { 0 };
123         int n, nr;
125         n = snprintf(path, 256, "%s/%s", fpath, link_name);
126         if (n < 0 || n >= 256) {
127                 fprintf(stderr, "%s: could not create full path string\n",
128                         __func__);
129                 return NULL;
130         }
132         nr = readlink(path, rel_path, sizeof(rel_path));
133         if (nr < 0) {
134                 fprintf(stderr, "%s: readlink failed for %s\n", __func__, path);
135                 return NULL;
136         }
138         if (n + nr >= 512) {
139                 fprintf(stderr, "%s: full relative path exceeds buffer size, n = %d nr = %d\n",
140                         __func__, n, nr);
141                 return NULL;
142         }
144         memset(path, 0, sizeof(path));
145         sprintf(path, "%s/%s", fpath, rel_path);
147         return realpath(path, NULL);