With such a question, the first thing you should do is reading
file manpage (
man 1 file).
As said in its documentation:
The filesystem tests are based on examining the return from a stat(2) system
call. The program checks to see if the file is empty, or if it's some sort of
special file. Any known file types appropriate to the system you are running
on (sockets, symbolic links, or named pipes (FIFOs) on those systems that
implement them) are intuited if they are defined in the system header file
The magic tests are used to check for files with data in particular fixed for‐
mats. The canonical example of this is a binary executable (compiled program)
a.out file, whose format is defined in <elf.h>, <a.out.h> and possibly
<exec.h> in the standard include directory. These files have a “magic number”
stored in a particular place near the beginning of the file that tells the
UNIX operating system that the file is a binary executable, and which of sev‐
eral types thereof. The concept of a “magic” has been applied by extension to
data files. Any file with some invariant identifier at a small fixed offset
into the file can usually be described in this way. The information identify‐
ing these files is read from /etc/magic and the compiled magic file
/usr/share/misc/magic.mgc, or the files in the directory /usr/share/misc/magic
if the compiled file does not exist. In addition, if $HOME/.magic.mgc or
$HOME/.magic exists, it will be used in preference to the system magic files.
file relies on magic number.
So if you want to implement a file equivalent by yourself, you have first to use
stat to check if it's a regular file and if it isn't empty and then, use magic number.
libmagic that would do this for you.