Prepare to write to the file *OUTNAME, using *TEMPNAME to store the name of the temporary file that will eventually be renamed to *OUTNAME. Assign the temporary file's name to both *OUTNAME and *TEMPNAME. If *TEMPNAME is null, allocate the name of any such temporary file; otherwise, reuse *TEMPNAME's storage, which is already set up and only needs its trailing suffix updated. */
| 1615 | *TEMPNAME. If *TEMPNAME is null, allocate the name of any such |
| 1616 | temporary file; otherwise, reuse *TEMPNAME's storage, which is |
| 1617 | already set up and only needs its trailing suffix updated. */ |
| 1618 | static FILE * |
| 1619 | open_outfile(char const **outname, char **tempname) |
| 1620 | { |
| 1621 | bool dirs_made = false; |
| 1622 | if (!*tempname) |
| 1623 | random_dirent(outname, tempname); |
| 1624 | |
| 1625 | for (;; check_for_signal()) { |
| 1626 | int oflags = O_WRONLY | O_BINARY | O_CREAT | O_EXCL; |
| 1627 | int fd = open(*outname, oflags, creat_perms); |
| 1628 | int err; |
| 1629 | if (fd < 0) |
| 1630 | err = errno; |
| 1631 | else { |
| 1632 | FILE *fp = fdopen(fd, "wb"); |
| 1633 | if (fp) |
| 1634 | return fp; |
| 1635 | err = errno; |
| 1636 | close(fd); |
| 1637 | } |
| 1638 | if (err == ENOENT && !dirs_made) { |
| 1639 | mkdirs(*outname, true); |
| 1640 | dirs_made = true; |
| 1641 | } else if (err == EEXIST) |
| 1642 | random_dirent(outname, tempname); |
| 1643 | else { |
| 1644 | fprintf(stderr, _("%s: Can't create %s%s%s: %s\n"), |
| 1645 | progname, diagdir(*outname), diagslash(*outname), *outname, |
| 1646 | strerror(err)); |
| 1647 | exit(EXIT_FAILURE); |
| 1648 | } |
| 1649 | } |
| 1650 | } |
| 1651 | |
| 1652 | /* If TEMPNAME, the result is in the temporary file TEMPNAME even |
no test coverage detected