[PATCH 3/9] Remove VIR_STRNDUP usage that subtracts from a non-NULL pointer

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

 



Use g_strndup in all the cases where we check upfront whether a pointer
is non-NULL and then use it to calculate the copied length.

Signed-off-by: Ján Tomko <jtomko@xxxxxxxxxx>
---
 src/util/virsysinfo.c | 241 ++++++++++++++++++++----------------------
 1 file changed, 112 insertions(+), 129 deletions(-)

diff --git a/src/util/virsysinfo.c b/src/util/virsysinfo.c
index 9d013067fe..635e4c4bfb 100644
--- a/src/util/virsysinfo.c
+++ b/src/util/virsysinfo.c
@@ -220,23 +220,23 @@ virSysinfoParsePPCSystem(const char *base, virSysinfoSystemDefPtr *sysdef)
     cur = strchr(cur, ':') + 1;
     eol = strchr(cur, '\n');
     virSkipSpaces(&cur);
-    if (eol && VIR_STRNDUP(def->family, cur, eol - cur) < 0)
-        goto cleanup;
+    if (eol)
+        def->family = g_strndup(cur, eol - cur);
 
     if ((cur = strstr(base, "model")) != NULL) {
         cur = strchr(cur, ':') + 1;
         eol = strchr(cur, '\n');
         virSkipSpaces(&cur);
-        if (eol && VIR_STRNDUP(def->serial, cur, eol - cur) < 0)
-            goto cleanup;
+        if (eol)
+            def->serial = g_strndup(cur, eol - cur);
     }
 
     if ((cur = strstr(base, "machine")) != NULL) {
         cur = strchr(cur, ':') + 1;
         eol = strchr(cur, '\n');
         virSkipSpaces(&cur);
-        if (eol && VIR_STRNDUP(def->version, cur, eol - cur) < 0)
-            goto cleanup;
+        if (eol)
+            def->version = g_strndup(cur, eol - cur);
     }
 
     if (!def->manufacturer && !def->product && !def->version &&
@@ -248,7 +248,6 @@ virSysinfoParsePPCSystem(const char *base, virSysinfoSystemDefPtr *sysdef)
     *sysdef = def;
     def = NULL;
     ret = 0;
- cleanup:
     virSysinfoSystemDefFree(def);
     return ret;
 }
@@ -270,18 +269,17 @@ virSysinfoParsePPCProcessor(const char *base, virSysinfoDefPtr ret)
         processor = &ret->processor[ret->nprocessor - 1];
 
         virSkipSpaces(&cur);
-        if (eol && VIR_STRNDUP(processor->processor_socket_destination,
-                               cur, eol - cur) < 0)
-            return -1;
+        if (eol)
+            processor->processor_socket_destination = g_strndup(cur,
+                                                                eol - cur);
         base = cur;
 
         if ((cur = strstr(base, "cpu")) != NULL) {
             cur = strchr(cur, ':') + 1;
             eol = strchr(cur, '\n');
             virSkipSpaces(&cur);
-            if (eol && VIR_STRNDUP(processor->processor_type,
-                                   cur, eol - cur) < 0)
-                return -1;
+            if (eol)
+                processor->processor_type = g_strndup(cur, eol - cur);
             base = cur;
         }
 
@@ -289,9 +287,8 @@ virSysinfoParsePPCProcessor(const char *base, virSysinfoDefPtr ret)
             cur = strchr(cur, ':') + 1;
             eol = strchr(cur, '\n');
             virSkipSpaces(&cur);
-            if (eol && VIR_STRNDUP(processor->processor_version,
-                                   cur, eol - cur) < 0)
-                return -1;
+            if (eol)
+                processor->processor_version = g_strndup(cur, eol - cur);
             base = cur;
         }
 
@@ -354,23 +351,23 @@ virSysinfoParseARMSystem(const char *base, virSysinfoSystemDefPtr *sysdef)
     cur = strchr(cur, ':') + 1;
     eol = strchr(cur, '\n');
     virSkipSpaces(&cur);
-    if (eol && VIR_STRNDUP(def->family, cur, eol - cur) < 0)
-        goto cleanup;
+    if (eol)
+        def->family = g_strndup(cur, eol - cur);
 
     if ((cur = strstr(base, "model")) != NULL) {
         cur = strchr(cur, ':') + 1;
         eol = strchr(cur, '\n');
         virSkipSpaces(&cur);
-        if (eol && VIR_STRNDUP(def->serial, cur, eol - cur) < 0)
-            goto cleanup;
+        if (eol)
+            def->serial = g_strndup(cur, eol - cur);
     }
 
     if ((cur = strstr(base, "machine")) != NULL) {
         cur = strchr(cur, ':') + 1;
         eol = strchr(cur, '\n');
         virSkipSpaces(&cur);
-        if (eol && VIR_STRNDUP(def->version, cur, eol - cur) < 0)
-            goto cleanup;
+        if (eol)
+            def->version = g_strndup(cur, eol - cur);
     }
 
     if (!def->manufacturer && !def->product && !def->version &&
@@ -382,7 +379,6 @@ virSysinfoParseARMSystem(const char *base, virSysinfoSystemDefPtr *sysdef)
     *sysdef = def;
     def = NULL;
     ret = 0;
- cleanup:
     virSysinfoSystemDefFree(def);
     return ret;
 }
@@ -402,8 +398,8 @@ virSysinfoParseARMProcessor(const char *base, virSysinfoDefPtr ret)
     eol = strchr(tmp_base, '\n');
     cur = strchr(tmp_base, ':') + 1;
     virSkipSpaces(&cur);
-    if (eol && VIR_STRNDUP(processor_type, cur, eol - cur) < 0)
-        goto error;
+    if (eol)
+        processor_type = g_strndup(cur, eol - cur);
 
     while ((tmp_base = strstr(base, "processor")) != NULL) {
         base = tmp_base;
@@ -415,10 +411,9 @@ virSysinfoParseARMProcessor(const char *base, virSysinfoDefPtr ret)
         processor = &ret->processor[ret->nprocessor - 1];
 
         virSkipSpaces(&cur);
-        if (eol &&
-            VIR_STRNDUP(processor->processor_socket_destination,
-                        cur, eol - cur) < 0)
-            goto error;
+        if (eol)
+            processor->processor_socket_destination = g_strndup(cur,
+                                                                eol - cur);
 
         processor->processor_type = g_strdup(processor_type);
 
@@ -670,29 +665,29 @@ virSysinfoParseBIOS(const char *base, virSysinfoBIOSDefPtr *bios)
         cur += 8;
         eol = strchr(cur, '\n');
         virSkipSpacesBackwards(cur, &eol);
-        if (eol && VIR_STRNDUP(def->vendor, cur, eol - cur) < 0)
-            goto cleanup;
+        if (eol)
+            def->vendor = g_strndup(cur, eol - cur);
     }
     if ((cur = strstr(base, "Version: ")) != NULL) {
         cur += 9;
         eol = strchr(cur, '\n');
         virSkipSpacesBackwards(cur, &eol);
-        if (eol && VIR_STRNDUP(def->version, cur, eol - cur) < 0)
-            goto cleanup;
+        if (eol)
+            def->version = g_strndup(cur, eol - cur);
     }
     if ((cur = strstr(base, "Release Date: ")) != NULL) {
         cur += 14;
         eol = strchr(cur, '\n');
         virSkipSpacesBackwards(cur, &eol);
-        if (eol && VIR_STRNDUP(def->date, cur, eol - cur) < 0)
-            goto cleanup;
+        if (eol)
+            def->date = g_strndup(cur, eol - cur);
     }
     if ((cur = strstr(base, "BIOS Revision: ")) != NULL) {
         cur += 15;
         eol = strchr(cur, '\n');
         virSkipSpacesBackwards(cur, &eol);
-        if (eol && VIR_STRNDUP(def->release, cur, eol - cur) < 0)
-            goto cleanup;
+        if (eol)
+            def->release = g_strndup(cur, eol - cur);
     }
 
     if (!def->vendor && !def->version &&
@@ -704,7 +699,6 @@ virSysinfoParseBIOS(const char *base, virSysinfoBIOSDefPtr *bios)
     *bios = def;
     def = NULL;
     ret = 0;
- cleanup:
     virSysinfoBIOSDefFree(def);
     return ret;
 }
