| 203 | } |
| 204 | |
| 205 | struct tempfile *mks_tempfile_dt(const char *directory_template, |
| 206 | const char *filename) |
| 207 | { |
| 208 | struct tempfile *tempfile; |
| 209 | const char *tmpdir; |
| 210 | struct strbuf sb = STRBUF_INIT; |
| 211 | int fd; |
| 212 | size_t directorylen; |
| 213 | |
| 214 | if (!ends_with(directory_template, "XXXXXX")) { |
| 215 | errno = EINVAL; |
| 216 | return NULL; |
| 217 | } |
| 218 | |
| 219 | tmpdir = getenv("TMPDIR"); |
| 220 | if (!tmpdir) |
| 221 | tmpdir = "/tmp"; |
| 222 | |
| 223 | strbuf_addf(&sb, "%s/%s", tmpdir, directory_template); |
| 224 | directorylen = sb.len; |
| 225 | if (!mkdtemp(sb.buf)) { |
| 226 | int orig_errno = errno; |
| 227 | strbuf_release(&sb); |
| 228 | errno = orig_errno; |
| 229 | return NULL; |
| 230 | } |
| 231 | |
| 232 | strbuf_addf(&sb, "/%s", filename); |
| 233 | fd = open(sb.buf, O_CREAT | O_EXCL | O_RDWR, 0600); |
| 234 | if (fd < 0) { |
| 235 | int orig_errno = errno; |
| 236 | strbuf_setlen(&sb, directorylen); |
| 237 | rmdir(sb.buf); |
| 238 | strbuf_release(&sb); |
| 239 | errno = orig_errno; |
| 240 | return NULL; |
| 241 | } |
| 242 | |
| 243 | tempfile = new_tempfile(); |
| 244 | strbuf_swap(&tempfile->filename, &sb); |
| 245 | tempfile->directory = xmemdupz(tempfile->filename.buf, directorylen); |
| 246 | tempfile->fd = fd; |
| 247 | activate_tempfile(tempfile); |
| 248 | return tempfile; |
| 249 | } |
| 250 | |
| 251 | struct tempfile *xmks_tempfile_m(const char *filename_template, int mode) |
| 252 | { |
no test coverage detected