mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-09 05:58:01 +02:00
ifcfg-rh: refactor svOpenFile() to use nm_utils_fd_get_contents()
Use nm_utils_fd_get_contents() which has precisely all the steps implemented to read data from a file descriptor. There is a downside to this: previously you could compile shvar.c without nm-core-utils.c. Now, the ifcfg implementation gained a dependency on NM core utils. That would matter if we one day would like to build shvar.c without core NetworkManager utils (but that is not planned).
This commit is contained in:
parent
1bfbe9383f
commit
ca3cb90fc2
1 changed files with 62 additions and 68 deletions
|
|
@ -37,6 +37,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "nm-core-internal.h"
|
#include "nm-core-internal.h"
|
||||||
|
#include "nm-core-utils.h"
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
@ -63,10 +64,10 @@ typedef struct {
|
||||||
} shvarLine;
|
} shvarLine;
|
||||||
|
|
||||||
struct _shvarFile {
|
struct _shvarFile {
|
||||||
char *fileName; /* read-only */
|
char *fileName;
|
||||||
int fd; /* read-only */
|
int fd;
|
||||||
GList *lineList; /* read-only */
|
GList *lineList;
|
||||||
gboolean modified; /* ignore */
|
gboolean modified;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
@ -618,6 +619,17 @@ out_error:
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static shvarFile *
|
||||||
|
svFile_new (const char *name)
|
||||||
|
{
|
||||||
|
shvarFile *s;
|
||||||
|
|
||||||
|
s = g_slice_new0 (shvarFile);
|
||||||
|
s->fd = -1;
|
||||||
|
s->fileName = g_strdup (name);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
svFileGetName (const shvarFile *s)
|
svFileGetName (const shvarFile *s)
|
||||||
{
|
{
|
||||||
|
|
@ -764,82 +776,67 @@ line_free (shvarLine *line)
|
||||||
static shvarFile *
|
static shvarFile *
|
||||||
svOpenFileInternal (const char *name, gboolean create, GError **error)
|
svOpenFileInternal (const char *name, gboolean create, GError **error)
|
||||||
{
|
{
|
||||||
shvarFile *s = NULL;
|
shvarFile *s;
|
||||||
gboolean closefd = FALSE;
|
gboolean closefd = FALSE;
|
||||||
int errsv = 0;
|
int errsv = 0;
|
||||||
|
char *arena;
|
||||||
|
const char *p, *q;
|
||||||
|
GError *local = NULL;
|
||||||
|
nm_auto_close int fd = -1;
|
||||||
|
GList *lineList = NULL;
|
||||||
|
|
||||||
s = g_slice_new0 (shvarFile);
|
|
||||||
|
|
||||||
s->fd = -1;
|
|
||||||
if (create)
|
if (create)
|
||||||
s->fd = open (name, O_RDWR | O_CLOEXEC); /* NOT O_CREAT */
|
fd = open (name, O_RDWR | O_CLOEXEC); /* NOT O_CREAT */
|
||||||
|
if (fd < 0) {
|
||||||
if (!create || s->fd == -1) {
|
|
||||||
/* try read-only */
|
/* try read-only */
|
||||||
s->fd = open (name, O_RDONLY | O_CLOEXEC); /* NOT O_CREAT */
|
fd = open (name, O_RDONLY | O_CLOEXEC); /* NOT O_CREAT */
|
||||||
if (s->fd == -1)
|
if (fd < 0)
|
||||||
errsv = errno;
|
errsv = errno;
|
||||||
else
|
else
|
||||||
closefd = TRUE;
|
closefd = TRUE;
|
||||||
}
|
}
|
||||||
s->fileName = g_strdup (name);
|
|
||||||
|
|
||||||
if (s->fd != -1) {
|
if (fd < 0) {
|
||||||
struct stat buf;
|
if (create)
|
||||||
char *arena, *p, *q;
|
return svFile_new (name);
|
||||||
ssize_t nread, total = 0;
|
|
||||||
|
|
||||||
if (fstat (s->fd, &buf) < 0) {
|
g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errsv),
|
||||||
errsv = errno;
|
"Could not read file '%s': %s",
|
||||||
goto bail;
|
name, strerror (errsv));
|
||||||
}
|
return NULL;
|
||||||
arena = g_malloc (buf.st_size + 1);
|
|
||||||
arena[buf.st_size] = '\0';
|
|
||||||
|
|
||||||
while (total < buf.st_size) {
|
|
||||||
nread = read (s->fd, arena + total, buf.st_size - total);
|
|
||||||
if (nread == -1 && errno == EINTR)
|
|
||||||
continue;
|
|
||||||
if (nread <= 0) {
|
|
||||||
errsv = errno;
|
|
||||||
g_free (arena);
|
|
||||||
goto bail;
|
|
||||||
}
|
|
||||||
total += nread;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* we'd use g_strsplit() here, but we want a list, not an array */
|
|
||||||
for (p = arena; (q = strchr (p, '\n')) != NULL; p = q + 1)
|
|
||||||
s->lineList = g_list_prepend (s->lineList, line_new_parse (p, q - p));
|
|
||||||
if (p[0])
|
|
||||||
s->lineList = g_list_prepend (s->lineList, line_new_parse (p, strlen (p)));
|
|
||||||
g_free (arena);
|
|
||||||
s->lineList = g_list_reverse (s->lineList);
|
|
||||||
|
|
||||||
/* closefd is set if we opened the file read-only, so go ahead and
|
|
||||||
* close it, because we can't write to it anyway
|
|
||||||
*/
|
|
||||||
if (closefd) {
|
|
||||||
close (s->fd);
|
|
||||||
s->fd = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (create)
|
if (nm_utils_fd_get_contents (fd,
|
||||||
return s;
|
10 * 1024 * 1024,
|
||||||
|
&arena,
|
||||||
|
NULL,
|
||||||
|
&local) < 0) {
|
||||||
|
g_set_error (error, G_FILE_ERROR,
|
||||||
|
local->domain == G_FILE_ERROR ? local->code : G_FILE_ERROR_FAILED,
|
||||||
|
"Could not read file '%s': %s",
|
||||||
|
name, local->message);
|
||||||
|
g_error_free (local);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
bail:
|
for (p = arena; (q = strchr (p, '\n')) != NULL; p = q + 1)
|
||||||
if (s->fd != -1)
|
lineList = g_list_prepend (lineList, line_new_parse (p, q - p));
|
||||||
close (s->fd);
|
if (p[0])
|
||||||
g_free (s->fileName);
|
lineList = g_list_prepend (lineList, line_new_parse (p, strlen (p)));
|
||||||
g_slice_free (shvarFile, s);
|
g_free (arena);
|
||||||
|
lineList = g_list_reverse (lineList);
|
||||||
|
|
||||||
g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errsv),
|
s = svFile_new (name);
|
||||||
"Could not read file '%s': %s",
|
s->lineList = lineList;
|
||||||
name, errsv ? strerror (errsv) : "Unknown error");
|
|
||||||
return NULL;
|
/* closefd is set if we opened the file read-only, so go ahead and
|
||||||
|
* close it, because we can't write to it anyway */
|
||||||
|
if (!closefd) {
|
||||||
|
s->fd = fd;
|
||||||
|
fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open the file <name>, return shvarFile on success, NULL on failure */
|
/* Open the file <name>, return shvarFile on success, NULL on failure */
|
||||||
|
|
@ -1152,8 +1149,6 @@ svWriteFile (shvarFile *s, int mode, GError **error)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Close the file descriptor (if open) and free the shvarFile. */
|
|
||||||
void
|
void
|
||||||
svCloseFile (shvarFile *s)
|
svCloseFile (shvarFile *s)
|
||||||
{
|
{
|
||||||
|
|
@ -1161,7 +1156,6 @@ svCloseFile (shvarFile *s)
|
||||||
|
|
||||||
if (s->fd != -1)
|
if (s->fd != -1)
|
||||||
close (s->fd);
|
close (s->fd);
|
||||||
|
|
||||||
g_free (s->fileName);
|
g_free (s->fileName);
|
||||||
g_list_free_full (s->lineList, (GDestroyNotify) line_free);
|
g_list_free_full (s->lineList, (GDestroyNotify) line_free);
|
||||||
g_slice_free (shvarFile, s);
|
g_slice_free (shvarFile, s);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue