#how to get username cross-platform?

1 messages · Page 1 of 1 (latest)

urban heron
#

how to get username cross-platform?

#

my options are:

  1. use environment variables $USER or $USERNAME
  2. use posix API
earnest fog
#

easy way: std.process.getEnvVarOwned(gpa, "USER")

#

will returned the associated string, which you'll need to free with gpa once you're done using it

urban heron
#

will this work on windows?

earnest fog
#

returns error.EnvironmentVariableNotFound in the event that USER isn't an environment variable

earnest fog
urban heron
#

what does even set $USER

earnest fog
#

usually the shell

#

most shells, at least on linux, export a bunch of posix-standard variables such as USER and HOME and so on

#

and usually they get that information from some source of information on the system

supple saffron
#

I just opened a Windows cmd prompt, and it looks like there the env var is USERNAME

urban heron
#

what about USER?

supple saffron
#

Not present

earnest fog
#

fair enough, so you'll probably want to either do a switch on the target os or have a fallback when the not found error returns

supple saffron
#

Instead of HOME, there's USERPROFILE

urban heron
#
const username = std.process.getEnvVarOwned(alloc, "USER") catch try std.process.getEnvVarOwned(alloc, "USERNAME");
earnest fog
#

ie

// switch on os
const user = try std.process.getEnvVarOwned(gpa, switch (@import("builtin").target.os.tag) {
    .windows => "USERNAME",
    else => "USER",
});
defer gpa.free(user);

// fallback in catch
const user = std.process.getEnvVarOwned(gpa, "USER") catch |err| switch (err) {
    error.EnvironmentVariableNotFound => try std.process.getEnvVarOwned(gpa, "USERNAME"),
    else => |e| return e,
};
defer gpa.free(user);
supple saffron
#

yah - better using comptime condition on target

earnest fog
#

note: it doesn't only return environmentvariablenotfound, it can also return OutOfMemory and InvalidWtf8

#

so using a catch-all catch is not too prudent

supple saffron
#

I don;t recall it exactly, but on Widnows there's an API to call that is not dependent on an environment variable.

urban heron
earnest fog
#

wdym?

#

it wouldn't

urban heron
#

ok but does it really matter

earnest fog
#

yeah

#

you don't want to try again if the reason you failed is due to failing due to out of memory or invalid environment

urban heron
#

the zig standard library browser is really nice

supple saffron
#

Windows: GetUserNameExW probably better

urban heron
#

W for win

#

i can probably rely on USERNAME being defined on Windows more than USER being defined on posix OSes

supple saffron
#

No, it's for the Unicode version, which you want in case the user's name uses characters that aren't in the system codepage.

urban heron
#

i know i was

supple saffron
#

There's also GetUserNameW

urban heron
#
pub const HOST_NAME_MAX = switch (native_os) {
    .linux => linux.HOST_NAME_MAX,
    .macos, .ios, .tvos, .watchos, .visionos => 72,
    .openbsd, .haiku, .dragonfly, .netbsd, .solaris, .illumos, .freebsd => 255,
    // https://github.com/SerenityOS/serenity/blob/c87557e9c1865fa1a6440de34ff6ce6fc858a2b7/Kernel/API/POSIX/sys/limits.h#L22
    .serenity => 64,
    else => {},
};
#

this will be what on windows?

supple saffron
#

Aren't length of host names established by IETF?

urban heron
#

thats from stdlib