basic/fileio: clean up executable_is_script() a bit
- Rename to script_get_shebang_interpreter and return -EMEDIUMTYPE if the executable is not a script. We nowadays utilize the scheme of making ret param of getters optional, and use them directly as checkers. - Don't unnecessarily read the whole line, but check only the shebang first.
This commit is contained in:
+35
-20
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "chase.h"
|
||||
#include "extract-word.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "fs-util.h"
|
||||
@@ -856,35 +857,49 @@ int read_full_file_full(
|
||||
return read_full_stream_full(f, filename, offset, size, flags, ret_contents, ret_size);
|
||||
}
|
||||
|
||||
int executable_is_script(const char *path, char **interpreter) {
|
||||
_cleanup_free_ char *line = NULL;
|
||||
size_t len;
|
||||
char *ans;
|
||||
int script_get_shebang_interpreter(const char *path, char **ret) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
|
||||
r = read_one_line_file(path, &line);
|
||||
if (r == -ENOBUFS) /* First line overly long? if so, then it's not a script */
|
||||
return 0;
|
||||
f = fopen(path, "re");
|
||||
if (!f)
|
||||
return -errno;
|
||||
|
||||
char c;
|
||||
r = safe_fgetc(f, &c);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return -EBADMSG;
|
||||
if (c != '#')
|
||||
return -EMEDIUMTYPE;
|
||||
r = safe_fgetc(f, &c);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return -EBADMSG;
|
||||
if (c != '!')
|
||||
return -EMEDIUMTYPE;
|
||||
|
||||
_cleanup_free_ char *line = NULL;
|
||||
r = read_line(f, LONG_LINE_MAX, &line);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!startswith(line, "#!"))
|
||||
return 0;
|
||||
_cleanup_free_ char *p = NULL;
|
||||
const char *s = line;
|
||||
|
||||
ans = strstrip(line + 2);
|
||||
len = strcspn(ans, " \t");
|
||||
r = extract_first_word(&s, &p, /* separators = */ NULL, /* flags = */ 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return -ENOEXEC;
|
||||
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
ans = strndup(ans, len);
|
||||
if (!ans)
|
||||
return -ENOMEM;
|
||||
|
||||
*interpreter = ans;
|
||||
return 1;
|
||||
if (ret)
|
||||
*ret = TAKE_PTR(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -94,7 +94,7 @@ static inline int verify_file(const char *fn, const char *blob, bool accept_extr
|
||||
return verify_file_at(AT_FDCWD, fn, blob, accept_extra_nl);
|
||||
}
|
||||
|
||||
int executable_is_script(const char *path, char **interpreter);
|
||||
int script_get_shebang_interpreter(const char *path, char **ret);
|
||||
|
||||
int get_proc_field(const char *filename, const char *pattern, const char *terminator, char **field);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user