Example #1
0
// File
//
// If there is an error, it will be of type *Error.
func (mgc *Magic) File(filename string) (string, error) {
	mgc.Lock()
	defer mgc.Unlock()
	runtime.KeepAlive(mgc.magic)

	if mgc.cookie == nil {
		return "", mgc.error()
	}

	cfilename := C.CString(filename)
	runtime.KeepAlive(cfilename)
	defer C.free(unsafe.Pointer(cfilename))

	cstring := C.magic_file_wrapper(mgc.cookie, cfilename, C.int(mgc.flags))
	if cstring == nil {
		rv, err := Version()
		if err != nil && err.(*Error).Errno != int(syscall.ENOSYS) {
			return "", err
		}

		// Handle the case when the "ERROR" flag is set regardless
		// of the current version of the underlying Magic library.
		//
		// Prior to version 5.15 the correct behaviour that concerns
		// the following IEEE 1003.1 standards was broken:
		//
		//   http://pubs.opengroup.org/onlinepubs/007904975/utilities/file.html
		//   http://pubs.opengroup.org/onlinepubs/9699919799/utilities/file.html
		//
		// This is an attempt to mitigate the problem and correct
		// it to achieve the desired behaviour as per the standards.
		if mgc.flags&ERROR != 0 {
			return "", mgc.error()
		} else if rv < 515 {
			C.magic_errno(mgc.cookie)
			cstring = C.magic_error(mgc.cookie)
		}
	}

	// XXX(kwilczynski): This case should not happen, ever.
	if cstring == nil {
		return "", &Error{-1, "unknown result or nil pointer"}
	}

	// Depending on the version of the underlying
	// Magic library the magic_file() function can
	// fail and either yield no results or return
	// the "(null)" string instead.  Often this
	// would indicate that an older version of
	// the Magic library is in use.
	s := C.GoString(cstring)
	if s == "" || s == "(null)" {
		return "", &Error{-1, "empty or invalid result"}
	}
	return s, nil
}
Example #2
0
// error retrieves an error from the underlying Magic library.
func (mgc *Magic) error() *Error {
	if mgc.cookie == nil {
		errno := syscall.EFAULT
		return &Error{int(errno), "Magic library is not open"}
	}
	runtime.KeepAlive(mgc.magic)

	cstring := C.magic_error(mgc.cookie)
	if cstring != nil {
		// Depending on the version of the underlying
		// Magic library, the error reporting facilities
		// can fail and either yield no results or return
		// the "(null)" string instead.  Often this would
		// indicate that an older version of the Magic
		// library is in use.
		s := C.GoString(cstring)
		if s == "" || s == "(null)" {
			return &Error{-1, "empty or invalid error message"}
		}
		errno := int(C.magic_errno(mgc.cookie))
		return &Error{errno, s}
	}
	return &Error{-1, "unknown error"}
}
Example #3
0
func Errno(cookie Magic_t) int {
	return (int)(C.magic_errno((C.magic_t)(cookie)))
}