Changeset View
Changeset View
Standalone View
Standalone View
head/contrib/elftoolchain/elfcopy/main.c
Show First 20 Lines • Show All 204 Lines • ▼ Show 20 Lines | static struct { | ||||
{"openvms", ELFOSABI_OPENVMS}, | {"openvms", ELFOSABI_OPENVMS}, | ||||
{"nsk", ELFOSABI_NSK}, | {"nsk", ELFOSABI_NSK}, | ||||
{"arm", ELFOSABI_ARM}, | {"arm", ELFOSABI_ARM}, | ||||
{"standalone", ELFOSABI_STANDALONE}, | {"standalone", ELFOSABI_STANDALONE}, | ||||
{NULL, 0} | {NULL, 0} | ||||
}; | }; | ||||
static int copy_from_tempfile(const char *src, const char *dst, | static int copy_from_tempfile(const char *src, const char *dst, | ||||
int infd, int *outfd); | int infd, int *outfd, int in_place); | ||||
static void create_file(struct elfcopy *ecp, const char *src, | static void create_file(struct elfcopy *ecp, const char *src, | ||||
const char *dst); | const char *dst); | ||||
static void elfcopy_main(struct elfcopy *ecp, int argc, char **argv); | static void elfcopy_main(struct elfcopy *ecp, int argc, char **argv); | ||||
static void elfcopy_usage(void); | static void elfcopy_usage(void); | ||||
static void mcs_main(struct elfcopy *ecp, int argc, char **argv); | static void mcs_main(struct elfcopy *ecp, int argc, char **argv); | ||||
static void mcs_usage(void); | static void mcs_usage(void); | ||||
static void parse_sec_address_op(struct elfcopy *ecp, int optnum, | static void parse_sec_address_op(struct elfcopy *ecp, int optnum, | ||||
const char *optname, char *s); | const char *optname, char *s); | ||||
▲ Show 20 Lines • Show All 296 Lines • ▼ Show 20 Lines | #define _TEMPFILEPATH "/tmp/ecp.XXXXXXXX" | ||||
if (fchmod(*fd, 0644) == -1) | if (fchmod(*fd, 0644) == -1) | ||||
err(EXIT_FAILURE, "fchmod %s failed", tmpf); | err(EXIT_FAILURE, "fchmod %s failed", tmpf); | ||||
*fn = tmpf; | *fn = tmpf; | ||||
#undef _TEMPFILE | #undef _TEMPFILE | ||||
#undef _TEMPFILEPATH | #undef _TEMPFILEPATH | ||||
} | } | ||||
/* | |||||
* Copy temporary file with path src and file descriptor infd to path dst. | |||||
* If in_place is set act as if editing the file in place, avoiding rename() | |||||
* to preserve hard and symbolic links. Output file remains open, with file | |||||
* descriptor returned in outfd. | |||||
*/ | |||||
static int | static int | ||||
copy_from_tempfile(const char *src, const char *dst, int infd, int *outfd) | copy_from_tempfile(const char *src, const char *dst, int infd, int *outfd, | ||||
int in_place) | |||||
{ | { | ||||
int tmpfd; | int tmpfd; | ||||
/* | /* | ||||
* First, check if we can use rename(). | * First, check if we can use rename(). | ||||
*/ | */ | ||||
if (in_place == 0) { | |||||
if (rename(src, dst) >= 0) { | if (rename(src, dst) >= 0) { | ||||
*outfd = infd; | *outfd = infd; | ||||
return (0); | return (0); | ||||
} else if (errno != EXDEV) | } else if (errno != EXDEV) | ||||
return (-1); | return (-1); | ||||
/* | /* | ||||
* If the rename() failed due to 'src' and 'dst' residing in | * If the rename() failed due to 'src' and 'dst' residing in | ||||
* two different file systems, invoke a helper function in | * two different file systems, invoke a helper function in | ||||
* libelftc to do the copy. | * libelftc to do the copy. | ||||
*/ | */ | ||||
if (unlink(dst) < 0) | if (unlink(dst) < 0) | ||||
return (-1); | return (-1); | ||||
} | |||||
if ((tmpfd = open(dst, O_CREAT | O_WRONLY, 0755)) < 0) | if ((tmpfd = open(dst, O_CREAT | O_TRUNC | O_WRONLY, 0755)) < 0) | ||||
return (-1); | return (-1); | ||||
if (lseek(infd, 0, SEEK_SET) < 0) | |||||
return (-1); | |||||
if (elftc_copyfile(infd, tmpfd) < 0) | if (elftc_copyfile(infd, tmpfd) < 0) | ||||
return (-1); | return (-1); | ||||
/* | /* | ||||
* Remove the temporary file from the file system | * Remove the temporary file from the file system | ||||
* namespace, and close its file descriptor. | * namespace, and close its file descriptor. | ||||
*/ | */ | ||||
if (unlink(src) < 0) | if (unlink(src) < 0) | ||||
Show All 10 Lines | |||||
} | } | ||||
static void | static void | ||||
create_file(struct elfcopy *ecp, const char *src, const char *dst) | create_file(struct elfcopy *ecp, const char *src, const char *dst) | ||||
{ | { | ||||
struct stat sb; | struct stat sb; | ||||
char *tempfile, *elftemp; | char *tempfile, *elftemp; | ||||
int efd, ifd, ofd, ofd0, tfd; | int efd, ifd, ofd, ofd0, tfd; | ||||
int in_place; | |||||
tempfile = NULL; | tempfile = NULL; | ||||
if (src == NULL) | if (src == NULL) | ||||
errx(EXIT_FAILURE, "internal: src == NULL"); | errx(EXIT_FAILURE, "internal: src == NULL"); | ||||
if ((ifd = open(src, O_RDONLY)) == -1) | if ((ifd = open(src, O_RDONLY)) == -1) | ||||
err(EXIT_FAILURE, "open %s failed", src); | err(EXIT_FAILURE, "open %s failed", src); | ||||
▲ Show 20 Lines • Show All 124 Lines • ▼ Show 20 Lines | #endif | ||||
elf_end(ecp->ein); | elf_end(ecp->ein); | ||||
#ifndef LIBELF_AR | #ifndef LIBELF_AR | ||||
copy_done: | copy_done: | ||||
#endif | #endif | ||||
if (tempfile != NULL) { | if (tempfile != NULL) { | ||||
if (dst == NULL) | in_place = 0; | ||||
if (dst == NULL) { | |||||
dst = src; | dst = src; | ||||
if (lstat(dst, &sb) != -1 && | |||||
(sb.st_nlink > 1 || S_ISLNK(sb.st_mode))) | |||||
in_place = 1; | |||||
} | |||||
if (copy_from_tempfile(tempfile, dst, ofd, &tfd) < 0) | if (copy_from_tempfile(tempfile, dst, ofd, &tfd, in_place) < 0) | ||||
err(EXIT_FAILURE, "creation of %s failed", dst); | err(EXIT_FAILURE, "creation of %s failed", dst); | ||||
free(tempfile); | free(tempfile); | ||||
tempfile = NULL; | tempfile = NULL; | ||||
ofd = tfd; | ofd = tfd; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 769 Lines • Show Last 20 Lines |