diff options
author | Junio C Hamano <gitster@pobox.com> | 2015-08-12 14:09:55 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2015-08-12 14:09:55 -0700 |
commit | 7aa2da616208a51ec51ce3639fe6abd9631b74db (patch) | |
tree | ecec6305390773f8f263f94e93d9c7bbf10521c8 /wrapper.c | |
parent | c1e5ca90dba834246e1fbac1c3ce9899873c22a5 (diff) | |
parent | e97a5e765db06995c3b027a5d7dceb6b4f2cba02 (diff) | |
download | git-7aa2da616208a51ec51ce3639fe6abd9631b74db.tar.gz |
Merge branch 'pt/am-builtin'
Rewrite "am" in "C".
* pt/am-builtin: (46 commits)
git-am: add am.threeWay config variable
builtin-am: remove redirection to git-am.sh
builtin-am: check for valid committer ident
builtin-am: implement legacy -b/--binary option
builtin-am: implement -i/--interactive
builtin-am: support and auto-detect mercurial patches
builtin-am: support and auto-detect StGit series files
builtin-am: support and auto-detect StGit patches
builtin-am: rerere support
builtin-am: invoke post-applypatch hook
builtin-am: invoke pre-applypatch hook
builtin-am: invoke applypatch-msg hook
builtin-am: support automatic notes copying
builtin-am: invoke post-rewrite hook
builtin-am: implement -S/--gpg-sign, commit.gpgsign
builtin-am: implement --committer-date-is-author-date
builtin-am: implement --ignore-date
builtin-am: pass git-apply's options to git-apply
builtin-am: implement --[no-]scissors
builtin-am: support --keep-cr, am.keepcr
...
Diffstat (limited to 'wrapper.c')
-rw-r--r-- | wrapper.c | 56 |
1 files changed, 56 insertions, 0 deletions
@@ -189,6 +189,41 @@ void *xcalloc(size_t nmemb, size_t size) # endif #endif +/** + * xopen() is the same as open(), but it die()s if the open() fails. + */ +int xopen(const char *path, int oflag, ...) +{ + mode_t mode = 0; + va_list ap; + + /* + * va_arg() will have undefined behavior if the specified type is not + * compatible with the argument type. Since integers are promoted to + * ints, we fetch the next argument as an int, and then cast it to a + * mode_t to avoid undefined behavior. + */ + va_start(ap, oflag); + if (oflag & O_CREAT) + mode = va_arg(ap, int); + va_end(ap); + + for (;;) { + int fd = open(path, oflag, mode); + if (fd >= 0) + return fd; + if (errno == EINTR) + continue; + + if ((oflag & O_RDWR) == O_RDWR) + die_errno(_("could not open '%s' for reading and writing"), path); + else if ((oflag & O_WRONLY) == O_WRONLY) + die_errno(_("could not open '%s' for writing"), path); + else + die_errno(_("could not open '%s' for reading"), path); + } +} + /* * xread() is the same a read(), but it automatically restarts read() * operations with a recoverable error (EAGAIN and EINTR). xread() @@ -311,6 +346,27 @@ int xdup(int fd) return ret; } +/** + * xfopen() is the same as fopen(), but it die()s if the fopen() fails. + */ +FILE *xfopen(const char *path, const char *mode) +{ + for (;;) { + FILE *fp = fopen(path, mode); + if (fp) + return fp; + if (errno == EINTR) + continue; + + if (*mode && mode[1] == '+') + die_errno(_("could not open '%s' for reading and writing"), path); + else if (*mode == 'w' || *mode == 'a') + die_errno(_("could not open '%s' for writing"), path); + else + die_errno(_("could not open '%s' for reading"), path); + } +} + FILE *xfdopen(int fd, const char *mode) { FILE *stream = fdopen(fd, mode); |