static void msg_write_response(int fd, rtsp_message *resp) { char pkt[1024]; int pktfree = sizeof(pkt); char *p = pkt; int i, n; n = snprintf(p, pktfree, "RTSP/1.0 %d %s\r\n", resp->respcode, resp->respcode==200 ? "OK" : "Error"); debug(1, "sending response: %s", pkt); pktfree -= n; p += n; for (i=0; i<resp->nheaders; i++) { debug(2, " %s: %s\n", resp->name[i], resp->value[i]); n = snprintf(p, pktfree, "%s: %s\r\n", resp->name[i], resp->value[i]); pktfree -= n; p += n; if (pktfree <= 0) die("Attempted to write overlong RTSP packet"); } if (pktfree < 3) die("Attempted to write overlong RTSP packet"); strcpy(p, "\r\n"); write_unchecked(fd, pkt, p-pkt+2); }
/* * Do a fork followed by a execvp, handling execvp errors correctly. * Return the pid of the new process upon success, or -1 if something failed. * Check errno for error details. */ static int fork_execvp(const char *file, char *const argv[]) { int execpipe[2]; int pid = 0; if (pipe(execpipe) < 0) { return -1; } if (fcntl(execpipe[1], F_SETFD, fcntl(execpipe[1], F_GETFD) | FD_CLOEXEC) < 0) { close(execpipe[0]); close(execpipe[1]); return -1; } pid = fork(); if (pid < 0) { close(execpipe[0]); close(execpipe[1]); return -1; } else if(pid == 0) { // Child close(execpipe[0]); // Close the read end execvp(file, argv); // If we reach this point then execve has failed. // Write erno's value into the pipe and exit. write_unchecked(execpipe[1], &errno, sizeof(errno)); _exit(-1); return 0; // Just to make the compiler happy. } else { // Parent close(execpipe[1]); // Close the write end int childErrno; // Block until child closes the pipe or sends errno. if(read(execpipe[0], &childErrno, sizeof(childErrno)) == sizeof(childErrno)) { // We received errno errno = childErrno; return -1; } else { // Child closed the pipe. execvp was successful. return pid; } } }