Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to determine time zone: Is a directory (os error 21) #712

Closed
Adventure4Life opened this issue Aug 5, 2020 · 9 comments
Closed

Unable to determine time zone: Is a directory (os error 21) #712

Adventure4Life opened this issue Aug 5, 2020 · 9 comments

Comments

@Adventure4Life
Copy link

My localtime is linked to directory... it is not a file.. this is as I am using a lnux called Bedrock.

Is there anyway I can define the timezone with a --command I can add to the alias... or something like that?

I can not seem to relink the file directly to the actual local file due to how bedrock works. So I was wondering if there was a way I can force exa to use a specified path to localtime?

@ariasuni
Copy link
Collaborator

ariasuni commented Apr 18, 2021

Do you still have this error with exa 0.10.1?

If yes, I would like to know more about how it works on Linux Bedrock.

Also, you can try to use the TZ environment variable (see #725).

Edit: I found these Configuration instructions but I don’t understand everything.

@bobbbay
Copy link

bobbbay commented Apr 22, 2021

Some software may ignore the TZ environment variable and instead attempt to read /etc/localtime to determine the current timezone. Bedrock Linux will copy /bedrock/etc/localtime to /etc/localtime when enabling a stratum to cover this possibility.

TL;DR Bedrock will apparently set both TZ and /etc/localtime.

@bobbbay
Copy link

bobbbay commented Apr 23, 2021

Also... @ariasuni I should mention this: I'm on Exa 0.10.1 and still receive this error (on WSL + NixOS). My $TZ is set, although /etc/timezone does not exist (just Nix things).

@ariasuni
Copy link
Collaborator

Please copy the content of your TZ variable and the error message when exa crashes. Right I’ve no idea what Bedrock Linux or NixOS is doing, and no idea where exa fails exactly.

I looked at how exa is handling the TZ variable and it’s not handled correctly (to be fair, how it’s supposed to work is documented poorly if at all, I had to look at the glibc source code), so I’m working on that, but I’m not sure it will fix your problem.

@bobbbay
Copy link

bobbbay commented Apr 25, 2021

I cannot vouch for Bedrock, as I do not own a Bedrock system and have only dabbled in contributing in the project, but here's some results from my side:

[bobbbay@NotYourLaptop:~]$ exa --version
exa - list files on the command-line
v0.10.1 [+git]
https://the.exa.website/

[bobbbay@NotYourLaptop:~]$ exa
... files go here ...

[bobbbay@NotYourLaptop:~]$ exa --long
Unable to determine time zone: No such file or directory (os error 2)
... files go here ...

[bobbbay@NotYourLaptop:~]$ echo $TZ
America/Toronto

[bobbbay@NotYourLaptop:~]$

I should note the following:

  • /etc/timezone does not exist
  • My $TZ was not previously set, so honestly I had to add it as a line to my bashrc. Now that I think of it I'm sure there's a more "correct" option, I just haven't had the time/motivation to search it up and switch over to it. (not that I believe this makes a difference, though.)

@ariasuni
Copy link
Collaborator

The problem with NixOS is that they’re using TZDIR and exa’s not taking this environment variable into account (yet).

In the meantime, I believe you can workaround this by setting TZ to an absolute path to the file (it’s usually /usr/share/zoneinfo/America/Toronto for example, not sure if it works on NixOS). Otherwise you could try to unset TZ, in the case that NixOS gives you an /etc/localtime (I didn’t know about /etc/timezone and it doesn’t seem to be used by anything except maybe old versions of Java??).

@Adventure4Life:

My localtime is linked to directory... it is not a file.. this is as I am using a lnux called Bedrock.

I just don’t understand how’s that supposed to happen. glibc and musl expects /etc/localtime to be a link to, or a zoneinfo file. What’s the current content of you TZ variable? Can you try setting TZ to something like /usr/share/zoneinfo/Europe/Paris (or your timezone instead of Europe/Paris)?

@necrophcodr
Copy link

I can confirm that setting TZ=:/etc/localtime I am getting this error as well (with /etc/localtime being a symlink to /etc/zoneinfo/Europe/Copenhagen in my case). Even if I set TZ=Europe/Copenhagen or TZ=:/etc/zoneinfo/Europe/Copenhagen, I still get errors using exa -l vs exa.

@rardiol
Copy link

rardiol commented Aug 25, 2023

I have the issue on both 0.10.1 and building from master. On my nixos system:

TZDIR=/etc/zoneinfo
TZ=:/etc/localtime
/etc/zoneinfo:  symbolic link to /etc/static/zoneinfo
/etc/localtime: symbolic link to /etc/zoneinfo/America/Sao_Paulo

TZ is not set by default, this is a workaround for this firefox issue: NixOS/nixpkgs#238025. Unsetting TZ fixes the issue. Although from the glibc docs it should work, since it is equivalent to the default setting which points to /etc/localtime:

The third format looks like this:
:characters
Each operating system interprets this format differently; in the GNU C Library, characters is the name of a file which describes the time zone.
If the TZ environment variable does not have a value, the operation chooses a time zone by default. In the GNU C Library, the default time zone is like the specification ‘TZ=:/etc/localtime’ (or ‘TZ=:/usr/local/etc/localtime’, depending on how the GNU C Library was configured; see Installing the GNU C Library). Other C libraries use their own rule for choosing the default time zone, so there is little we can say about them.

https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html

The current code at

fn determine_time_zone() -> TZResult<TimeZone> {

does not seem to handle the case where TZ starts with a ":" and is an absolute path.

fn determine_time_zone() -> TZResult<TimeZone> {
    if let Ok(file) = env::var("TZ") {
        TimeZone::from_file({
            if file.starts_with('/') {
                file
            } else {
                format!("/usr/share/zoneinfo/{}", {
                    if file.starts_with(':') {
                        file.replacen(':', "", 1)
                    } else {
                        file
                    }
                })
            }
        })
    } else {
        TimeZone::from_file("/etc/localtime")
    }
}

The problem with NixOS is that they’re using TZDIR and exa’s not taking this environment variable into account (yet).

I think that would only matter if TZ is a timezone string like "TZ=America/Sao_Paulo", if it is an absolute path to a file it shouldn't matter.

https://docs.rs/datetime/0.5.2/datetime/fn.sys_timezone.html doesn't seem to handle the TZ env var.

This seems to work for me, strip the ":" from the beginning, then use absolute paths as is or else use TZDIR if it there:

diff --git a/src/output/table.rs b/src/output/table.rs
index 06e13b9..1221775 100644
--- a/src/output/table.rs
+++ b/src/output/table.rs
@@ -341,17 +341,17 @@ impl Environment {
 #[cfg(unix)]
 fn determine_time_zone() -> TZResult<TimeZone> {
     if let Ok(file) = env::var("TZ") {
+        let file = if file.starts_with(':') {
+               file.replacen(':', "", 1)
+            } else { file };
         TimeZone::from_file({
             if file.starts_with('/') {
                 file
             } else {
-                format!("/usr/share/zoneinfo/{}", {
-                    if file.starts_with(':') {
-                        file.replacen(':', "", 1)
-                    } else {
-                        file
-                    }
-                })
+                let mut str = env::var("TZDIR").unwrap_or_else(|_|String::from("/usr/share/zoneinfo"));
+                str.push('/');
+                str.push_str(&file);
+                str
             }
         })
     } else {

Or just merge #867, it's probably simpler than handling it here.

@ariasuni
Copy link
Collaborator

Closing this, since exa is unmaintained (see #1243), and this has (finally 🎉) fixed in the active fork eza!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants