| 231 | */ |
| 232 | |
| 233 | cups_file_t * /* O - CUPS file or NULL on error */ |
| 234 | cupsdPipeCommand(int *pid, /* O - Process ID or 0 on error */ |
| 235 | const char *command, /* I - Command to run */ |
| 236 | char **argv, /* I - Arguments to pass to command */ |
| 237 | uid_t user) /* I - User to run as or 0 for current */ |
| 238 | { |
| 239 | int fd, /* Temporary file descriptor */ |
| 240 | fds[2]; /* Pipe file descriptors */ |
| 241 | |
| 242 | |
| 243 | /* |
| 244 | * First create the pipe... |
| 245 | */ |
| 246 | |
| 247 | if (pipe(fds)) |
| 248 | { |
| 249 | *pid = 0; |
| 250 | return (NULL); |
| 251 | } |
| 252 | |
| 253 | /* |
| 254 | * Set the "close on exec" flag on each end of the pipe... |
| 255 | */ |
| 256 | |
| 257 | if (fcntl(fds[0], F_SETFD, fcntl(fds[0], F_GETFD) | FD_CLOEXEC)) |
| 258 | { |
| 259 | close(fds[0]); |
| 260 | close(fds[1]); |
| 261 | |
| 262 | *pid = 0; |
| 263 | |
| 264 | return (NULL); |
| 265 | } |
| 266 | |
| 267 | if (fcntl(fds[1], F_SETFD, fcntl(fds[1], F_GETFD) | FD_CLOEXEC)) |
| 268 | { |
| 269 | close(fds[0]); |
| 270 | close(fds[1]); |
| 271 | |
| 272 | *pid = 0; |
| 273 | |
| 274 | return (NULL); |
| 275 | } |
| 276 | |
| 277 | /* |
| 278 | * Then run the command... |
| 279 | */ |
| 280 | |
| 281 | if ((*pid = fork()) < 0) |
| 282 | { |
| 283 | /* |
| 284 | * Unable to fork! |
| 285 | */ |
| 286 | |
| 287 | *pid = 0; |
| 288 | close(fds[0]); |
| 289 | close(fds[1]); |
| 290 |
no test coverage detected