Run the command. This is not ip specific, but used to call linux "ip" and "route" commands. If commands starts with '|', capture stdout and return the file descriptor to read it.
| 167 | // This is not ip specific, but used to call linux "ip" and "route" commands. |
| 168 | // If commands starts with '|', capture stdout and return the file descriptor to read it. |
| 169 | int runcmd(const char *path, ...) |
| 170 | { |
| 171 | int pipefd[2]; |
| 172 | int dopipe = 0; |
| 173 | if (*path == '|') { |
| 174 | path++; |
| 175 | dopipe = 1; |
| 176 | if (pipe(pipefd) == -1) { |
| 177 | MGERROR("could not create pipe: %s",strerror(errno)); |
| 178 | return -1; |
| 179 | } |
| 180 | } |
| 181 | int pid = fork(); |
| 182 | if (pid == -1) { |
| 183 | MGERROR("could not fork: %s",strerror(errno)); |
| 184 | return -1; |
| 185 | } |
| 186 | if (pid) { // This is the parent; wait for child to exit, then return childs status. |
| 187 | int status; |
| 188 | if (dopipe) { |
| 189 | close(pipefd[1]); // Close unused write end of pipe. |
| 190 | } |
| 191 | waitpid(pid,&status,0); |
| 192 | return dopipe ? pipefd[0] : status; // Return read end of pipe, if piped. |
| 193 | } |
| 194 | // This is the child process. |
| 195 | if (dopipe) { |
| 196 | close(pipefd[0]); // Close unused read end of pipe. |
| 197 | dup2(pipefd[1],1); // Capture stdout to pipe. |
| 198 | close(pipefd[1]); // Close now redundant fd. |
| 199 | } |
| 200 | |
| 201 | // Gather args into argc,argv; |
| 202 | int argc = 0; char *argv[100]; |
| 203 | va_list ap; |
| 204 | va_start(ap, path); |
| 205 | do { |
| 206 | argv[argc] = va_arg(ap,char*); |
| 207 | } while (argv[argc++]); |
| 208 | argv[argc] = NULL; |
| 209 | va_end(ap); |
| 210 | |
| 211 | // Print them out. |
| 212 | // But dont print if piped, because it goes into the pipe! |
| 213 | if (! dopipe) { |
| 214 | char buf[208], *bp = buf, *ep = &buf[200]; |
| 215 | int i; |
| 216 | for (i = 0; argv[i]; i++) { |
| 217 | int len = strlen(argv[i]); |
| 218 | if (bp + len > ep) { strcpy(bp,"..."); break; } |
| 219 | strcpy(bp,argv[i]); |
| 220 | bp += len; |
| 221 | *bp++ = ' '; |
| 222 | *bp = 0; |
| 223 | } |
| 224 | buf[200] = 0; |
| 225 | MGINFO("%s",buf); |
| 226 | } |