2 Copyright (C) 2008 Mathias Gottschlag
4 Permission is hereby granted, free of charge, to any person obtaining a copy of
5 this software and associated documentation files (the "Software"), to deal in the
6 Software without restriction, including without limitation the rights to use,
7 copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
8 Software, and to permit persons to whom the Software is furnished to do so,
9 subject to the following conditions:
11 The above copyright notice and this permission notice shall be included in all
12 copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
15 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
16 PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
17 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
18 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
19 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 #include <planlos/syscalls.h>
33 asm volatile("int $0x80" : "=b"(status
): "a"(SYS_FORK
));
37 static char *exec_get_path(const char *file
, const char *paths
)
39 while (strlen(paths
) > 0)
41 const char *nextpath
= strchr(paths
, ':');
42 if (!nextpath
) nextpath
= paths
+ strlen(paths
);
43 if (nextpath
&& (nextpath
!= paths
))
45 char *path
= malloc(strlen(file
) + 1 + ((uintptr_t)nextpath
- (uintptr_t)paths
));
46 memset(path
, 0, strlen(file
) + 1 + ((uintptr_t)nextpath
- (uintptr_t)paths
));
47 strncpy(path
, paths
, ((uintptr_t)nextpath
- (uintptr_t)paths
));
51 int fd
= open(path
, O_RDONLY
);
60 if (strchr(paths
, ':'))
68 int execl(const char *path
, const char *arg0
, ...)
70 char **args
= (char**)&arg0
;
71 return execv(path
, args
);
73 int execle(const char *path
, const char *arg0
, ...)
75 char **args
= (char**)&arg0
;
79 return execve(path
, args
, env
);
81 int execlp(const char *file
, const char *arg0
, ...)
83 char **args
= (char**)&arg0
;
84 return execvp(file
, args
);
86 int execv(const char *path
, char *const argv
[])
89 for (argcount
= 0; argv
[argcount
] != 0; argcount
++);
93 while (*env
) envcount
++;
95 asm volatile("int $0x80" : "=b"(status
): "a"(SYS_EXEC
), "b"(path
),
96 "c"(argcount
), "d"(argv
), "S"(envcount
), "D"(environ
));
99 int execve(const char *path
, char *const argv
[], char *const env
[])
103 for (; argv
[argcount
] != 0; argcount
++);
106 for (; env
[envcount
] != 0; envcount
++);
108 asm volatile("int $0x80" : "=b"(status
): "a"(SYS_EXEC
), "b"(path
),
109 "c"(argcount
), "d"(argv
), "S"(envcount
), "D"(env
));
112 int execvp(const char *file
, char *const argv
[])
115 if (!strchr(file
, '/'))
117 char *pathvar
= getenv("PATH");
119 path
= exec_get_path(file
, pathvar
);
121 path
= exec_get_path(file
, "/bin:/usr/bin");
122 if (!path
) return -1;
125 return execve(file
, argv
, 0);
128 int result
= execve(path
, argv
, 0);
134 char *getcwd(char *buf
, size_t size
)
137 asm volatile("int $0x80" : "=b"(status
): "a"(SYS_GETWD
), "b"(buf
), "c"(size
));
138 if (status
== -1) return 0;
141 int chdir(const char *path
)
144 asm volatile("int $0x80" : "=b"(status
): "a"(SYS_CHDIR
), "b"(path
));
149 return fcntl(fd
, F_DUPFD
, 0);
151 int dup2(int fd
, int fd2
)
153 return fcntl(fd
, F_DUPFD
, fd2
);
159 asm volatile("int $0x80" : "=b"(pid
): "a"(SYS_GETPID
));
164 int isatty(int fildes
)
169 int access(const char *path
, int amode
)
174 char *setlocale(int category
, const char *locale
)
179 pid_t
tcgetpgrp(int fd
)
188 char *getenv(const char *name
)
190 if (!environ
) return 0;
191 char **env
= environ
;
194 if (!strncmp(name
, *env
, (uintptr_t)strchr(*env
, '=') - (uintptr_t)*env
))
196 return strchr(*env
, '=') + 1;
202 int putenv(char *string
)
204 char *value
= strchr(string
, '=');
207 // Remove from environment
210 char **env
= environ
;
213 int namelength
= (uintptr_t)strchr(*env
, '=') - (uintptr_t)*env
;
214 if (namelength
< (int)strlen(string
)) continue;
215 if (!strncmp(string
, *env
, (uintptr_t)strchr(*env
, '=') - (uintptr_t)*env
))
222 if (found
== -1) return -1;
224 char **newenv
= malloc(sizeof(char*) * i
);
225 memcpy(newenv
, environ
, found
* sizeof(char*));
226 memcpy(newenv
+ found
, environ
+ found
+ 1, (i
+ 1 - found
) * sizeof(char*));
232 char *name
= strdup(string
);
233 *strchr(name
, '=') = 0;
236 char **env
= environ
;
239 if (!strncmp(name
, *env
, (uintptr_t)strchr(*env
, '=') - (uintptr_t)*env
))
248 char **newenv
= malloc(sizeof(char*) * (size
+ 2));
249 memcpy(newenv
, environ
, sizeof(char*) * size
);
250 newenv
[size
] = string
;
251 newenv
[size
+ 1] = 0;
257 environ
[found
] = string
;
263 int setenv(const char *name
, const char *value
, int overwrite
)
268 char **env
= environ
;
271 if (!strncmp(name
, *env
, (uintptr_t)strchr(*env
, '=') - (uintptr_t)*env
))
280 char **newenv
= malloc(sizeof(char*) * (size
+ 2));
281 memcpy(newenv
, environ
, sizeof(char*) * size
);
282 newenv
[size
] = malloc(strlen(name
) + strlen(value
) + 2);
283 strcpy(newenv
[size
], name
);
284 strcat(newenv
[size
], "=");
285 strcat(newenv
[size
], value
);
286 newenv
[size
+ 1] = 0;
292 environ
[found
] = malloc(strlen(name
) + strlen(value
) + 2);
293 strcpy(environ
[found
], name
);
294 strcat(environ
[found
], "=");
295 strcat(environ
[found
], value
);
300 int unsetenv(const char *name
)
302 // Remove from environment
305 char **env
= environ
;
306 if (!environ
) return 0;
309 if (!strncmp(name
, *env
, (uintptr_t)strchr(*env
, '=') - (uintptr_t)*env
))
315 if (found
== -1) return 0;
317 char **newenv
= malloc(sizeof(char*) * i
);
318 memcpy(newenv
, environ
, found
* sizeof(char*));
319 memcpy(newenv
+ found
, environ
+ found
+ 1, (i
+ 1 - found
) * sizeof(char*));