mirror of
https://github.com/golang/go
synced 2024-11-25 09:17:57 -07:00
lib9: add mktempdir, removeall, runprog
R=golang-dev, bradfitz CC=golang-dev https://golang.org/cl/7523043
This commit is contained in:
parent
c76379954f
commit
7610a0552f
@ -292,6 +292,10 @@ extern char* getgoversion(void);
|
||||
extern char* getgoarm(void);
|
||||
extern char* getgo386(void);
|
||||
|
||||
extern char* mktempdir(void);
|
||||
extern void removeall(char*);
|
||||
extern int runcmd(char**);
|
||||
|
||||
extern void flagcount(char*, char*, int*);
|
||||
extern void flagint32(char*, char*, int32*);
|
||||
extern void flagint64(char*, char*, int64*);
|
||||
|
2
src/cmd/dist/windows.c
vendored
2
src/cmd/dist/windows.c
vendored
@ -271,6 +271,8 @@ static void bgwait1(void);
|
||||
static void
|
||||
genrun(Buf *b, char *dir, int mode, Vec *argv, int wait)
|
||||
{
|
||||
// Another copy of this logic is in ../../lib9/run_windows.c.
|
||||
// If there's a bug here, fix the logic there too.
|
||||
int i, j, nslash;
|
||||
Buf cmd;
|
||||
char *q;
|
||||
|
38
src/lib9/run_plan9.c
Normal file
38
src/lib9/run_plan9.c
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
int
|
||||
runcmd(char **argv)
|
||||
{
|
||||
int pid;
|
||||
Waitmsg *w;
|
||||
|
||||
switch(pid = fork()) {
|
||||
case -1:
|
||||
return -1;
|
||||
case 0:
|
||||
execvp(argv[0], argv);
|
||||
fprint(2, "exec %s: %r", argv[0]);
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
w = wait();
|
||||
if(w == nil)
|
||||
return -1;
|
||||
if(w->pid != pid) {
|
||||
werrstr("unexpected pid in wait");
|
||||
free(w);
|
||||
return -1;
|
||||
}
|
||||
if(w->msg[0]) {
|
||||
werrstr("unsuccessful exit status: %s", w->msg);
|
||||
free(w);
|
||||
return -1;
|
||||
}
|
||||
free(w);
|
||||
return 0;
|
||||
}
|
43
src/lib9/run_unix.c
Normal file
43
src/lib9/run_unix.c
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin freebsd linux netbsd openbsd
|
||||
|
||||
#include <u.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#define NOPLAN9DEFINES
|
||||
#include <libc.h>
|
||||
|
||||
int
|
||||
runcmd(char **argv)
|
||||
{
|
||||
int pid, pid1, status;
|
||||
|
||||
switch(pid = fork()) {
|
||||
case -1:
|
||||
return -1;
|
||||
case 0:
|
||||
execvp(argv[0], argv);
|
||||
fprint(2, "exec %s: %r", argv[0]);
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
while((pid1 = wait(&status)) < 0) {
|
||||
if(errno != EINTR) {
|
||||
werrstr("waitpid: %r");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if(pid1 != pid) {
|
||||
werrstr("unexpected pid in wait");
|
||||
return -1;
|
||||
}
|
||||
if(!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||
werrstr("unsuccessful exit status %#x", status);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
83
src/lib9/run_windows.c
Normal file
83
src/lib9/run_windows.c
Normal file
@ -0,0 +1,83 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include <u.h>
|
||||
#include <windows.h>
|
||||
#define NOPLAN9DEFINES
|
||||
#include <libc.h>
|
||||
#include "win.h"
|
||||
|
||||
int
|
||||
runcmd(char **argv)
|
||||
{
|
||||
// Mostly copied from ../cmd/dist/windows.c.
|
||||
// If there's a bug here, fix the logic there too.
|
||||
int i, j, nslash;
|
||||
Fmt fmt;
|
||||
char *q;
|
||||
WinRune *r;
|
||||
STARTUPINFOW si;
|
||||
PROCESS_INFORMATION pi;
|
||||
DWORD code;
|
||||
|
||||
fmtstrinit(&fmt);
|
||||
for(i=0; argv[i]; i++) {
|
||||
if(i > 0)
|
||||
fmtprint(&fmt, " ");
|
||||
q = argv[i];
|
||||
if(strstr(q, " ") || strstr(q, "\t") || strstr(q, "\"") || strstr(q, "\\\\") || (strlen(q) > 0 && q[strlen(q)-1] == '\\')) {
|
||||
fmtprint(&fmt, "\"");
|
||||
nslash = 0;
|
||||
for(; *q; q++) {
|
||||
if(*q == '\\') {
|
||||
nslash++;
|
||||
continue;
|
||||
}
|
||||
if(*q == '"') {
|
||||
for(j=0; j<2*nslash+1; j++)
|
||||
fmtprint(&fmt, "\\");
|
||||
nslash = 0;
|
||||
}
|
||||
for(j=0; j<nslash; j++)
|
||||
fmtprint(&fmt, "\\");
|
||||
nslash = 0;
|
||||
fmtprint(&fmt, "\"");
|
||||
}
|
||||
for(j=0; j<2*nslash; j++)
|
||||
fmtprint(&fmt, "\\");
|
||||
fmtprint(&fmt, "\"");
|
||||
} else {
|
||||
fmtprint(&fmt, "%s", q);
|
||||
}
|
||||
}
|
||||
|
||||
q = fmtstrflush(&fmt);
|
||||
r = torune(q);
|
||||
free(q);
|
||||
|
||||
memset(&si, 0, sizeof si);
|
||||
si.cb = sizeof si;
|
||||
si.dwFlags = STARTF_USESTDHANDLES;
|
||||
si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
|
||||
|
||||
if(!CreateProcessW(nil, r, nil, nil, TRUE, 0, nil, nil, &si, &pi)) {
|
||||
free(r);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(r);
|
||||
if(WaitForMultipleObjects(1, &pi.hProcess, FALSE, INFINITE) != 0)
|
||||
return -1;
|
||||
i = GetExitCodeProcess(pi.hProcess, &code);
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
if(!i)
|
||||
return -1;
|
||||
if(code != 0) {
|
||||
werrstr("unsuccessful exit status: %d", (int)code);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
54
src/lib9/tempdir_plan9.c
Normal file
54
src/lib9/tempdir_plan9.c
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
char*
|
||||
mktempdir(void)
|
||||
{
|
||||
char *p;
|
||||
int i;
|
||||
|
||||
p = smprint("/tmp/go-link-XXXXXX");
|
||||
for(i=0; i<1000; i++) {
|
||||
sprint(p, "/tmp/go-link-%06x", nrand((1<<24)-1));
|
||||
fd = create(p, OREAD|OEXCL, 0700|DMDIR);
|
||||
if(fd >= 0) {
|
||||
close(fd);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
free(p);
|
||||
return nil;
|
||||
}
|
||||
|
||||
void
|
||||
removeall(char *p)
|
||||
{
|
||||
int fd, n;
|
||||
Dir *d;
|
||||
char *q;
|
||||
|
||||
if(remove(p) >= 0)
|
||||
return;
|
||||
if((d = dirstat(p)) == nil)
|
||||
return;
|
||||
if(!(d->mode & DMDIR)) {
|
||||
free(d);
|
||||
return;
|
||||
}
|
||||
free(d);
|
||||
|
||||
if((fd = open(p, OREAD)) < 0)
|
||||
return;
|
||||
n = dirreadall(fd, &d);
|
||||
close(fd);
|
||||
for(i=0; i<n; i++) {
|
||||
q = smprint("%s/%s", p, d[i].name);
|
||||
removeall(q);
|
||||
free(q);
|
||||
}
|
||||
free(d);
|
||||
}
|
52
src/lib9/tempdir_unix.c
Normal file
52
src/lib9/tempdir_unix.c
Normal file
@ -0,0 +1,52 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin freebsd linux netbsd openbsd
|
||||
|
||||
#include <u.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#define NOPLAN9DEFINES
|
||||
#include <libc.h>
|
||||
|
||||
char*
|
||||
mktempdir(void)
|
||||
{
|
||||
char *tmp, *p;
|
||||
|
||||
tmp = getenv("TMPDIR");
|
||||
if(tmp == nil)
|
||||
tmp = "/var/tmp";
|
||||
p = smprint("%s/go-link-XXXXXX", tmp);
|
||||
if(mkdtemp(p) == nil)
|
||||
return nil;
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
removeall(char *p)
|
||||
{
|
||||
DIR *d;
|
||||
struct dirent *dp;
|
||||
char *q;
|
||||
struct stat st;
|
||||
|
||||
if(stat(p, &st) < 0)
|
||||
return;
|
||||
if(!S_ISDIR(st.st_mode)) {
|
||||
unlink(p);
|
||||
return;
|
||||
}
|
||||
|
||||
d = opendir(p);
|
||||
while((dp = readdir(d)) != nil) {
|
||||
if(strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
|
||||
continue;
|
||||
q = smprint("%s/%s", p, dp->d_name);
|
||||
removeall(q);
|
||||
free(q);
|
||||
}
|
||||
closedir(d);
|
||||
rmdir(p);
|
||||
}
|
112
src/lib9/tempdir_windows.c
Normal file
112
src/lib9/tempdir_windows.c
Normal file
@ -0,0 +1,112 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include <u.h>
|
||||
#include <windows.h>
|
||||
#include <libc.h>
|
||||
#include "win.h"
|
||||
|
||||
char*
|
||||
toutf(WinRune *r)
|
||||
{
|
||||
Rune *r1;
|
||||
int i, n;
|
||||
char *p;
|
||||
|
||||
n = 0;
|
||||
while(r[n] != '\0')
|
||||
n++;
|
||||
n++;
|
||||
r1 = malloc(n*sizeof r1[0]);
|
||||
for(i=0; i<n; i++)
|
||||
r1[i] = r[i];
|
||||
p = smprint("%S", r1);
|
||||
free(r1);
|
||||
return p;
|
||||
}
|
||||
|
||||
WinRune*
|
||||
torune(char *p)
|
||||
{
|
||||
int i, n;
|
||||
Rune *r1;
|
||||
WinRune *r;
|
||||
|
||||
r1 = runesmprint("%s", p);
|
||||
n = 0;
|
||||
while(r1[n] != '\0')
|
||||
n++;
|
||||
n++;
|
||||
r = malloc(n*sizeof r[0]);
|
||||
for(i=0; i<n; i++)
|
||||
r[i] = r1[i];
|
||||
free(r1);
|
||||
return r;
|
||||
}
|
||||
|
||||
char*
|
||||
mktempdir(void)
|
||||
{
|
||||
WinRune buf[1024];
|
||||
WinRune tmp[MAX_PATH];
|
||||
WinRune golink[] = {'g', 'o', 'l', 'i', 'n', 'k', '\0'};
|
||||
int n;
|
||||
|
||||
n = GetTempPathW(nelem(buf), buf);
|
||||
if(n <= 0)
|
||||
return nil;
|
||||
buf[n] = '\0';
|
||||
|
||||
if(GetTempFileNameW(buf, golink, 0, tmp) == 0)
|
||||
return nil;
|
||||
DeleteFileW(tmp);
|
||||
if(!CreateDirectoryW(tmp, nil))
|
||||
return nil;
|
||||
|
||||
return toutf(tmp);
|
||||
}
|
||||
|
||||
void
|
||||
removeall(char *p)
|
||||
{
|
||||
WinRune *r, *r1;
|
||||
DWORD attr;
|
||||
char *q, *elem;
|
||||
HANDLE h;
|
||||
WIN32_FIND_DATAW data;
|
||||
|
||||
r = torune(p);
|
||||
attr = GetFileAttributesW(r);
|
||||
if(attr == INVALID_FILE_ATTRIBUTES || !(attr & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
DeleteFileW(r);
|
||||
free(r);
|
||||
return;
|
||||
}
|
||||
|
||||
q = smprint("%s\\*", p);
|
||||
r1 = torune(q);
|
||||
free(q);
|
||||
h = FindFirstFileW(r1, &data);
|
||||
if(h == INVALID_HANDLE_VALUE)
|
||||
goto done;
|
||||
do{
|
||||
q = toutf(data.cFileName);
|
||||
elem = strrchr(q, '\\');
|
||||
if(elem != nil) {
|
||||
elem++;
|
||||
if(strcmp(elem, ".") == 0 || strcmp(elem, "..") == 0) {
|
||||
free(q);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
removeall(q);
|
||||
free(q);
|
||||
}while(FindNextFileW(h, &data));
|
||||
FindClose(h);
|
||||
|
||||
done:
|
||||
free(r1);
|
||||
RemoveDirectoryW(r);
|
||||
free(r);
|
||||
}
|
8
src/lib9/win.h
Normal file
8
src/lib9/win.h
Normal file
@ -0,0 +1,8 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
typedef unsigned short WinRune;
|
||||
|
||||
WinRune* torune(char*);
|
||||
char *toutf(WinRune*);
|
Loading…
Reference in New Issue
Block a user