@@ -728,50 +722,50 @@ virSysinfoParseX86System(const char *base, virSysinfoSystemDefPtr *sysdef)
         cur += 14;
         eol = strchr(cur, '\n');
         virSkipSpacesBackwards(cur, &eol);
-        if (eol && VIR_STRNDUP(def->manufacturer, cur, eol - cur) < 0)
-            goto cleanup;
+        if (eol)
+            def->manufacturer = g_strndup(cur, eol - cur);
     }
     if ((cur = strstr(base, "Product Name: ")) != NULL) {
         cur += 14;
         eol = strchr(cur, '\n');
         virSkipSpacesBackwards(cur, &eol);
-        if (eol && VIR_STRNDUP(def->product, cur, eol - cur) < 0)
-            goto cleanup;
+        if (eol)
+            def->product = g_strndup(cur, eol - cur);
     }
     if ((cur = strstr(base, "Version: ")) != NULL) {
         cur += 9;
         eol = strchr(cur, '\n');
         virSkipSpacesBackwards(cur, &eol);
-        if (eol && VIR_STRNDUP(def->version, cur, eol - cur) < 0)
-            goto cleanup;
+        if (eol)
+            def->version = g_strndup(cur, eol - cur);
     }
     if ((cur = strstr(base, "Serial Number: ")) != NULL) {
         cur += 15;
         eol = strchr(cur, '\n');
         virSkipSpacesBackwards(cur, &eol);
-        if (eol && VIR_STRNDUP(def->serial, cur, eol - cur) < 0)
-            goto cleanup;
+        if (eol)
+            def->serial = g_strndup(cur, eol - cur);
     }
     if ((cur = strstr(base, "UUID: ")) != NULL) {
         cur += 6;
         eol = strchr(cur, '\n');
         virSkipSpacesBackwards(cur, &eol);
-        if (eol && VIR_STRNDUP(def->uuid, cur, eol - cur) < 0)
-            goto cleanup;
+        if (eol)
+            def->uuid = g_strndup(cur, eol - cur);
     }
     if ((cur = strstr(base, "SKU Number: ")) != NULL) {
         cur += 12;
         eol = strchr(cur, '\n');
         virSkipSpacesBackwards(cur, &eol);
-        if (eol && VIR_STRNDUP(def->sku, cur, eol - cur) < 0)
-            goto cleanup;
+        if (eol)
+            def->sku = g_strndup(cur, eol - cur);
     }
     if ((cur = strstr(base, "Family: ")) != NULL) {
         cur += 8;
         eol = strchr(cur, '\n');
         virSkipSpacesBackwards(cur, &eol);
-        if (eol && VIR_STRNDUP(def->family, cur, eol - cur) < 0)
-            goto cleanup;
+        if (eol)
+            def->family = g_strndup(cur, eol - cur);
     }
 
     if (!def->manufacturer && !def->product && !def->version &&
@@ -783,7 +777,6 @@ virSysinfoParseX86System(const char *base, virSysinfoSystemDefPtr *sysdef)
     *sysdef = def;
     def = NULL;
     ret = 0;
- cleanup:
     virSysinfoSystemDefFree(def);
     return ret;
 }
