| 91 | } |
| 92 | |
| 93 | int exec_sync(struct sip_msg* msg, str* command, str* input, |
| 94 | pv_spec_t *outvar, pv_spec_t *errvar) |
| 95 | { |
| 96 | |
| 97 | pid_t pid; |
| 98 | int ret = -1; |
| 99 | FILE *pin = NULL, *pout, *perr; |
| 100 | |
| 101 | if ((input && input->len && input->s) || outvar || errvar) { |
| 102 | pid = __popen3(command->s, (input&&input->len&&input->s) ? &pin : NULL, |
| 103 | outvar ? &pout : NULL, |
| 104 | errvar ? &perr : NULL); |
| 105 | } else { |
| 106 | pid = fork(); |
| 107 | if (pid == 0) { |
| 108 | close_open_fds(); |
| 109 | execl("/bin/sh", "/bin/sh", "-c", command->s, NULL); |
| 110 | exit(-1); |
| 111 | } else if (pid < 0) { |
| 112 | LM_ERR("fork failed\n"); |
| 113 | return -1; |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | if (input && input->len && pin) { |
| 118 | if (fwrite(input->s, 1, input->len, pin) != input->len) { |
| 119 | LM_ERR("failed to write to pipe\n"); |
| 120 | ser_error=E_EXEC; |
| 121 | goto error; |
| 122 | } |
| 123 | |
| 124 | if (ferror(pin)) { |
| 125 | ser_error=E_EXEC; |
| 126 | goto error; |
| 127 | } |
| 128 | |
| 129 | fclose(pin); |
| 130 | } |
| 131 | |
| 132 | schedule_to_kill(pid); |
| 133 | |
| 134 | if (outvar) { |
| 135 | if (read_and_write2var(msg, &pout, outvar) < 0) { |
| 136 | LM_ERR("failed reading stdout from pipe\n"); |
| 137 | goto error; |
| 138 | } |
| 139 | } |
| 140 | |
| 141 | if (errvar) { |
| 142 | if (read_and_write2var(msg, &perr, errvar) < 0) { |
| 143 | LM_ERR("failed reading stderr from pipe\n"); |
| 144 | goto error; |
| 145 | } |
| 146 | } |
| 147 | |
| 148 | ret=1; |
| 149 | |
| 150 | error: |
no test coverage detected