Skip to content

Instantly share code, notes, and snippets.

@AdjWang
Last active April 11, 2024 13:38
Show Gist options
  • Save AdjWang/c861081fcdbd31cba3356620785c3e60 to your computer and use it in GitHub Desktop.
Save AdjWang/c861081fcdbd31cba3356620785c3e60 to your computer and use it in GitHub Desktop.
Run a command through popen and get the output.
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
size_t get_line_size() {
// https://man7.org/linux/man-pages/man3/fgets.3p.html
const size_t kLineMax = 16384u;
size_t line_max;
if (LINE_MAX >= kLineMax) {
line_max = kLineMax;
} else {
long limit = sysconf(_SC_LINE_MAX);
line_max =
(limit < 0 || (size_t)limit > kLineMax) ? kLineMax : (size_t)limit;
}
return line_max + 1;
}
int run_cmd(const char* cmd, char* output, size_t n) {
if (cmd == NULL) {
return 0;
}
FILE* fp = popen(cmd, "r");
if (fp == NULL) {
fprintf(stderr, "failed. cmd=%s\n", cmd);
perror("popen failed\n");
return -1;
}
if (output == NULL || n == 0) {
if (pclose(fp) == -1) {
perror("pclose failed\n");
}
return -1;
}
size_t line_size = get_line_size();
char* line = (char*)malloc(line_size);
if (line == NULL) {
fprintf(stderr, "malloc size=%ld failed\n", line_size);
perror("malloc failed\n");
if (pclose(fp) == -1) {
perror("pclose failed\n");
}
return -1;
}
size_t size_remain = n;
char* dest = output;
while (size_remain > 0 && fgets(line, line_size, fp) != NULL) {
size_t s = strlen(line);
size_t size_copy = size_remain < s ? size_remain : s;
memcpy(dest, line, size_copy);
size_remain -= size_copy;
dest += size_copy;
}
*dest = '\0';
free(line);
if (pclose(fp) == -1) {
perror("pclose failed\n");
return -1;
}
return 0;
}
int main() {
// only execute the command
run_cmd("ls", NULL, 0);
run_cmd("ls", NULL, 1);
run_cmd("ls", (char*)1, 0);
// execute the command and print the result
char output[LINE_MAX];
run_cmd("ls /", output, LINE_MAX);
printf("%s", output);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment