/* * m_mktemp.c -- Construct a temporary file. * * $Id: m_mktemp.c,v 1.4 2002/07/02 22:09:14 kenh Exp $ * * This code is Copyright (c) 2010, by the authors of nmh. See the * COPYRIGHT file in the root directory of the nmh distribution for * complete copyright information. */ #include #include char * m_mktemp ( const char *pfx_in, /* Pathname prefix for temporary file. */ int *fd_ret, /* (return,optional) File descriptor to temp file. */ FILE **fp_ret /* (return,optional) FILE pointer to temp file. */ ) { static char tmpfil[BUFSIZ]; const char *pfx = (pfx_in == NULL) ? "/tmp/nmh" : pfx_in; int fd = -1; int keep_open = 0; snprintf(tmpfil, sizeof(tmpfil), "%sXXXXXX", pfx); fd = mkstemp(tmpfil); if (fd < 0) { return NULL; } if (fd_ret != NULL) { *fd_ret = fd; keep_open = 1; } if (fp_ret != NULL) { FILE *fp = fdopen(fd, "w+"); if (fp == NULL) { int olderr = errno; unlink(tmpfil); close(fd); errno = olderr; return NULL; } *fp_ret = fp; keep_open = 1; } if (!keep_open) { close(fd); } return tmpfil; } /* This version allows one to specify the directory the temp file should * by created based on a given pathname. The pfx_in parameter specifies * a basename prefix for the file. If dir_in is NULL, then the system * temporary directory will be used for containing the temporary file. */ char * m_mktemp2 ( const char *dir_in, /* Directory to place temp file. */ const char *pfx_in, /* Basename prefix for temp file. */ int *fd_ret, /* (return,optional) File descriptor to temp file. */ FILE **fp_ret /* (return,optional) FILE pointer to temp file. */ ) { static char buffer[BUFSIZ]; char *cp; if (dir_in == NULL) { if (pfx_in == NULL) { return m_mktemp(NULL, fd_ret, fp_ret); } snprintf(buffer, sizeof(buffer), "/tmp/%s", pfx_in); return m_mktemp(buffer, fd_ret, fp_ret); } if ((cp = r1bindex ((char *)dir_in, '/')) == dir_in) { /* No directory component */ return m_mktemp(pfx_in, fd_ret, fp_ret); } int n = (int)(cp-dir_in-1); /* Length of dir component */ snprintf(buffer, sizeof(buffer), "%.*s%s", n, dir_in, pfx_in); return m_mktemp(buffer, fd_ret, fp_ret); }