aboutsummaryrefslogtreecommitdiffstats
path: root/libasn1compiler
diff options
context:
space:
mode:
Diffstat (limited to 'libasn1compiler')
-rw-r--r--libasn1compiler/asn1c_compat.c9
-rw-r--r--libasn1compiler/asn1c_save.c51
-rw-r--r--libasn1compiler/asn1compiler.h5
3 files changed, 51 insertions, 14 deletions
diff --git a/libasn1compiler/asn1c_compat.c b/libasn1compiler/asn1c_compat.c
index 2a80251a..b393d6d2 100644
--- a/libasn1compiler/asn1c_compat.c
+++ b/libasn1compiler/asn1c_compat.c
@@ -80,12 +80,19 @@ asn1c_open_file(const char *name, const char *ext, char **opt_tmpname) {
if(fp == NULL) {
if(created) unlink(fname);
close(fd);
+ return NULL;
}
/* Return the temporary file name */
if(opt_tmpname) {
*opt_tmpname = strdup(fname);
- assert(*opt_tmpname);
+ if(*opt_tmpname) {
+ /* Successfull */
+ } else {
+ if(created) unlink(fname);
+ fclose(fp);
+ return NULL;
+ }
}
return fp;
diff --git a/libasn1compiler/asn1c_save.c b/libasn1compiler/asn1c_save.c
index e0a2f671..d35db940 100644
--- a/libasn1compiler/asn1c_save.c
+++ b/libasn1compiler/asn1c_save.c
@@ -280,6 +280,8 @@ asn1c_save_streams(arg_t *arg, asn1c_fdeps_t *deps) {
if(rename(tmpname_c, name_buf)) {
unlink(tmpname_c);
perror(tmpname_c);
+ free(tmpname_c);
+ free(tmpname_h);
return -1;
}
}
@@ -292,6 +294,8 @@ asn1c_save_streams(arg_t *arg, asn1c_fdeps_t *deps) {
if(rename(tmpname_h, name_buf)) {
unlink(tmpname_h);
perror(tmpname_h);
+ free(tmpname_c);
+ free(tmpname_h);
return -1;
}
}
@@ -308,11 +312,20 @@ asn1c_save_streams(arg_t *arg, asn1c_fdeps_t *deps) {
static int
identical_files(const char *fname1, const char *fname2) {
- char buf[2][8192];
+ char buf[2][4096];
FILE *fp1, *fp2;
size_t olen, nlen;
int retval = 1; /* Files are identical */
+#ifndef WIN32
+ struct stat sb;
+
+ if(lstat(fname1, &sb) || !S_ISREG(sb.st_mode)
+ || lstat(fname2, &sb) || !S_ISREG(sb.st_mode)) {
+ return 0; /* Files are not identical */
+ }
+#endif
+
fp1 = fopen(fname1, "r");
if(!fp1) { return 0; }
fp2 = fopen(fname2, "r");
@@ -338,7 +351,8 @@ identical_files(const char *fname1, const char *fname2) {
*/
static int
real_copy(const char *src, const char *dst) {
- unsigned char buf[8192];
+ unsigned char buf[4096];
+ char *tmpname;
FILE *fpsrc, *fpdst;
size_t len;
int retval = 0;
@@ -348,36 +362,45 @@ real_copy(const char *src, const char *dst) {
fpsrc = fopen(src, "r");
if(!fpsrc) { errno = EIO; return -1; }
- fpdst = asn1c_open_file(dst, "", 0);
+ fpdst = asn1c_open_file(dst, "", &tmpname);
if(!fpdst) { fclose(fpsrc); errno = EIO; return -1; }
while(!feof(fpsrc)) {
len = fread(buf, 1, sizeof(buf), fpsrc);
if(fwrite(buf, 1, len, fpdst) != len) {
+ perror(tmpname);
errno = EIO;
retval = -1;
break;
}
}
-
fclose(fpsrc);
fclose(fpdst);
+
+ /* Check if copied correctly, and rename into a permanent name */
+ if(retval) {
+ unlink(tmpname);
+ } else if(rename(tmpname, dst)) {
+ unlink(tmpname);
+ perror(tmpname);
+ retval = -1;
+ }
+ free(tmpname);
return retval;
}
static int
asn1c_copy_over(arg_t *arg, char *path) {
char *fname;
-
- (void)arg; /* Unused argument */
-
- fname = a1c_basename(path);
- if(!fname
#ifdef WIN32
- || real_copy(path, fname)
+ int use_real_copy = 1;
#else
- || (1 ? symlink(path, fname) : real_copy(path, fname))
+ int use_real_copy = (arg->flags & A1C_SKELETONS_COPY);
#endif
+
+ fname = a1c_basename(path);
+ if(!fname
+ || (use_real_copy ? real_copy(path, fname) : symlink(path, fname))
) {
if(errno == EEXIST) {
struct stat sb1, sb2;
@@ -402,13 +425,15 @@ asn1c_copy_over(arg_t *arg, char *path) {
/* Ignore this */
return 0;
} else {
- fprintf(stderr, "Symlink %s -> %s failed: %s\n",
+ fprintf(stderr, "%s %s -> %s failed: %s\n",
+ use_real_copy ? "Copy" : "Symlink",
path, fname, strerror(errno));
return -1;
}
}
- fprintf(stderr, "Symlinked %s\t-> %s\n", path, fname);
+ fprintf(stderr, "%s %s\t-> %s\n",
+ use_real_copy ? "Copied" : "Symlinked", path, fname);
return 1;
}
diff --git a/libasn1compiler/asn1compiler.h b/libasn1compiler/asn1compiler.h
index e688018a..847300ff 100644
--- a/libasn1compiler/asn1compiler.h
+++ b/libasn1compiler/asn1compiler.h
@@ -51,6 +51,11 @@ enum asn1c_flags {
* Compile members of CHOICE as indirect pointers.
*/
A1C_INDIRECT_CHOICE = 0x0400,
+ /*
+ * -fskeletons-copy
+ * Copy support files rather than symlink them.
+ */
+ A1C_SKELETONS_COPY = 0x0800,
};
/*