glob(3)

๐ŸŒธ glob(3) โ€” bestie edition ๐ŸŒธ

okay so this is a page from the Library Functions Manual, section 3 (that's the library-call girlies ๐Ÿ’…), and it's all about finding pathnames that match a pattern and then cleaning up after yourself. let's get into it.


โœจ NAME โœจ

glob, globfree โ€” find pathnames matching a pattern, and free the memory from glob()

๐Ÿ“š LIBRARY ๐Ÿ“š

Standard C library (libc, -lc)

๐ŸŽ€ SYNOPSIS ๐ŸŽ€

#include <glob.h>

int glob(const char *restrict pattern, int flags,
         typeof(int (const char *epath, int eerrno)) *errfunc,
         glob_t *restrict pglob);
void globfree(glob_t *pglob);

๐Ÿ’– DESCRIPTION ๐Ÿ’–

so. glob() goes and finds all the pathnames that match pattern, following the exact same rules the shell uses (peep glob(7) for those rules, bestie). and listen โ€” it does not do tilde expansion and it does not do parameter substitution. if you wanted those, go use wordexp(3) instead, no cap.

globfree() frees the dynamically allocated storage from an earlier glob() call. it's the cleanup bestie. don't ghost it.

the results of a glob() call live in the structure pointed to by pglob. that structure is of type glob_t (declared in <glob.h>) and it includes these elements, defined by POSIX.2 (there might be more in there as an extension, she's got layers):

typedef struct {
    size_t   gl_pathc;    /* Count of paths matched so far  */
    char   **gl_pathv;    /* List of matched pathnames.  */
    size_t   gl_offs;     /* Slots to reserve in gl_pathv.  */
} glob_t;

results are stored in dynamically allocated storage, so yes you need globfree() after. periodt.

the flags argument is made up of the bitwise OR of zero or more of these symbolic constants, and they change how glob() behaves:

  • GLOB_ERR โ€” return as soon as there's a read error (like when a directory doesn't have read permission, for example). by default glob() just kinda carries on regardless, reading every directory it can. this flag says no, we're not doing that today ๐Ÿ™…
  • GLOB_MARK โ€” slap a slash on the end of every path that corresponds to a directory. cute little tell.
  • GLOB_NOSORT โ€” do not sort the returned pathnames. the only reason you'd ever do this is to save processing time. by default, the returned pathnames are sorted, and that's the vibe.
  • GLOB_DOOFFS โ€” reserve pglob->gl_offs slots at the beginning of the list of strings in pglob->pathv. those reserved slots contain null pointers, they're just empty seats.
  • GLOB_NOCHECK โ€” if nothing matches, return the original pattern itself. by default glob() returns GLOB_NOMATCH when there are no matches, she's honest like that.
  • GLOB_APPEND โ€” append this call's results to the vector of results from a previous glob() call. do not set this flag on the very first invocation, bestie, that's undefined-behavior-adjacent chaos, we don't do that.
  • GLOB_NOESCAPE โ€” don't let backslash ('\') be used as an escape character. normally a backslash can quote the next character, which is your mechanism for turning off the special meaning metacharacters have. turn that whole thing off with this flag.

flags may also include any of these, which are GNU extensions and not defined by POSIX.2:

  • GLOB_PERIOD โ€” let a leading period be matched by metacharacters. by default, metacharacters can't match a leading period. (you know, the whole hidden-file thing ๐Ÿ‘€)
  • GLOB_ALTDIRFUNC โ€” use alternative functions pglob->gl_closedir, pglob->gl_readdir, pglob->gl_opendir, pglob->gl_lstat, and pglob->gl_stat for filesystem access instead of the normal library functions.
  • GLOB_BRACE โ€” expand csh(1) style brace expressions of the form {a,b}. and yes they can be nested. so for example, specifying the pattern "{foo/{,cat,dog},bar}" would return the exact same results as four separate glob() calls using the strings: "foo/", "foo/cat", "foo/dog", and "bar". she's efficient like that โœจ
  • GLOB_NOMAGIC โ€” if the pattern contains no metacharacters at all, then it should be returned as the sole matching word, even if there's no file with that name. fake it till you make it.
  • GLOB_TILDE โ€” carry out tilde expansion. if a tilde ('~') is the only character in the pattern, or an initial tilde is followed immediately by a slash ('/'), then the home directory of the caller is substituted for the tilde. and if an initial tilde is followed by a username (like "~andrea/bin"), then the tilde and the username get substituted by that user's home directory. but if the username is invalid, or the home directory can't be determined, then no substitution is performed โ€” she just leaves it.
  • GLOB_TILDE_CHECK โ€” basically the same behavior as GLOB_TILDE, but the difference is that if the username is invalid, or the home directory can't be determined, then instead of using the pattern itself as the name, glob() returns GLOB_NOMATCH to indicate an error. she's telling you something went wrong instead of pretending.
  • GLOB_ONLYDIR โ€” this is just a hint to glob() that you only care about directories matching the pattern. if the implementation can easily determine file-type info, then nondirectory files are not returned to you. however โ€” and this is important โ€” you must still check that the returned files are directories. the purpose of this flag is merely to optimize performance when you only care about directories. it's a hint, not a promise, fr fr.

if errfunc is not NULL, it gets called in case of an error with the arguments epath (a pointer to the path that failed) and eerrno (the value of errno as returned from one of the calls to opendir(3), readdir(3), or stat(2)). and if errfunc returns nonzero, or if GLOB_ERR is set, then glob() will terminate after the call to errfunc. so if you error out, the party's over.

upon successful return, pglob->gl_pathc contains the number of matched pathnames, and pglob->gl_pathv contains a pointer to the list of pointers to matched pathnames. that list of pointers is terminated by a null pointer. classic.

it's totally possible to call glob() several times. in that case, the GLOB_APPEND flag has to be set in flags on the second and later invocations. no exceptions bestie.

and as a GNU extension, pglob->gl_flags is set to the flags you specified, ored with GLOB_MAGCHAR if any metacharacters were found.

๐Ÿซถ RETURN VALUE ๐Ÿซถ

on successful completion, glob() returns zero. other possible returns are:

  • GLOB_NOSPACE โ€” for running out of memory,
  • GLOB_ABORTED โ€” for a read error, and
  • GLOB_NOMATCH โ€” for no found matches.

๐Ÿ‘‘ ATTRIBUTES ๐Ÿ‘‘

for an explanation of the terms used in this section, see attributes(7).

  • glob() โ€” Thread safety โ€” MT-Unsafe race:utent env sig:ALRM timer locale
  • globfree() โ€” Thread safety โ€” MT-Safe

so in that table, utent in race:utent means that if any of the functions setutent(3), getutent(3), or endutent(3) are used in parallel in different threads of a program, then data races could occur. and glob() calls those functions, so we use race:utent to remind users. consider this your reminder ๐ŸŒˆ

โญ STANDARDS โญ

POSIX.1-2008.

๐Ÿฆ‹ HISTORY ๐Ÿฆ‹

POSIX.1-2001, POSIX.2.

๐Ÿ’œ NOTES ๐Ÿ’œ

the structure elements gl_pathc and gl_offs are declared as size_t in glibc 2.1, as they should be according to POSIX.2 โ€” but they're declared as int in glibc 2.0. glow-up of the century honestly.

๐Ÿ’€ BUGS ๐Ÿ’€

glob() may fail due to failure of underlying function calls, like malloc(3) or opendir(3). those will store their error code in errno. so yeah, always check errno, bestie, she's trying to tell you something.

๐Ÿ“ EXAMPLES ๐Ÿ“

one example of use is this code, which simulates typing

ls -l *.c ../*.c

in the shell:

glob_t globbuf;

globbuf.gl_offs = 2;
glob("*.c", GLOB_DOOFFS, NULL, &globbuf);
glob("../*.c", GLOB_DOOFFS | GLOB_APPEND, NULL, &globbuf);
globbuf.gl_pathv[0] = "ls";
globbuf.gl_pathv[1] = "-l";
execvp("ls", &globbuf.gl_pathv[0]);

that's the whole move, she ate ๐Ÿ’…

๐ŸŒˆ SEE ALSO ๐ŸŒˆ

ls(1), sh(1), stat(2), exec(3), fnmatch(3), malloc(3), opendir(3), readdir(3), wordexp(3), glob(7)


and that's the tea ๐Ÿงš from Linux man-pages 6.20, dated 2026-02-08. go forth and glob responsibly, bestie โ€” and remember to globfree() your memory or the vibe check will catch up with you ๐Ÿ˜ญ๐Ÿ’–

๐Ÿ“ฆ where this page comes from
  • arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
  • nixpkgs unstable: man-pages 6.20
  • ๐Ÿ“œ the page's license: Linux-man-pages-copyleft
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms