[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[tyndur-devel] [PATCH] Neue POSIX-Funktionen



+ truncate und ftruncate hinzugefügt

Signed-off-by: Arne Hasselbring <arne.hasselbring@xxxxxxxxxxxxxx>
---
 src/modules/include/unistd.h  |    6 +++
 src/modules/lib/posix/trunc.c |   88 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 94 insertions(+), 0 deletions(-)
 create mode 100644 src/modules/lib/posix/trunc.c

diff --git a/src/modules/include/unistd.h b/src/modules/include/unistd.h
index 3532f1a..db4e426 100644
--- a/src/modules/include/unistd.h
+++ b/src/modules/include/unistd.h
@@ -125,6 +125,12 @@ long alarm(long seconds);
 /// Gibt die Groesse einer Page zurueck
 int getpagesize(void);
 
+/// Datei auf eine bestimmte Länge setzen
+int truncate(const char *path, off_t length);
+
+/// Datei anhand des Deskriptors auf eine bestimmte Länge setzen
+int ftruncate(int fd, off_t length);
+
 /**
  * Einen symbolischen Link anlegen
  *
diff --git a/src/modules/lib/posix/trunc.c b/src/modules/lib/posix/trunc.c
new file mode 100644
index 0000000..df5e882
--- /dev/null
+++ b/src/modules/lib/posix/trunc.c
@@ -0,0 +1,88 @@
+#include <unistd.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+int truncate(const char *path, off_t length)
+{
+    FILE *handle = fopen(path, "a+");
+    if (handle == NULL) {
+	errno = ENOENT;
+	return -1;
+    }
+    fseek(handle, 0, SEEK_END);
+    int cur_len = ftell(handle);
+    int diff = length - cur_len;
+    if (diff == 0) {
+	return 0;
+    }
+    if (diff < 0) {
+	char *data = malloc(cur_len);
+	fseek(handle, 0, SEEK_SET);
+	fread(data, cur_len, 1, handle);
+	char *buffer = malloc(length);
+	memcpy(buffer, data, length);
+	free(data);
+	fclose(handle);
+	handle = fopen(path, "w");
+	fwrite(buffer, length, 1, handle);
+	free(buffer);
+	fclose(handle);
+	return 0;
+    } else if (diff > 0) {
+	fseek(handle, 0, SEEK_END);
+	int i;
+	for (i = 0; i < diff; i++) {
+	    fprintf(handle, "%c", 0);
+	}
+	fclose(handle);
+	return 0;
+    } else {
+	errno = EAGAIN;
+	return -1;
+    }
+}
+
+
+int ftruncate(int fd, off_t length)
+{
+    FILE *handle = fdopen(fd, "a+");
+    if (handle == NULL) {
+	errno = ENOENT;
+	return -1;
+    }
+    fseek(handle, 0, SEEK_END);
+    int cur_len = ftell(handle);
+    int diff = length - cur_len;
+    if (diff == 0) {
+	return 0;
+    }
+    if (diff < 0) {
+	char *data = malloc(cur_len);
+	fseek(handle, 0, SEEK_SET);
+	fread(data, cur_len, 1, handle);
+	char *buffer = malloc(length);
+	memcpy(buffer, data, length);
+	free(data);
+	fclose(handle);
+	remove(handle->path);
+	handle = fdopen(fd, "w");
+	fwrite(buffer, length, 1, handle);
+	free(buffer);
+	fclose(handle);
+	return 0;
+    } else if (diff > 0) {
+	fseek(handle, 0, SEEK_END);
+	int i;
+	for (i = 0; i < diff; i++) {
+	    fprintf(handle, "%c", 0);
+	}
+	fclose(handle);
+	return 0;
+    } else {
+	errno = EAGAIN;
+	return -1;
+    }
+}
-- 
1.7.1