/* * Pipe stream to or from process. Similar to popen(), only much faster. * * This is simpler than popen_noshell() but is more INSECURE. * Since shells have very complicated expansion, quoting and word splitting algorithms, we do NOT try to re-implement them here. * This function does NOT support any special characters. It will immediately return an error if such symbols are encountered in "command". * The "command" is split only by space and tab delimiters. The special symbols are pre-defined in popen_bash_meta_characters[]. * The only special characters supported are single and double quotes. You can enclose arguments in quotes and they should be splitted correctly. * * If possible, use popen_noshell() because of its better security. * * "command" is the command and its arguments to be executed. The command is searched within the PATH environment variable. * The whole "command" string is parsed and splitted, so that it can be directly given to popen_noshell() and resp. to exec(). * This parsing is very simple and may contain bugs (see above). If possible, use popen_noshell() directly. * "type" specifies if we are reading from the STDOUT or writing to the STDIN of the executed command. Use "r" for reading, "w" for writing. * "pid" is a pointer to an interger. The PID of the child process is stored there. * * Returns NULL on any error, "errno" is set appropriately. * On success, a stream pointer is returned. * When you are done working with the stream, you have to close it by calling pclose_noshell(), or else you will leave zombie processes. */ FILE *popen_noshell_compat(const char *command, const char *type, struct popen_noshell_pass_to_pclose *pclose_arg) { char **argv; FILE *fp; char *to_free; argv = popen_noshell_split_command_to_argv(command, &to_free); if (!argv) { if (to_free) free(to_free); return NULL; } fp = popen_noshell(argv[0], (const char * const *)argv, type, pclose_arg, 0); free(to_free); free(argv); return fp; }
int main(int argc, char* argv[]) { char *p[] = {"echo", "pokemon", NULL}; char buffer[LSIZE] = {0}; FILE *fp = popen_noshell(p, "r"); while (fgets(buffer, LSIZE, fp)) { printf("%s", buffer); } if (ferror(fp)) { printf("omg error"); } pclose_noshell(fp); return 0; }
static int openInputDevice(lua_State *L) { const char* inputdevice = luaL_checkstring(L, 1); #ifndef EMULATE_READER int fd; int childpid; fd = findFreeFdSlot(); if(fd == -1) { return luaL_error(L, "no free slot for new input device <%s>", inputdevice); } if(!strcmp("fake_events", inputdevice)) { /* special case: the power slider */ int pipefd[2]; pipe(pipefd); if((childpid = fork()) == -1) { return luaL_error(L, "cannot fork() slider event listener"); } if(childpid == 0) { // We send a SIGTERM to this child on exit, trap it to kill lipc properly. signal(SIGTERM, slider_handler); FILE *fp; char std_out[256]; int status; struct input_event ev; __u16 key_code = 10000; close(pipefd[0]); ev.type = EV_KEY; ev.code = key_code; ev.value = 1; /* listen power slider events (listen for ever for multiple events) */ char *argv[] = {"lipc-wait-event", "-m", "-s", "0", "com.lab126.powerd", "goingToScreenSaver,outOfScreenSaver,charging,notCharging", (char *) NULL}; /* @TODO 07.06 2012 (houqp) * plugin and out event can only be watched by: lipc-wait-event com.lab126.hal usbPlugOut,usbPlugIn */ fp = popen_noshell("lipc-wait-event", (const char * const *)argv, "r", &pclose_arg, 0); if (!fp) { err(EXIT_FAILURE, "popen_noshell()"); } /* Flush to get rid of buffering issues? */ fflush(fp); while(fgets(std_out, sizeof(std_out)-1, fp)) { if(std_out[0] == 'g') { ev.code = CODE_IN_SAVER; } else if(std_out[0] == 'o') { ev.code = CODE_OUT_SAVER; } else if((std_out[0] == 'u') && (std_out[7] == 'I')) { ev.code = CODE_USB_PLUG_IN; } else if((std_out[0] == 'u') && (std_out[7] == 'O')) { ev.code = CODE_USB_PLUG_OUT; } else if(std_out[0] == 'c') { ev.code = CODE_CHARGING; } else if(std_out[0] == 'n') { ev.code = CODE_NOT_CHARGING; } else { printf("Unrecognized event.\n"); } /* fill event struct */ gettimeofday(&ev.time, NULL); /* generate event */ if(write(pipefd[1], &ev, sizeof(struct input_event)) == -1) { printf("Failed to generate event.\n"); } } status = pclose_noshell(&pclose_arg); if (status == -1) { err(EXIT_FAILURE, "pclose_noshell()"); } else { if (WIFEXITED(status)) { printf("lipc-wait-event exited normally with status: %d\n", WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { printf("lipc-wait-event was killed by signal %d\n", WTERMSIG(status)); } else if (WIFSTOPPED(status)) { printf("lipc-wait-event was stopped by signal %d\n", WSTOPSIG(status)); } else if (WIFCONTINUED(status)) { printf("lipc-wait-event continued\n"); } } // We're done, go away :). _exit(EXIT_SUCCESS); } else { close(pipefd[1]); inputfds[fd] = pipefd[0]; slider_pid = childpid; } } else { inputfds[fd] = open(inputdevice, O_RDONLY | O_NONBLOCK, 0); if(inputfds[fd] != -1) { ioctl(inputfds[fd], EVIOCGRAB, 1); return 0; } else { return luaL_error(L, "error opening input device <%s>: %d", inputdevice, errno); } } #else if(SDL_Init(SDL_INIT_VIDEO) < 0) { return luaL_error(L, "cannot initialize SDL."); } SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); /* we only use inputfds[0] in emu mode, because we only have one * fake device so far. */ inputfds[0] = open(inputdevice, O_RDWR | O_NONBLOCK); if (inputfds < 0) { return luaL_error(L, "error opening input device <%s>: %d", inputdevice, errno); } #endif return 0; }