2008-01-28 21:37:16 +00:00
|
|
|
/* source: xio-creat.c */
|
2016-07-22 06:54:31 +00:00
|
|
|
/* Copyright Gerhard Rieger and contributors (see file CHANGES) */
|
2008-01-27 12:00:08 +00:00
|
|
|
/* Published under the GNU General Public License V.2, see file COPYING */
|
|
|
|
|
|
|
|
/* this file contains the source for opening addresses of create type */
|
|
|
|
|
|
|
|
#include "xiosysincludes.h"
|
|
|
|
|
|
|
|
#if WITH_CREAT
|
|
|
|
|
|
|
|
#include "xioopen.h"
|
|
|
|
#include "xio-named.h"
|
|
|
|
#include "xio-creat.h"
|
|
|
|
|
|
|
|
|
2023-07-13 07:06:35 +00:00
|
|
|
static int xioopen_creat(int arg, const char *argv[], struct opt *opts, int rw, xiofile_t *fd, const struct addrdesc *addrdesc);
|
2008-01-27 12:00:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
/*! within stream model, this is a write-only address - use 2 instead of 3 */
|
2023-06-21 18:44:29 +00:00
|
|
|
const struct addrdesc xioaddr_creat = { "CREATE", 1+XIO_WRONLY, xioopen_creat, GROUP_FD|GROUP_NAMED|GROUP_FILE, 0, 0, 0 HELP(":<filename>") };
|
2008-01-27 12:00:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* retrieve the mode option and perform the creat() call.
|
|
|
|
returns the file descriptor or a negative value. */
|
|
|
|
static int _xioopen_creat(const char *path, int rw, struct opt *opts) {
|
|
|
|
mode_t mode = 0666;
|
|
|
|
int fd;
|
|
|
|
|
|
|
|
retropt_modet(opts, OPT_PERM, &mode);
|
|
|
|
|
|
|
|
if ((fd = Creat(path, mode)) < 0) {
|
|
|
|
Error3("creat(\"%s\", 0%03o): %s",
|
|
|
|
path, mode, strerror(errno));
|
|
|
|
return STAT_RETRYLATER;
|
|
|
|
}
|
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-07-13 07:06:35 +00:00
|
|
|
static int xioopen_creat(
|
|
|
|
int argc,
|
|
|
|
const char *argv[],
|
|
|
|
struct opt *opts,
|
|
|
|
int xioflags,
|
|
|
|
xiofile_t *xxfd,
|
|
|
|
const struct addrdesc *addrdesc)
|
|
|
|
{
|
2023-07-13 07:06:08 +00:00
|
|
|
struct single *sfd = &xxfd->stream;
|
2008-01-27 12:00:08 +00:00
|
|
|
const char *filename = argv[1];
|
|
|
|
int rw = (xioflags&XIO_ACCMODE);
|
|
|
|
bool exists;
|
|
|
|
bool opt_unlink_close = false;
|
|
|
|
int result;
|
|
|
|
|
|
|
|
/* remove old file, or set user/permissions on old file; parse options */
|
2023-07-13 07:06:35 +00:00
|
|
|
if ((result =
|
|
|
|
_xioopen_named_early(argc, argv, xxfd, addrdesc->groups, &exists, opts,
|
|
|
|
addrdesc->syntax))
|
|
|
|
< 0) {
|
2008-01-27 12:00:08 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
|
|
|
if (opt_unlink_close) {
|
2023-07-13 07:06:08 +00:00
|
|
|
if ((sfd->unlink_close = strdup(filename)) == NULL) {
|
2008-01-27 12:00:08 +00:00
|
|
|
Error1("strdup(\"%s\"): out of memory", filename);
|
|
|
|
}
|
2023-07-13 07:06:08 +00:00
|
|
|
sfd->opt_unlink_close = true;
|
2008-01-27 12:00:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Notice2("creating regular file \"%s\" for %s", filename, ddirection[rw]);
|
|
|
|
if ((result = _xioopen_creat(filename, rw, opts)) < 0)
|
|
|
|
return result;
|
2023-07-13 07:06:08 +00:00
|
|
|
sfd->fd = result;
|
2008-01-27 12:00:08 +00:00
|
|
|
|
|
|
|
applyopts_named(filename, opts, PH_PASTOPEN);
|
2023-07-13 07:06:08 +00:00
|
|
|
if ((result = applyopts2(sfd, -1, opts, PH_PASTOPEN, PH_LATE2)) < 0)
|
2008-01-27 12:00:08 +00:00
|
|
|
return result;
|
|
|
|
|
2023-07-13 07:06:08 +00:00
|
|
|
applyopts_cloexec(sfd->fd, opts);
|
2008-01-27 12:00:08 +00:00
|
|
|
|
2023-07-13 07:06:08 +00:00
|
|
|
applyopts_fchown(sfd->fd, opts);
|
2008-01-27 12:00:08 +00:00
|
|
|
|
2023-07-13 07:06:08 +00:00
|
|
|
if ((result = _xio_openlate(sfd, opts)) < 0)
|
2008-01-27 12:00:08 +00:00
|
|
|
return result;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* WITH_CREAT */
|