2 * Shell-like utility functions
4 * Copyright 2004, Broadcom Corporation
7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
25 #include <sys/types.h>
29 #include <sys/ioctl.h>
31 #include <net/ethernet.h>
36 * Reads file and returns contents
37 * @param fd file descriptor
38 * @return contents of file or NULL if an error occurred
47 buf = realloc(buf, count + 512);
48 n = read(fd, buf + count, 512);
63 * Reads file and returns contents
64 * @param path path to file
65 * @return contents of file or NULL if an error occurred
68 file2str(const char *path)
72 if ((fd = open(path, O_RDONLY)) == -1) {
81 * Waits for a file descriptor to change status or unblocked signal
82 * @param fd file descriptor
83 * @param timeout seconds to wait before timing out or 0 for no timeout
84 * @return 1 if descriptor changed status or 0 if timed out or -1 on error
87 waitfor(int fd, int timeout)
90 struct timeval tv = { timeout, 0 };
94 return select(fd + 1, &rfds, NULL, NULL, (timeout > 0) ? &tv : NULL);
98 * Concatenates NULL-terminated list of arguments into a single
99 * commmand and executes it
100 * @param argv argument list
101 * @param path NULL, ">output", or ">>output"
102 * @param timeout seconds to wait before timing out or 0 for no timeout
103 * @param ppid NULL to wait for child termination or pointer to pid
104 * @return return value of executed command or errno
107 _eval(char *const argv[], char *path, int timeout, int *ppid)
117 switch (pid = fork()) {
122 /* Reset signal handlers set for parent process */
123 for (sig = 0; sig < (_NSIG-1); sig++)
124 signal(sig, SIG_DFL);
127 ioctl(0, TIOCNOTTY, 0);
129 close(STDOUT_FILENO);
130 close(STDERR_FILENO);
133 /* We want to check the board if exist UART? , add by honor 2003-12-04 */
134 if ((fd = open("/dev/console", O_RDWR)) < 0) {
135 (void) open("/dev/null", O_RDONLY);
136 (void) open("/dev/null", O_WRONLY);
137 (void) open("/dev/null", O_WRONLY);
141 (void) open("/dev/console", O_RDONLY);
142 (void) open("/dev/console", O_WRONLY);
143 (void) open("/dev/console", O_WRONLY);
146 /* Redirect stdout to <path> */
148 flags = O_WRONLY | O_CREAT;
149 if (!strncmp(path, ">>", 2)) {
150 /* append to <path> */
153 } else if (!strncmp(path, ">", 1)) {
154 /* overwrite <path> */
158 if ((fd = open(path, flags, 0644)) < 0)
161 dup2(fd, STDOUT_FILENO);
166 /* execute command */
167 for(i=0 ; argv[i] ; i++)
168 snprintf(buf+strlen(buf), sizeof(buf), "%s ", argv[i]);
169 dprintf("cmd=[%s]\n", buf);
170 setenv("PATH", "/sbin:/bin:/usr/sbin:/usr/bin", 1);
172 execvp(argv[0], argv);
175 default: /* parent */
180 waitpid(pid, &status, 0);
181 if (WIFEXITED(status))
182 return WEXITSTATUS(status);
190 * Concatenates NULL-terminated list of arguments into a single
191 * commmand and executes it
192 * @param argv argument list
193 * @return stdout of executed command or NULL if an error occurred
196 _backtick(char *const argv[])
204 if (pipe(filedes) == -1) {
209 switch (pid = fork()) {
213 close(filedes[0]); /* close read end of pipe */
214 dup2(filedes[1], 1); /* redirect stdout to write end of pipe */
215 close(filedes[1]); /* close write end of pipe */
216 execvp(argv[0], argv);
219 default: /* parent */
220 close(filedes[1]); /* close write end of pipe */
221 buf = fd2str(filedes[0]);
222 waitpid(pid, &status, 0);
230 * Kills process whose PID is stored in plaintext in pidfile
231 * @param pidfile PID file
232 * @return 0 on success and errno on failure
235 kill_pidfile(char *pidfile)
237 FILE *fp = fopen(pidfile, "r");
240 if (fp && fgets(buf, sizeof(buf), fp)) {
241 pid_t pid = strtoul(buf, NULL, 0);
243 return kill(pid, SIGTERM);
249 * fread() with automatic retry on syscall interrupt
250 * @param ptr location to store to
251 * @param size size of each element of data
252 * @param nmemb number of elements
253 * @param stream file stream
254 * @return number of items successfully read
257 safe_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
263 ret += fread((char *)ptr + (ret * size), size, nmemb - ret, stream);
264 } while (ret < nmemb && ferror(stream) && errno == EINTR);
270 * fwrite() with automatic retry on syscall interrupt
271 * @param ptr location to read from
272 * @param size size of each element of data
273 * @param nmemb number of elements
274 * @param stream file stream
275 * @return number of items successfully written
278 safe_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
284 ret += fwrite((char *)ptr + (ret * size), size, nmemb - ret, stream);
285 } while (ret < nmemb && ferror(stream) && errno == EINTR);
291 * Convert Ethernet address string representation to binary data
292 * @param a string in xx:xx:xx:xx:xx:xx notation
293 * @param e binary data
294 * @return TRUE if conversion was successful and FALSE otherwise
297 ether_atoe(const char *a, unsigned char *e)
299 char *c = (char *) a;
302 memset(e, 0, ETHER_ADDR_LEN);
304 e[i++] = (unsigned char) strtoul(c, &c, 16);
305 if (!*c++ || i == ETHER_ADDR_LEN)
308 return (i == ETHER_ADDR_LEN);
312 * Convert Ethernet address binary data to string representation
313 * @param e binary data
314 * @param a string in xx:xx:xx:xx:xx:xx notation
318 ether_etoa(const unsigned char *e, char *a)
323 for (i = 0; i < ETHER_ADDR_LEN; i++) {
326 c += sprintf(c, "%02X", e[i] & 0xff);