Memory Management
authorMarkus Bröker <mbroeker@largo.dyndns.tv>
Thu, 16 Apr 2009 12:49:13 +0200
changeset 60 47c13ca8c4d0
parent 59 a7ba10b68915
child 61 4b4c97f179da
Memory Management * myprintf.c: Dynamic Memory allocation added * prog_limit: fixed a segfault committer: Markus Bröker <mbroeker@largo.homelinux.org>
myprintf.c
prog_limit.c
set_limit.c
--- a/myprintf.c
+++ b/myprintf.c
@@ -8,17 +8,23 @@
 #include <stdarg.h>
 #include <string.h>
 
+#define BUF_SIZE 1024
+
 int myprintf (char *fmt, ...)
 {
-    int i, pos = 0;
+    int i, value, pos = 0, size = 1;
+    char c;
+
+    char *ptr;
+    char *s;
+    char *s_str;
+    char v_str[28];
+
     va_list list;
 
-    char c;
-    char *s;
-    char s_str[1024];
-
-    char v[12];
-    int value;
+    if ((s_str = malloc (BUF_SIZE)) == NULL) {
+        return EOF;
+    }
 
     va_start (list, fmt);
 
@@ -29,35 +35,54 @@
             case 'c':
                 c = va_arg (list, int);
                 s_str[pos++] = c;
-                c = *fmt++;
                 break;
+
             case 's':
                 s = va_arg (list, char *);
+                while ((pos + strlen (s)) > (size * BUF_SIZE)) {
+                    if ((ptr = realloc (s_str, ++size * BUF_SIZE)) == NULL) {
+                        s_str[pos] = '\0';
+                        fputs (s_str, stdout);  /* print it anyway... */
+                        return EOF;
+                    }
+                    s_str = ptr;
+                }
                 for (i = 0; i < strlen (s); i++) {
                     s_str[pos++] = s[i];
                 }
-                c = *fmt++;
                 break;
+
             case 'd':
                 value = va_arg (list, int);
-                sprintf (v, "%d", value);
-                for (i = 0; i < strlen (v); i++) {
-                    s_str[pos++] = v[i];
+                sprintf (v_str, "%d", value);
+                for (i = 0; i < strlen (v_str); i++) {
+                    s_str[pos++] = v_str[i];
                 }
-                c = *fmt++;
                 break;
+
             default:
-                puts ("Unknown character");
+                s_str[pos++] = *fmt;
             }
+
+            c = *fmt++;
         default:
             s_str[pos++] = *fmt++;
         }
+
+        if (pos > (size * BUF_SIZE / 2)) {
+            if ((ptr = realloc (s_str, ++size * BUF_SIZE)) == NULL) {
+                return EOF;
+            }
+            s_str = ptr;
+        }
+
         va_end (list);
     }
 
     s_str[pos] = '\0';
+    fputs (s_str, stdout);
+    free (s_str);
 
-    puts (s_str);
     return pos;
 }
 
@@ -65,6 +90,7 @@
 {
     int len;
 
-    len = myprintf ("Bugfix needed: %s\t[%d:%d]", "Lines", 20, 30);
+    len = myprintf ("Printf replacement %% [Version %d - %s]...\n", 5, "LSF Rostock");
+
     return EXIT_SUCCESS;
 }
--- a/prog_limit.c
+++ b/prog_limit.c
@@ -6,8 +6,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include <sys/time.h>
-#include <sys/resource.h>
 
 int set_limit (int);
 
@@ -23,7 +21,7 @@
         return EXIT_FAILURE;
     }
 
-    if ((args = calloc ((argc - 2), sizeof (char *))) == NULL) {
+    if ((args = calloc ((argc - 1), sizeof (char *))) == NULL) {
         perror ("calloc");
         return EXIT_FAILURE;
     }
@@ -31,15 +29,17 @@
     for (i = 2; i < argc; i++)
         args[i - 2] = argv[i];
 
-    args[i] = NULL;
+    args[i - 2] = NULL;
 
-    if (set_limit (atoi (argv[1])) == 0)
-        execvp (argv[2], args);
-    else
+    if (set_limit (atoi (argv[1])) == 0) {
+        i = execvp (argv[2], args);
+    } else {
         perror ("Limit Error");
+        return EXIT_FAILURE;
+    }
 
     if (args != NULL)
         free (args);
 
-    return EXIT_SUCCESS;
+    return i;
 }
--- a/set_limit.c
+++ b/set_limit.c
@@ -3,9 +3,11 @@
  * Copyright (C) 2008 Markus Broeker
  */
 
-#include <sys/time.h>
+#include <errno.h>
 #include <sys/resource.h>
 
+#define MINIMUM (2*1024*1024)
+
 int set_limit (int megs)
 {
     struct rlimit rlim;
@@ -14,8 +16,10 @@
 
     rlim.rlim_cur = megs;
     rlim.rlim_max = 1.25 * megs;
-    if (megs > (4 * 1024 * 1024))
+    if (megs >= MINIMUM)
         return setrlimit (RLIMIT_AS, &rlim);
 
+    errno = ENOMEM;
+
     return -1;
 }