@@ -76,9 +76,150 @@ func argv_index(argv **byte, i int32) *byte {
76
76
return * (* * byte )(add (unsafe .Pointer (argv ), uintptr (i )* goarch .PtrSize ))
77
77
}
78
78
79
+ // when using -buildmode=c-archive or -buildmode=c-shared on linux
80
+ // we have to first make sure that glibc is being used or else
81
+ // we cannot rely on argc/argv/auxv to be accurate
82
+ func sysLibArgsValid () bool {
83
+ if _cgo_sys_lib_args_valid != nil {
84
+ ret := asmcgocall (_cgo_sys_lib_args_valid , nil )
85
+ if ret != 1 {
86
+ return false
87
+ }
88
+ }
89
+ return true
90
+ }
91
+
92
+ var procCmdline = []byte ("/proc/self/cmdline\x00 " )
93
+ var procEnviron = []byte ("/proc/self/environ\x00 " )
94
+
79
95
func args (c int32 , v * * byte ) {
80
- argc = c
81
- argv = v
96
+ if sysLibArgsValid () {
97
+ argc = c
98
+ argv = v
99
+ } else if GOOS == "linux" {
100
+ argc = 0
101
+ argv = nil
102
+
103
+ // get argc and argv size
104
+ var argvSize int32 = 0
105
+ fd := open (& procCmdline [0 ], 0 /* O_RDONLY */ , 0 )
106
+ if fd >= 0 {
107
+ for {
108
+ var buf [128 ]byte
109
+ c := read (fd , noescape (unsafe .Pointer (& buf [0 ])), int32 (unsafe .Sizeof (buf )))
110
+ if c <= 0 {
111
+ break
112
+ }
113
+
114
+ argvSize += c
115
+
116
+ i := c
117
+ for i = 0 ; i < c ; i ++ {
118
+ if buf [i ] == 0 {
119
+ argc ++
120
+ }
121
+ }
122
+ }
123
+
124
+ closefd (fd )
125
+ }
126
+
127
+ var environSize int32 = 0
128
+ var envc int32 = 0
129
+ fd = open (& procEnviron [0 ], 0 /* O_RDONLY */ , 0 )
130
+ if fd >= 0 {
131
+ for {
132
+ var buf [128 ]byte
133
+ c := read (fd , noescape (unsafe .Pointer (& buf [0 ])), int32 (unsafe .Sizeof (buf )))
134
+ if c <= 0 {
135
+ break
136
+ }
137
+
138
+ environSize += c
139
+
140
+ i := c
141
+ for i = 0 ; i < c ; i ++ {
142
+ if buf [i ] == 0 {
143
+ envc ++
144
+ }
145
+ }
146
+ }
147
+
148
+ closefd (fd )
149
+ }
150
+
151
+ argv = (* * byte )(unsafe .Pointer (persistentalloc (goarch .PtrSize * (uintptr (argc )+ uintptr (envc )+ 1 ), 0 , & memstats .other_sys )))
152
+ argvPtr := (* * byte )(add (unsafe .Pointer (argv ), goarch .PtrSize * (uintptr (argc )+ uintptr (envc )+ 1 )))
153
+ * argvPtr = (* byte )(nil ) //null terminate array
154
+
155
+ if argvSize > 0 {
156
+ argvBuf := unsafe .Pointer (persistentalloc (uintptr (argvSize ), 0 , & memstats .other_sys ))
157
+ fd := open (& procCmdline [0 ], 0 /* O_RDONLY */ , 0 )
158
+ if fd >= 0 {
159
+ c := read (fd , noescape (argvBuf ), int32 (argvSize ))
160
+ if c < 0 {
161
+ throw ("failed to read arguments" )
162
+ return
163
+ }
164
+
165
+ if c != int32 (argvSize ) {
166
+ throw ("short read arguments" )
167
+ return
168
+ }
169
+
170
+ strStart := int32 (0 )
171
+ strNum := 0
172
+
173
+ i := c
174
+ var b * byte
175
+ for i = 0 ; i < c ; i ++ {
176
+ b = (* byte )(add (argvBuf , uintptr (i )))
177
+ if * b == 0 {
178
+ argvPtr := (* * byte )(add (unsafe .Pointer (argv ), goarch .PtrSize * uintptr (strNum )))
179
+ * argvPtr = (* byte )(add (argvBuf , uintptr (strStart )))
180
+ strStart = i + 1
181
+ strNum ++
182
+ }
183
+ }
184
+
185
+ closefd (fd )
186
+ }
187
+ }
188
+
189
+ if environSize > 0 {
190
+ environBuf := unsafe .Pointer (persistentalloc (uintptr (environSize ), 0 , & memstats .other_sys ))
191
+ fd := open (& procEnviron [0 ], 0 /* O_RDONLY */ , 0 )
192
+ if fd >= 0 {
193
+ c := read (fd , noescape (environBuf ), int32 (environSize ))
194
+ if c < 0 {
195
+ throw ("failed to read environment" )
196
+ return
197
+ }
198
+
199
+ if c != int32 (environSize ) {
200
+ throw ("short read environment" )
201
+ return
202
+ }
203
+
204
+ strStart := int32 (0 )
205
+ strNum := 0
206
+
207
+ i := c
208
+ var b * byte
209
+ for i = 0 ; i < c ; i ++ {
210
+ b = (* byte )(add (environBuf , uintptr (i )))
211
+ if * b == 0 {
212
+ argvPtr := (* * byte )(add (unsafe .Pointer (argv ), goarch .PtrSize * (uintptr (argc )+ uintptr (strNum ))))
213
+ * argvPtr = (* byte )(add (environBuf , uintptr (strStart )))
214
+ strStart = i + 1
215
+ strNum ++
216
+ }
217
+ }
218
+
219
+ closefd (fd )
220
+ }
221
+ }
222
+ }
82
223
sysargs (c , v )
83
224
}
84
225
0 commit comments