const char * vp_file_open(char *args) { vp_stack_t stack; char *path; char *flags; int mode; /* used when flags have O_CREAT */ int oflag = 0; int fd; VP_RETURN_IF_FAIL(vp_stack_from_args(&stack, args)); VP_RETURN_IF_FAIL(vp_stack_pop_str(&stack, &path)); VP_RETURN_IF_FAIL(vp_stack_pop_str(&stack, &flags)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &mode)); oflag = str_to_oflag(flags); if (oflag == -1) return vp_stack_return_error(&_result, "open flag error."); fd = open(path, oflag, mode); if (fd == -1) return vp_stack_return_error(&_result, "open() error: %s", strerror(errno)); vp_stack_push_num(&_result, "%d", fd); return vp_stack_return(&_result); }
const char * vp_socket_open(char *args) { vp_stack_t stack; char *host; char *port; int port_nr; int n; unsigned short nport; int sock; struct sockaddr_in sockaddr; struct hostent *hostent; struct servent *servent; VP_RETURN_IF_FAIL(vp_stack_from_args(&stack, args)); VP_RETURN_IF_FAIL(vp_stack_pop_str(&stack, &host)); VP_RETURN_IF_FAIL(vp_stack_pop_str(&stack, &port)); if (sockets_number++ == 0) { WSADATA wsadata; WSAStartup(2, &wsadata); } if (sscanf(port, "%d%n", &port_nr, &n) == 1 && port[n] == '\0') { nport = htons((u_short)port_nr); } else { servent = getservbyname(port, NULL); if (servent == NULL) return vp_stack_return_error(&_result, "getservbyname() error: %s", port); nport = servent->s_port; } sock = (int)socket(PF_INET, SOCK_STREAM, 0); hostent = gethostbyname(host); sockaddr.sin_family = AF_INET; sockaddr.sin_port = nport; sockaddr.sin_addr = *((struct in_addr*)*hostent->h_addr_list); if (connect(sock, (struct sockaddr*)&sockaddr, sizeof(struct sockaddr_in)) == -1) return vp_stack_return_error(&_result, "connect() error: %s", strerror(errno)); vp_stack_push_num(&_result, "%d", sock); return vp_stack_return(&_result); }
/* * Added by Richard Emberson * Check to see if a host exists. */ const char * vp_host_exists(char *args) { vp_stack_t stack; char *host; struct hostent *hostent; VP_RETURN_IF_FAIL(vp_stack_from_args(&stack, args)); VP_RETURN_IF_FAIL(vp_stack_pop_str(&stack, &host)); if (sockets_number++ == 0) { WSADATA wsadata; WSAStartup(2, &wsadata); } hostent = gethostbyname(host); if (--sockets_number == 0) { WSACleanup(); } if (hostent) { vp_stack_push_num(&_result, "%d", 1); } else { vp_stack_push_num(&_result, "%d", 0); } return vp_stack_return(&_result); }
const char * vp_readdir(char *args) { vp_stack_t stack; char *dirname; char buf[1024]; DIR *dir; struct dirent *dp; VP_RETURN_IF_FAIL(vp_stack_from_args(&stack, args)); VP_RETURN_IF_FAIL(vp_stack_pop_str(&stack, &dirname)); if ((dir=opendir(dirname)) == NULL) { return vp_stack_return_error(&_result, "opendir() error: %s", strerror(errno)); } for (dp = readdir(dir); dp != NULL; dp = readdir(dir)) { snprintf(buf, sizeof(buf), "%s/%s", dirname, dp->d_name); vp_stack_push_str(&_result, buf); } closedir(dir); return vp_stack_return(&_result); }
const char * vp_decode(char *args) { vp_stack_t stack; size_t len; char *str; char *p, *q; VP_RETURN_IF_FAIL(vp_stack_from_args(&stack, args)); VP_RETURN_IF_FAIL(vp_stack_pop_str(&stack, &str)); len = strlen(str); if (len % 2 != 0) { return "vp_decode: invalid data length"; } VP_RETURN_IF_FAIL(vp_stack_reserve(&_result, (_result.top - _result.buf) + (len / 2) + sizeof(VP_EOV_STR))); for (p = str, q = _result.top; p < str + len; ) { char hb, lb; hb = CHR2XD[(int)*(p++)]; lb = CHR2XD[(int)*(p++)]; if (hb != (char)-1 && lb != (char)-1) { *(q++) = (hb << 4) | lb; } } *(q++) = VP_EOV; *q = '\0'; _result.top = q; return vp_stack_return(&_result); }
/* http://www.syuhitu.org/other/dir.html */ const char * vp_readdir(char *args) { vp_stack_t stack; char *dirname; char buf[1024]; WIN32_FIND_DATA fd; HANDLE h; VP_RETURN_IF_FAIL(vp_stack_from_args(&stack, args)); VP_RETURN_IF_FAIL(vp_stack_pop_str(&stack, &dirname)); snprintf(buf, sizeof(buf), "%s\\*", dirname); /* Get handle. */ h = FindFirstFileEx(buf, FindExInfoStandard, &fd, FindExSearchNameMatch, NULL, 0 ); if (h == INVALID_HANDLE_VALUE) { return vp_stack_return_error(&_result, "FindFirstFileEx() error: %s", GetLastError()); } do { snprintf(buf, sizeof(buf), "%s/%s", dirname, fd.cFileName); vp_stack_push_str(&_result, buf); } while (FindNextFile(h, &fd)); FindClose(h); return vp_stack_return(&_result); }
/* * This is based on socket.diff.gz written by Yasuhiro Matsumoto. * see: http://marc.theaimsgroup.com/?l=vim-dev&m=105289857008664&w=2 */ const char * vp_socket_open(char *args) { vp_stack_t stack; char *host; char *port; char *p; int n; unsigned short nport; int sock; struct sockaddr_in sockaddr; struct hostent *hostent; struct servent *servent; VP_RETURN_IF_FAIL(vp_stack_from_args(&stack, args)); VP_RETURN_IF_FAIL(vp_stack_pop_str(&stack, &host)); VP_RETURN_IF_FAIL(vp_stack_pop_str(&stack, &port)); n = strtol(port, &p, 10); if (p == port + strlen(port)) { nport = htons(n); } else { servent = getservbyname(port, NULL); if (servent == NULL) return vp_stack_return_error(&_result, "getservbyname() error: %s", port); nport = servent->s_port; } sock = socket(PF_INET, SOCK_STREAM, 0); hostent = gethostbyname(host); sockaddr.sin_family = AF_INET; sockaddr.sin_port = nport; sockaddr.sin_addr = *((struct in_addr*)*hostent->h_addr_list); if (connect(sock, (struct sockaddr*)&sockaddr, sizeof(struct sockaddr_in)) == -1) return vp_stack_return_error(&_result, "connect() error: %s", strerror(errno)); vp_stack_push_num(&_result, "%d", sock); return vp_stack_return(&_result); }
const char * vp_pty_open(char *args) { vp_stack_t stack; int argc; char *argv[VP_ARGC_MAX]; int fdm; pid_t pid; struct winsize ws = {0, 0, 0, 0}; struct termios ti; int i; VP_RETURN_IF_FAIL(vp_stack_from_args(&stack, args)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%hu", &(ws.ws_col))); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%hu", &(ws.ws_row))); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &argc)); if (argc < 1 || VP_ARGC_MAX <= argc) return vp_stack_return_error(&_result, "argc range error. too many arguments. please use xargs."); for (i = 0; i < argc; ++i) VP_RETURN_IF_FAIL(vp_stack_pop_str(&stack, &(argv[i]))); argv[argc] = NULL; #if 0 /* TODO: set termios parameter */ /* tcgetattr will fail when gvim is executed from gnome menu */ if (tcgetattr(STDIN_FILENO, &ti) < 0) return vp_stack_return_error(&_result, "tcgetattr() error: %s", strerror(errno)); pid = forkpty(&fdm, NULL, &ti, &ws); #else pid = forkpty(&fdm, NULL, NULL, &ws); #endif if (pid < 0) { return vp_stack_return_error(&_result, "forkpty() error: %s", strerror(errno)); } else if (pid == 0) { /* child */ if (execv(argv[0], argv) < 0) { /* error */ write(fdm, strerror(errno), strlen(strerror(errno))); _exit(EXIT_FAILURE); } } else { /* parent */ vp_stack_push_num(&_result, "%d", pid); vp_stack_push_num(&_result, "%d", fdm); /* XXX - ttyname(fdm) breaks in OS X */ vp_stack_push_str(&_result, "unused"); return vp_stack_return(&_result); } /* DO NOT REACH HERE */ return NULL; }
const char * vp_dlopen(char *args) { vp_stack_t stack; char *path; void *handle; VP_RETURN_IF_FAIL(vp_stack_from_args(&stack, args)); VP_RETURN_IF_FAIL(vp_stack_pop_str(&stack, &path)); handle = dlopen(path, RTLD_LAZY); if (handle == NULL) return dlerror(); vp_stack_push_num(&_result, "%p", handle); return vp_stack_return(&_result); }
const char * vp_dlopen(char *args) { vp_stack_t stack; char *path; HINSTANCE handle; VP_RETURN_IF_FAIL(vp_stack_from_args(&stack, args)); VP_RETURN_IF_FAIL(vp_stack_pop_str(&stack, &path)); handle = LoadLibrary(path); if (handle == NULL) return lasterror(); vp_stack_push_num(&_result, "%p", handle); return vp_stack_return(&_result); }
const char * vp_open(char *args) { vp_stack_t stack; char *path; VP_RETURN_IF_FAIL(vp_stack_from_args(&stack, args)); VP_RETURN_IF_FAIL(vp_stack_pop_str(&stack, &path)); if ((size_t)ShellExecute(NULL, "open", path, NULL, NULL, SW_SHOWNORMAL) < 32) { return vp_stack_return_error(&_result, "ShellExecute() error: %s", lasterror()); } return NULL; }
/* bin is hexdump */ static const char * vp_stack_pop_bin(vp_stack_t *stack, char **buf, size_t *size) { char *p; char ub, lb; size_t gain = 0; VP_RETURN_IF_FAIL(vp_stack_pop_str(stack, buf)); p = *buf; while (*p) { ub = CHR2XD[(unsigned char)*(p++)]; lb = CHR2XD[(unsigned char)*(p++)]; if (ub < 0 || lb < 0) return "vp_stack_pop_bin: sscanf error"; (*buf)[gain++] = (char)((ub << 4) | (lb << 0)); } *size = gain; return NULL; }
/* * Added by Richard Emberson * Check to see if a host exists. */ const char * vp_host_exists(char *args) { vp_stack_t stack; char *host; struct hostent *hostent; VP_RETURN_IF_FAIL(vp_stack_from_args(&stack, args)); VP_RETURN_IF_FAIL(vp_stack_pop_str(&stack, &host)); hostent = gethostbyname(host); if (hostent) { vp_stack_push_num(&_result, "%d", 1); } else { vp_stack_push_num(&_result, "%d", 0); } return vp_stack_return(&_result); }
const char * vp_decode(char *args) { vp_stack_t stack; unsigned num = 0; unsigned i = 0; size_t length; char *str; char *buf; char *p; char *bp; VP_RETURN_IF_FAIL(vp_stack_from_args(&stack, args)); VP_RETURN_IF_FAIL(vp_stack_pop_str(&stack, &str)); length = strlen(str); buf = (char *)malloc(length/2 + 2); if (buf == NULL) { return vp_stack_return_error(&_result, "malloc() error: %s", "Memory cannot allocate"); } p = str; bp = buf; for (i = 0; i < length; i++, p++) { if (isdigit(*p)) num |= (*p & 15); else num |= (*p & 15) + 9; if (i % 2) { *bp++ = num; num = 0; } else { num <<= 4; } } *bp = '\0'; vp_stack_push_str(&_result, buf); free(buf); return vp_stack_return(&_result); }
const char * vp_delete_trash(char *args) { vp_stack_t stack; char *filename; char *buf; size_t len; SHFILEOPSTRUCT fs; VP_RETURN_IF_FAIL(vp_stack_from_args(&stack, args)); VP_RETURN_IF_FAIL(vp_stack_pop_str(&stack, &filename)); len = strlen(filename); buf = malloc(len + 2); if (buf == NULL) { return vp_stack_return_error(&_result, "malloc() error: %s", "Memory cannot allocate"); } /* Copy filename + '\0\0' */ strcpy(buf, filename); buf[len + 1] = 0; ZeroMemory(&fs, sizeof(SHFILEOPSTRUCT)); fs.hwnd = NULL; fs.wFunc = FO_DELETE; fs.pFrom = buf; fs.pTo = NULL; fs.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT; vp_stack_push_num(&_result, "%d", SHFileOperation(&fs)); free(buf); return vp_stack_return(&_result); }
const char * vp_decode(char *args) { vp_stack_t stack; unsigned num; unsigned i, bi; size_t length, max_buf; char *str; char *buf; char *p; VP_RETURN_IF_FAIL(vp_stack_from_args(&stack, args)); VP_RETURN_IF_FAIL(vp_stack_pop_str(&stack, &str)); length = strlen(str); max_buf = length/2 + 2; buf = (char *)malloc(max_buf); if (buf == NULL) { return vp_stack_return_error(&_result, "malloc() error: %s", "Memory cannot allocate"); } p = str; bi = 0; num = 0; for (i = 0; i < length; i++, p++) { if (isdigit((int)*p)) num |= (*p & 15); else num |= (*p & 15) + 9; if (i % 2 == 0) { num <<= 4; continue; } /* Write character. */ if (num == 0) { /* Convert NULL character. */ max_buf += 1; buf = (char *)realloc(buf, max_buf); if (buf == NULL) { return vp_stack_return_error( &_result, "realloc() error: %s", "Memory cannot allocate"); } buf[bi] = '^'; bi++; buf[bi] = '@'; bi++; } else { buf[bi] = num; bi++; } num = 0; } buf[bi] = '\0'; vp_stack_push_str(&_result, buf); free(buf); return vp_stack_return(&_result); }
const char * vp_pipe_open(char *args) { #define VP_GOTO_ERROR(_fmt) do { errfmt = (_fmt); goto error; } while(0) vp_stack_t stack; int npipe, hstdin, hstderr, hstdout; int argc; int fd[3][2] = {{0}}; pid_t pid; int dummy; char *errfmt; VP_RETURN_IF_FAIL(vp_stack_from_args(&stack, args)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &npipe)); if (npipe != 2 && npipe != 3) return vp_stack_return_error(&_result, "npipe range error. wrong pipes."); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &hstdin)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &hstdout)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &hstderr)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &argc)); if (hstdin > 0) { fd[0][0] = hstdin; fd[0][1] = 0; } else { if (pipe(fd[0]) < 0) { VP_GOTO_ERROR("pipe() error: %s"); } } if (hstdout > 0) { fd[1][1] = hstdout; fd[1][0] = 0; } else { if (pipe(fd[1]) < 0) { VP_GOTO_ERROR("pipe() error: %s"); } } if (hstderr > 0) { fd[2][1] = hstderr; fd[2][0] = 0; } else if (npipe == 3 && hstderr == 0) { if (pipe(fd[2]) < 0) { VP_GOTO_ERROR("pipe() error: %s"); } } pid = fork(); if (pid < 0) { VP_GOTO_ERROR("fork() error: %s"); } else if (pid == 0) { /* child */ char **argv; int i; /* Set process group. */ setpgid(0, 0); if (fd[0][1] > 0) { close(fd[0][1]); } if (fd[1][0] > 0) { close(fd[1][0]); } if (fd[2][0] > 0) { close(fd[2][0]); } if (fd[0][0] > 0) { if (dup2(fd[0][0], STDIN_FILENO) != STDIN_FILENO) { goto child_error; } close(fd[0][0]); } if (fd[1][1] > 0) { if (dup2(fd[1][1], STDOUT_FILENO) != STDOUT_FILENO) { goto child_error; } close(fd[1][1]); } if (fd[2][1] > 0) { if (dup2(fd[2][1], STDERR_FILENO) != STDERR_FILENO) { goto child_error; } close(fd[2][1]); } else if (npipe == 2) { if (dup2(STDOUT_FILENO, STDERR_FILENO) != STDERR_FILENO) { goto child_error; } } { #ifndef TIOCNOTTY setsid(); #else /* Ignore tty. */ char name[L_ctermid]; if (ctermid(name)[0] != '\0') { int tfd; if ((tfd = open(name, O_RDONLY)) != -1) { ioctl(tfd, TIOCNOTTY, NULL); close(tfd); } } #endif } argv = malloc(sizeof(char *) * (argc+1)); if (argv == NULL) { goto child_error; } for (i = 0; i < argc; ++i) { if (vp_stack_pop_str(&stack, &(argv[i]))) { free(argv); goto child_error; } } argv[argc] = NULL; execv(argv[0], argv); /* error */ goto child_error; } else { /* parent */ if (fd[0][0] > 0) { close(fd[0][0]); } if (fd[1][1] > 0) { close(fd[1][1]); } if (fd[2][1] > 0) { close(fd[2][1]); } vp_stack_push_num(&_result, "%d", pid); vp_stack_push_num(&_result, "%d", fd[0][1]); vp_stack_push_num(&_result, "%d", fd[1][0]); if (npipe == 3) { vp_stack_push_num(&_result, "%d", fd[2][0]); } return vp_stack_return(&_result); } /* DO NOT REACH HERE */ return NULL; /* error */ error: close_allfd(fd); return vp_stack_return_error(&_result, errfmt, strerror(errno)); child_error: dummy = write(STDOUT_FILENO, strerror(errno), strlen(strerror(errno))); _exit(EXIT_FAILURE); #undef VP_GOTO_ERROR }
const char * vp_pty_open(char *args) { #define VP_GOTO_ERROR(_fmt) do { errfmt = (_fmt); goto error; } while(0) vp_stack_t stack; int argc; int fd[3][2] = {{0}}; pid_t pid; struct winsize ws = {0, 0, 0, 0}; int dummy; int hstdin, hstderr, hstdout; int fdm; int npipe; char *errfmt; VP_RETURN_IF_FAIL(vp_stack_from_args(&stack, args)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &npipe)); if (npipe != 2 && npipe != 3) return vp_stack_return_error(&_result, "npipe range error. wrong pipes."); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%hu", &(ws.ws_col))); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%hu", &(ws.ws_row))); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &hstdin)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &hstdout)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &hstderr)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &argc)); /* Set pipe */ if (hstdin > 0) { fd[0][0] = hstdin; fd[0][1] = 0; } if (hstdout > 1) { fd[1][1] = hstdout; fd[1][0] = 0; } else if (hstdout == 1) { if (pipe(fd[1]) < 0) { VP_GOTO_ERROR("pipe() error: %s"); } } if (hstderr > 1) { fd[2][1] = hstderr; fd[2][0] = 0; } else if (npipe == 3) { if (hstderr == 1){ if (pipe(fd[2]) < 0) { VP_GOTO_ERROR("pipe() error: %s"); } } else if (hstderr == 0) { if (openpty(&fd[2][0], &fd[2][1], NULL, NULL, &ws) < 0) { VP_GOTO_ERROR("openpty() error: %s"); } VP_SET_NONBLOCK_IF_NEEDED(fd[2][0]); } } pid = forkpty(&fdm, NULL, NULL, &ws); if (pid < 0) { VP_GOTO_ERROR("fork() error: %s"); } else if (pid == 0) { /* child */ char **argv; int i; /* Close pipe */ if (fd[1][0] > 0) { close(fd[1][0]); } if (fd[2][0] > 0) { close(fd[2][0]); } if (fd[0][0] > 0) { if (dup2(fd[0][0], STDIN_FILENO) != STDIN_FILENO) { goto child_error; } close(fd[0][0]); } if (fd[1][1] > 0) { if (dup2(fd[1][1], STDOUT_FILENO) != STDOUT_FILENO) { goto child_error; } close(fd[1][1]); } if (fd[2][1] > 0) { if (dup2(fd[2][1], STDERR_FILENO) != STDERR_FILENO) { goto child_error; } close(fd[2][1]); } argv = malloc(sizeof(char *) * (argc+1)); if (argv == NULL) { goto child_error; } for (i = 0; i < argc; ++i) { if (vp_stack_pop_str(&stack, &(argv[i]))) { free(argv); goto child_error; } } argv[argc] = NULL; execv(argv[0], argv); /* error */ goto child_error; } else { /* parent */ if (fd[1][1] > 0) { close(fd[1][1]); } if (fd[2][1] > 0) { close(fd[2][1]); } if (hstdin == 0) { fd[0][1] = fdm; } if (hstdout == 0) { fd[1][0] = hstdin == 0 ? dup(fdm) : fdm; VP_SET_NONBLOCK_IF_NEEDED(fd[1][0]); } vp_stack_push_num(&_result, "%d", pid); vp_stack_push_num(&_result, "%d", fd[0][1]); vp_stack_push_num(&_result, "%d", fd[1][0]); if (npipe == 3) { vp_stack_push_num(&_result, "%d", fd[2][0]); } return vp_stack_return(&_result); } /* DO NOT REACH HERE */ return NULL; /* error */ error: close_allfd(fd); return vp_stack_return_error(&_result, errfmt, strerror(errno)); child_error: dummy = write(STDOUT_FILENO, strerror(errno), strlen(strerror(errno))); _exit(EXIT_FAILURE); #undef VP_GOTO_ERROR }
const char * vp_pty_open(char *args) { vp_stack_t stack; int argc; int fd[3][2]; pid_t pid; struct winsize ws = {0, 0, 0, 0}; int dummy; int hstdin, hstderr, hstdout; int fdm; int npipe; VP_RETURN_IF_FAIL(vp_stack_from_args(&stack, args)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &npipe)); if (npipe != 2 && npipe != 3) return vp_stack_return_error(&_result, "npipe range error. wrong pipes."); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%hu", &(ws.ws_col))); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%hu", &(ws.ws_row))); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &hstdin)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &hstdout)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &hstderr)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &argc)); /* Set pipe */ if (hstdin) { fd[0][0] = hstdin; fd[0][1] = 0; } if (hstdout == 1) { if (pipe(fd[1]) < 0) { return vp_stack_return_error(&_result, "pipe() error: %s", strerror(errno)); } } else if (hstdout) { fd[1][1] = hstdout; fd[1][0] = 0; } if (npipe == 3) { if (hstderr == 1) { if (pipe(fd[2]) < 0) { return vp_stack_return_error(&_result, "pipe() error: %s", strerror(errno)); } } else if (hstderr == 1) { fd[2][1] = hstderr; fd[2][0] = 0; } else { if (openpty(&fd[2][0], &fd[2][1], NULL, NULL, &ws) < 0) { return vp_stack_return_error(&_result, "openpty() error: %s", strerror(errno)); } } } pid = forkpty(&fdm, NULL, NULL, &ws); if (hstdin == 0) { fd[0][1] = fdm; } if (hstdout == 0) { fd[1][0] = fdm; } if (hstdin == 0 && hstdout == 0) { fd[1][0] = dup(fdm); } if (pid < 0) { return vp_stack_return_error(&_result, "fork() error: %s", strerror(errno)); } else if (pid == 0) { /* child */ char **argv; int i; /* Close pipe */ if (hstdout == 1) { close(fd[1][0]); } if (npipe == 3 && hstderr == 1) { close(fd[2][0]); } if (hstdin && fd[0][0] != STDIN_FILENO) { if (dup2(fd[0][0], STDIN_FILENO) != STDIN_FILENO) { goto child_error; } close(fd[0][0]); } if (hstdout && fd[1][1] != STDOUT_FILENO) { /* Set termios. */ if (dup2(fd[1][1], STDOUT_FILENO) != STDOUT_FILENO) { goto child_error; } close(fd[1][1]); } if (npipe == 3 && fd[2][1] != STDERR_FILENO) { if (dup2(fd[2][1], STDERR_FILENO) != STDERR_FILENO) { goto child_error; } close(fd[2][1]); } argv = malloc(sizeof(char *) * (argc+1)); if (argv == NULL) { goto child_error; } for (i = 0; i < argc; ++i) { if (vp_stack_pop_str(&stack, &(argv[i]))) { free(argv); goto child_error; } } argv[argc] = NULL; if (execvp(argv[0], argv) < 0) { /* error */ free(argv); goto child_error; } free(argv); } else { /* parent */ if (hstdout == 1) { close(fd[1][1]); } if (npipe == 3 && (hstderr == 0 || hstderr == 1)) { close(fd[2][1]); } vp_stack_push_num(&_result, "%d", pid); vp_stack_push_num(&_result, "%d", fd[0][1]); vp_stack_push_num(&_result, "%d", fd[1][0]); if (npipe == 3) { vp_stack_push_num(&_result, "%d", fd[2][0]); } return vp_stack_return(&_result); } /* DO NOT REACH HERE */ return NULL; /* error */ child_error: dummy = write(STDOUT_FILENO, strerror(errno), strlen(strerror(errno))); _exit(EXIT_FAILURE); }
const char * vp_pipe_open(char *args) { vp_stack_t stack; int npipe, hstdin, hstderr, hstdout; int argc; int fd[3][2]; pid_t pid; int dummy; VP_RETURN_IF_FAIL(vp_stack_from_args(&stack, args)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &npipe)); if (npipe != 2 && npipe != 3) return vp_stack_return_error(&_result, "npipe range error. wrong pipes."); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &hstdin)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &hstdout)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &hstderr)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &argc)); if (hstdin) { fd[0][0] = hstdin; fd[0][1] = 0; } else { if (pipe(fd[0]) < 0) { return vp_stack_return_error(&_result, "pipe() error: %s", strerror(errno)); } } if (hstdout) { fd[1][1] = hstdout; fd[1][0] = 0; } else { if (pipe(fd[1]) < 0) { return vp_stack_return_error(&_result, "pipe() error: %s", strerror(errno)); } } if (npipe == 3) { if (hstderr) { fd[2][1] = hstderr; fd[2][0] = 0; } else { if (pipe(fd[2]) < 0) { return vp_stack_return_error(&_result, "pipe() error: %s", strerror(errno)); } } } pid = fork(); if (pid < 0) { return vp_stack_return_error(&_result, "fork() error: %s", strerror(errno)); } else if (pid == 0) { /* child */ char **argv; int i; if (!hstdin) { close(fd[0][1]); } if (!hstdout) { close(fd[1][0]); } if (npipe == 3 && !hstderr) { close(fd[2][0]); } if (fd[0][0] != STDIN_FILENO) { if (dup2(fd[0][0], STDIN_FILENO) != STDIN_FILENO) { goto child_error; } close(fd[0][0]); } if (fd[1][1] != STDOUT_FILENO) { if (dup2(fd[1][1], STDOUT_FILENO) != STDOUT_FILENO) { goto child_error; } close(fd[1][1]); } if (npipe == 2) { if (dup2(STDOUT_FILENO, STDERR_FILENO) != STDERR_FILENO) { goto child_error; } } else if (fd[2][1] != STDERR_FILENO) { if (dup2(fd[2][1], STDERR_FILENO) != STDERR_FILENO) { goto child_error; } close(fd[2][1]); } argv = malloc(sizeof(char *) * (argc+1)); if (argv == NULL) { goto child_error; } for (i = 0; i < argc; ++i) { if (vp_stack_pop_str(&stack, &(argv[i]))) { free(argv); goto child_error; } } argv[argc] = NULL; if (execvp(argv[0], argv) < 0) { free(argv); goto child_error; } free(argv); } else { /* parent */ if (!hstdin) { close(fd[0][0]); } if (!hstdout) { close(fd[1][1]); } if (npipe == 3 && !hstderr) { close(fd[2][1]); } vp_stack_push_num(&_result, "%d", pid); vp_stack_push_num(&_result, "%d", fd[0][1]); vp_stack_push_num(&_result, "%d", fd[1][0]); if (npipe == 3) vp_stack_push_num(&_result, "%d", fd[2][0]); return vp_stack_return(&_result); } /* DO NOT REACH HEAR */ return NULL; /* error */ child_error: dummy = write(STDOUT_FILENO, strerror(errno), strlen(strerror(errno))); _exit(EXIT_FAILURE); }
const char * vp_file_open(char *args) { vp_stack_t stack; char *path; char *flags; int mode; /* used when flags have O_CREAT */ int f = 0; int fd; VP_RETURN_IF_FAIL(vp_stack_from_args(&stack, args)); VP_RETURN_IF_FAIL(vp_stack_pop_str(&stack, &path)); VP_RETURN_IF_FAIL(vp_stack_pop_str(&stack, &flags)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &mode)); #ifdef O_RDONLY if (strstr(flags, "O_RDONLY")) f |= O_RDONLY; #endif #ifdef O_WRONLY if (strstr(flags, "O_WRONLY")) f |= O_WRONLY; #endif #ifdef O_RDRW if (strstr(flags, "O_RDRW")) f |= O_RDWR; #endif #ifdef O_NONBLOCK if (strstr(flags, "O_NONBLOCK")) f |= O_NONBLOCK; #endif #ifdef O_APPEND if (strstr(flags, "O_APPEND")) f |= O_APPEND; #endif #ifdef O_CREAT if (strstr(flags, "O_CREAT")) f |= O_CREAT; #endif #ifdef O_EXCL if (strstr(flags, "O_EXCL")) f |= O_EXCL; #endif #ifdef O_TRUNC if (strstr(flags, "O_TRUNC")) f |= O_TRUNC; #endif #ifdef O_SHLOCK if (strstr(flags, "O_SHLOCK")) f |= O_SHLOCK; #endif #ifdef O_EXLOCK if (strstr(flags, "O_EXLOCK")) f |= O_EXLOCK; #endif #ifdef O_DIRECT if (strstr(flags, "O_DIRECT")) f |= O_DIRECT; #endif #ifdef O_FSYNC if (strstr(flags, "O_FSYNC")) f |= O_FSYNC; #endif #ifdef O_NOFOLLOW if (strstr(flags, "O_NOFOLLOW")) f |= O_NOFOLLOW; #endif #ifdef O_TEMPORARY if (strstr(flags, "O_TEMPORARY")) f |= O_TEMPORARY; #endif #ifdef O_RANDOM if (strstr(flags, "O_RANDOM")) f |= O_RANDOM; #endif #ifdef O_SEQUENTIAL if (strstr(flags, "O_SEQENTIAL")) f |= O_SEQUENTIAL; #endif #ifdef O_BINARY if (strstr(flags, "O_BINARY")) f |= O_BINARY; #endif #ifdef O_TEXT if (strstr(flags, "O_TEXT")) f |= O_TEXT; #endif #ifdef O_INHERIT if (strstr(flags, "O_INHERIT")) f |= O_INHERIT; #endif #ifdef _O_SHORT_LIVED if (strstr(flags, "O_SHORT_LIVED")) f |= _O_SHORT_LIVED; #endif fd = open(path, f, mode); if (fd == -1) return vp_stack_return_error(&_result, "open() error: %s", strerror(errno)); vp_stack_push_num(&_result, "%d", fd); return vp_stack_return(&_result); }
/* * http://support.microsoft.com/kb/190351/ */ const char * vp_pipe_open(char *args) { vp_stack_t stack; int npipe, hstdin, hstderr, hstdout; char *cmdline; HANDLE hInputWrite = INVALID_HANDLE_VALUE, hInputRead; HANDLE hOutputWrite, hOutputRead = INVALID_HANDLE_VALUE; HANDLE hErrorWrite, hErrorRead = INVALID_HANDLE_VALUE; SECURITY_ATTRIBUTES sa; PROCESS_INFORMATION pi; STARTUPINFO si; VP_RETURN_IF_FAIL(vp_stack_from_args(&stack, args)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &npipe)); if (npipe != 2 && npipe != 3) return vp_stack_return_error(&_result, "npipe range error"); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &hstdin)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &hstdout)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &hstderr)); VP_RETURN_IF_FAIL(vp_stack_pop_str(&stack, &cmdline)); sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; if (hstdin) { /* Get handle. */ hInputRead = (HANDLE)_get_osfhandle(hstdin); } else { HANDLE hInputWriteTmp; /* Create pipe. */ if (!CreatePipe(&hInputRead, &hInputWriteTmp, &sa, 0)) return vp_stack_return_error(&_result, "CreatePipe() error: %s", lasterror()); if (!DuplicateHandle(GetCurrentProcess(), hInputWriteTmp, GetCurrentProcess(), &hInputWrite, 0, FALSE, DUPLICATE_SAME_ACCESS)) return vp_stack_return_error(&_result, "DuplicateHandle() error: %s", lasterror()); if (!CloseHandle(hInputWriteTmp)) return vp_stack_return_error(&_result, "CloseHandle() error: %s", lasterror()); } if (hstdout) { /* Get handle. */ hOutputWrite = (HANDLE)_get_osfhandle(hstdout); } else { HANDLE hOutputReadTmp; /* Create pipe. */ if (!CreatePipe(&hOutputReadTmp, &hOutputWrite, &sa, 0)) return vp_stack_return_error(&_result, "CreatePipe() error: %s", lasterror()); if (!DuplicateHandle(GetCurrentProcess(), hOutputReadTmp, GetCurrentProcess(), &hOutputRead, 0, TRUE, DUPLICATE_SAME_ACCESS)) return vp_stack_return_error(&_result, "DuplicateHandle() error: %s", lasterror()); if (!CloseHandle(hOutputReadTmp)) return vp_stack_return_error(&_result, "CloseHandle() error: %s", lasterror()); } if (npipe == 2) { if (!DuplicateHandle(GetCurrentProcess(), hOutputWrite, GetCurrentProcess(), &hErrorWrite, 0, TRUE, DUPLICATE_SAME_ACCESS)) return vp_stack_return_error(&_result, "DuplicateHandle() error: %s", lasterror()); } else { if (hstderr) { /* Get handle. */ hErrorWrite = (HANDLE)_get_osfhandle(hstderr); } else { HANDLE hErrorReadTmp; /* Create pipe. */ if (!CreatePipe(&hErrorReadTmp, &hErrorWrite, &sa, 0)) return vp_stack_return_error(&_result, "CreatePipe() error: %s", lasterror()); if (!DuplicateHandle(GetCurrentProcess(), hErrorReadTmp, GetCurrentProcess(), &hErrorRead, 0, TRUE, DUPLICATE_SAME_ACCESS)) return vp_stack_return_error(&_result, "DuplicateHandle() error: %s", lasterror()); if (!CloseHandle(hErrorReadTmp)) return vp_stack_return_error(&_result, "CloseHandle() error: %s", lasterror()); } } ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); /*si.dwFlags = STARTF_USESTDHANDLES;*/ si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; si.hStdInput = hInputRead; si.hStdOutput = hOutputWrite; si.hStdError = hErrorWrite; if (!CreateProcess(NULL, cmdline, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) /*0, NULL, NULL, &si, &pi))*/ /*DETACHED_PROCESS, NULL, NULL, &si, &pi))*/ /*CREATE_NO_WINDOW, NULL, NULL, &si, &pi))*/ return vp_stack_return_error(&_result, "CreateProcess() error: %s %s", lasterror()); if (!CloseHandle(pi.hThread)) return vp_stack_return_error(&_result, "CloseHandle() error: %s", lasterror()); if (!CloseHandle(hInputRead)) return vp_stack_return_error(&_result, "CloseHandle() error: %s", lasterror()); if (!CloseHandle(hOutputWrite)) return vp_stack_return_error(&_result, "CloseHandle() error: %s", lasterror()); if (!CloseHandle(hErrorWrite)) return vp_stack_return_error(&_result, "CloseHandle() error: %s", lasterror()); vp_stack_push_num(&_result, "%p", pi.hProcess); vp_stack_push_num(&_result, "%d", hstdin ? 0 : _open_osfhandle((size_t)hInputWrite, 0)); vp_stack_push_num(&_result, "%d", hstdout ? 0 : _open_osfhandle((size_t)hOutputRead, _O_RDONLY)); if (npipe == 3) vp_stack_push_num(&_result, "%d", hstderr ? 0 : _open_osfhandle((size_t)hErrorRead, _O_RDONLY)); return vp_stack_return(&_result); }
const char * vp_pipe_open(char *args) { vp_stack_t stack; int npipe; int argc; char *argv[VP_ARGC_MAX]; int fd[3][2]; pid_t pid; int i; VP_RETURN_IF_FAIL(vp_stack_from_args(&stack, args)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &npipe)); if (npipe != 2 && npipe != 3) return vp_stack_return_error(&_result, "npipe range error. wrong pipes."); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &argc)); if (argc < 1 || VP_ARGC_MAX <= argc) return vp_stack_return_error(&_result, "argc range error. too many arguments. please use xargs."); for (i = 0; i < argc; ++i) VP_RETURN_IF_FAIL(vp_stack_pop_str(&stack, &(argv[i]))); argv[argc] = NULL; if (pipe(fd[0]) < 0 || pipe(fd[1]) < 0 || (npipe == 3 && pipe(fd[2]) < 0)) return vp_stack_return_error(&_result, "pipe() error: %s", strerror(errno)); pid = fork(); if (pid < 0) { return vp_stack_return_error(&_result, "fork() error: %s", strerror(errno)); } else if (pid == 0) { /* child */ close(fd[0][1]); close(fd[1][0]); if (npipe == 3) close(fd[2][0]); if (fd[0][0] != STDIN_FILENO) { if (dup2(fd[0][0], STDIN_FILENO) != STDIN_FILENO) { write(fd[1][1], strerror(errno), strlen(strerror(errno))); _exit(EXIT_FAILURE); } close(fd[0][0]); } if (fd[1][1] != STDOUT_FILENO) { if (dup2(fd[1][1], STDOUT_FILENO) != STDOUT_FILENO) { write(fd[1][1], strerror(errno), strlen(strerror(errno))); _exit(EXIT_FAILURE); } close(fd[1][1]); } if (npipe == 2) { if (dup2(STDOUT_FILENO, STDERR_FILENO) != STDERR_FILENO) { write(STDOUT_FILENO, strerror(errno), strlen(strerror(errno))); _exit(EXIT_FAILURE); } } else if (fd[2][1] != STDERR_FILENO) { if (dup2(fd[2][1], STDERR_FILENO) != STDERR_FILENO) { write(STDOUT_FILENO, strerror(errno), strlen(strerror(errno))); _exit(EXIT_FAILURE); } close(fd[2][1]); } if (execv(argv[0], argv) < 0) { /* error */ write(STDOUT_FILENO, strerror(errno), strlen(strerror(errno))); _exit(EXIT_FAILURE); } } else { /* parent */ close(fd[0][0]); close(fd[1][1]); if (npipe == 3) close(fd[2][1]); vp_stack_push_num(&_result, "%d", pid); vp_stack_push_num(&_result, "%d", fd[0][1]); vp_stack_push_num(&_result, "%d", fd[1][0]); if (npipe == 3) vp_stack_push_num(&_result, "%d", fd[2][0]); return vp_stack_return(&_result); } /* DO NOT REACH HEAR */ return NULL; }