@@ -813,43 +806,43 @@ virSysinfoParseX86BaseBoard(const char *base,
             cur += 14;
             eol = strchr(cur, '\n');
             virSkipSpacesBackwards(cur, &eol);
-            if (eol && VIR_STRNDUP(def->manufacturer, cur, eol - cur) < 0)
-                goto cleanup;
+            if (eol)
+                def->manufacturer = g_strndup(cur, eol - cur);
         }
         if ((cur = strstr(base, "Product Name: ")) != NULL) {
             cur += 14;
             eol = strchr(cur, '\n');
             virSkipSpacesBackwards(cur, &eol);
-            if (eol && VIR_STRNDUP(def->product, cur, eol - cur) < 0)
-                goto cleanup;
+            if (eol)
+                def->product = g_strndup(cur, eol - cur);
         }
         if ((cur = strstr(base, "Version: ")) != NULL) {
             cur += 9;
             eol = strchr(cur, '\n');
             virSkipSpacesBackwards(cur, &eol);
-            if (eol && VIR_STRNDUP(def->version, cur, eol - cur) < 0)
-                goto cleanup;
+            if (eol)
+                def->version = g_strndup(cur, eol - cur);
         }
         if ((cur = strstr(base, "Serial Number: ")) != NULL) {
             cur += 15;
             eol = strchr(cur, '\n');
             virSkipSpacesBackwards(cur, &eol);
-            if (eol && VIR_STRNDUP(def->serial, cur, eol - cur) < 0)
-                goto cleanup;
+            if (eol)
+                def->serial = g_strndup(cur, eol - cur);
         }
         if ((cur = strstr(base, "Asset Tag: ")) != NULL) {
             cur += 11;
             eol = strchr(cur, '\n');
             virSkipSpacesBackwards(cur, &eol);
-            if (eol && VIR_STRNDUP(def->asset, cur, eol - cur) < 0)
-                goto cleanup;
+            if (eol)
+                def->asset = g_strndup(cur, eol - cur);
         }
         if ((cur = strstr(base, "Location In Chassis: ")) != NULL) {
             cur += 21;
             eol = strchr(cur, '\n');
             virSkipSpacesBackwards(cur, &eol);
-            if (eol && VIR_STRNDUP(def->location, cur, eol - cur) < 0)
-                goto cleanup;
+            if (eol)
+                def->location = g_strndup(cur, eol - cur);
         }
 
         if (!def->manufacturer && !def->product && !def->version &&
@@ -898,36 +891,36 @@ virSysinfoParseX86Chassis(const char *base,
         cur += 14;
         eol = strchr(cur, '\n');
         virSkipSpacesBackwards(cur, &eol);
-        if (eol && VIR_STRNDUP(def->manufacturer, cur, eol - cur) < 0)
-            goto cleanup;
+        if (eol)
+            def->manufacturer = g_strndup(cur, eol - cur);
     }
     if ((cur = strstr(base, "Version: ")) != NULL) {
         cur += 9;
         eol = strchr(cur, '\n');
         virSkipSpacesBackwards(cur, &eol);
-        if (eol && VIR_STRNDUP(def->version, cur, eol - cur) < 0)
-            goto cleanup;
+        if (eol)
+            def->version = g_strndup(cur, eol - cur);
     }
     if ((cur = strstr(base, "Serial Number: ")) != NULL) {
         cur += 15;
         eol = strchr(cur, '\n');
         virSkipSpacesBackwards(cur, &eol);
-        if (eol && VIR_STRNDUP(def->serial, cur, eol - cur) < 0)
-            goto cleanup;
+        if (eol)
+            def->serial = g_strndup(cur, eol - cur);
     }
     if ((cur = strstr(base, "Asset Tag: ")) != NULL) {
         cur += 11;
         eol = strchr(cur, '\n');
         virSkipSpacesBackwards(cur, &eol);
-        if (eol && VIR_STRNDUP(def->asset, cur, eol - cur) < 0)
-            goto cleanup;
+        if (eol)
+            def->asset = g_strndup(cur, eol - cur);
     }
     if ((cur = strstr(base, "SKU Number: ")) != NULL) {
         cur += 12;
         eol = strchr(cur, '\n');
         virSkipSpacesBackwards(cur, &eol);
-        if (eol && VIR_STRNDUP(def->sku, cur, eol - cur) < 0)
-            goto cleanup;
+        if (eol)
+            def->sku = g_strndup(cur, eol - cur);
     }
 
     if (!def->manufacturer && !def->version &&
@@ -939,7 +932,6 @@ virSysinfoParseX86Chassis(const char *base,
     *chassisdef = def;
     def = NULL;
     ret = 0;
- cleanup:
     virSysinfoChassisDefFree(def);
     return ret;
 }
@@ -964,86 +956,80 @@ virSysinfoParseX86Processor(const char *base, virSysinfoDefPtr ret)
             cur += 20;
             eol = strchr(cur, '\n');
             virSkipSpacesBackwards(cur, &eol);
-            if (eol && VIR_STRNDUP(processor->processor_socket_destination,
-                                   cur, eol - cur) < 0)
-                return -1;
+            if (eol)
+                processor->processor_socket_destination = g_strndup(cur,
+                                                                    eol - cur);
         }
         if ((cur = strstr(base, "Type: ")) != NULL) {
             cur += 6;
             eol = strchr(cur, '\n');
             virSkipSpacesBackwards(cur, &eol);
-            if (eol && VIR_STRNDUP(processor->processor_type, cur, eol - cur) < 0)
-                return -1;
+            if (eol)
+                processor->processor_type = g_strndup(cur, eol - cur);
         }
         if ((cur = strstr(base, "Family: ")) != NULL) {
             cur += 8;
             eol = strchr(cur, '\n');
             virSkipSpacesBackwards(cur, &eol);
-            if (eol && VIR_STRNDUP(processor->processor_family, cur, eol - cur) < 0)
-                return -1;
+            if (eol)
+                processor->processor_family = g_strndup(cur, eol - cur);
         }
         if ((cur = strstr(base, "Manufacturer: ")) != NULL) {
             cur += 14;
             eol = strchr(cur, '\n');
             virSkipSpacesBackwards(cur, &eol);
-            if (eol && VIR_STRNDUP(processor->processor_manufacturer,
-                                   cur, eol - cur) < 0)
-                return -1;
+            if (eol)
+                processor->processor_manufacturer = g_strndup(cur, eol - cur);
         }
         if ((cur = strstr(base, "Signature: ")) != NULL) {
             cur += 11;
             eol = strchr(cur, '\n');
             virSkipSpacesBackwards(cur, &eol);
-            if (eol && VIR_STRNDUP(processor->processor_signature,
-                                   cur, eol - cur) < 0)
-                return -1;
+            if (eol)
+                processor->processor_signature = g_strndup(cur, eol - cur);
         }
         if ((cur = strstr(base, "Version: ")) != NULL) {
             cur += 9;
             eol = strchr(cur, '\n');
             virSkipSpacesBackwards(cur, &eol);
-            if (eol && VIR_STRNDUP(processor->processor_version,
-                                   cur, eol - cur) < 0)
-                return -1;
+            if (eol)
+                processor->processor_version = g_strndup(cur, eol - cur);
         }
         if ((cur = strstr(base, "External Clock: ")) != NULL) {
             cur += 16;
             eol = strchr(cur, '\n');
             virSkipSpacesBackwards(cur, &eol);
-            if (eol && VIR_STRNDUP(processor->processor_external_clock,
-                                   cur, eol - cur) < 0)
-                return -1;
+            if (eol)
+                processor->processor_external_clock = g_strndup(cur,
+                                                                eol - cur);
         }
         if ((cur = strstr(base, "Max Speed: ")) != NULL) {
             cur += 11;
             eol = strchr(cur, '\n');
             virSkipSpacesBackwards(cur, &eol);
-            if (eol && VIR_STRNDUP(processor->processor_max_speed,
-                                   cur, eol - cur) < 0)
-                return -1;
+            if (eol)
+                processor->processor_max_speed = g_strndup(cur, eol - cur);
         }
         if ((cur = strstr(base, "Status: ")) != NULL) {
             cur += 8;
             eol = strchr(cur, '\n');
             virSkipSpacesBackwards(cur, &eol);
-            if (eol && VIR_STRNDUP(processor->processor_status, cur, eol - cur) < 0)
-                return -1;
+            if (eol)
+                processor->processor_status = g_strndup(cur, eol - cur);
         }
         if ((cur = strstr(base, "Serial Number: ")) != NULL) {
             cur += 15;
             eol = strchr(cur, '\n');
             virSkipSpacesBackwards(cur, &eol);
-            if (eol && VIR_STRNDUP(processor->processor_serial_number,
-                                   cur, eol - cur) < 0)
-                return -1;
+            if (eol)
+                processor->processor_serial_number = g_strndup(cur, eol - cur);
         }
         if ((cur = strstr(base, "Part Number: ")) != NULL) {
             cur += 13;
             eol = strchr(cur, '\n');
             virSkipSpacesBackwards(cur, &eol);
-            if (eol && VIR_STRNDUP(processor->processor_part_number,
-                                   cur, eol - cur) < 0)
-                return -1;
+            if (eol)
+                processor->processor_part_number = g_strndup(cur, eol - cur);
         }
 
         base += strlen("Processor Information");
@@ -1074,74 +1060,71 @@ virSysinfoParseX86Memory(const char *base, virSysinfoDefPtr ret)
                 goto next;
 
             virSkipSpacesBackwards(cur, &eol);
-            if (eol && VIR_STRNDUP(memory->memory_size, cur, eol - cur) < 0)
-                return -1;
+            if (eol)
+                memory->memory_size = g_strndup(cur, eol - cur);
         }
         if ((cur = strstr(base, "Form Factor: ")) != NULL) {
             cur += 13;
             eol = strchr(cur, '\n');
             virSkipSpacesBackwards(cur, &eol);
-            if (eol && VIR_STRNDUP(memory->memory_form_factor,
-                                   cur, eol - cur) < 0)
-                return -1;
+            if (eol)
+                memory->memory_form_factor = g_strndup(cur, eol - cur);
         }
         if ((cur = strstr(base, "Locator: ")) != NULL) {
             cur += 9;
             eol = strchr(cur, '\n');
             virSkipSpacesBackwards(cur, &eol);
-            if (eol && VIR_STRNDUP(memory->memory_locator, cur, eol - cur) < 0)
-                return -1;
+            if (eol)
+                memory->memory_locator = g_strndup(cur, eol - cur);
         }
         if ((cur = strstr(base, "Bank Locator: ")) != NULL) {
             cur += 14;
             eol = strchr(cur, '\n');
             virSkipSpacesBackwards(cur, &eol);
-            if (eol && VIR_STRNDUP(memory->memory_bank_locator,
-                                   cur, eol - cur) < 0)
-                return -1;
+            if (eol)
+                memory->memory_bank_locator = g_strndup(cur, eol - cur);
         }
         if ((cur = strstr(base, "Type: ")) != NULL) {
             cur += 6;
             eol = strchr(cur, '\n');
             virSkipSpacesBackwards(cur, &eol);
-            if (eol && VIR_STRNDUP(memory->memory_type, cur, eol - cur) < 0)
-                return -1;
+            if (eol)
+                memory->memory_type = g_strndup(cur, eol - cur);
         }
         if ((cur = strstr(base, "Type Detail: ")) != NULL) {
             cur += 13;
             eol = strchr(cur, '\n');
             virSkipSpacesBackwards(cur, &eol);
-            if (eol && VIR_STRNDUP(memory->memory_type_detail, cur, eol - cur) < 0)
-                return -1;
+            if (eol)
+                memory->memory_type_detail = g_strndup(cur, eol - cur);
         }
         if ((cur = strstr(base, "Speed: ")) != NULL) {
             cur += 7;
             eol = strchr(cur, '\n');
             virSkipSpacesBackwards(cur, &eol);
-            if (eol && VIR_STRNDUP(memory->memory_speed, cur, eol - cur) < 0)
-                return -1;
+            if (eol)
+                memory->memory_speed = g_strndup(cur, eol - cur);
         }
         if ((cur = strstr(base, "Manufacturer: ")) != NULL) {
             cur += 14;
             eol = strchr(cur, '\n');
             virSkipSpacesBackwards(cur, &eol);
-            if (eol && VIR_STRNDUP(memory->memory_manufacturer, cur, eol - cur) < 0)
-                return -1;
+            if (eol)
+                memory->memory_manufacturer = g_strndup(cur, eol - cur);
         }
         if ((cur = strstr(base, "Serial Number: ")) != NULL) {
             cur += 15;
             eol = strchr(cur, '\n');
             virSkipSpacesBackwards(cur, &eol);
-            if (eol && VIR_STRNDUP(memory->memory_serial_number,
-                                   cur, eol - cur) < 0)
-                return -1;
+            if (eol)
+                memory->memory_serial_number = g_strndup(cur, eol - cur);
         }
         if ((cur = strstr(base, "Part Number: ")) != NULL) {
             cur += 13;
             eol = strchr(cur, '\n');
             virSkipSpacesBackwards(cur, &eol);
-            if (eol && VIR_STRNDUP(memory->memory_part_number, cur, eol - cur) < 0)
-                return -1;
+            if (eol)
+                memory->memory_part_number = g_strndup(cur, eol - cur);
         }
 
     next:
-- 
2.21.0

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux